create-ailk 0.9.0 → 0.11.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 (104) hide show
  1. package/README.md +10 -5
  2. package/dist/cli.js +17 -2
  3. package/dist/content-payloads.d.ts +37 -0
  4. package/dist/content-payloads.js +64 -0
  5. package/dist/lib/fetch-module.d.ts +3 -3
  6. package/dist/lib/fetch-module.js +11 -5
  7. package/dist/lib/fetch-template.d.ts +1 -1
  8. package/dist/lib/fetch-template.js +7 -4
  9. package/dist/lib/module-license-gate.d.ts +29 -23
  10. package/dist/lib/module-license-gate.js +98 -0
  11. package/dist/module-architecture.d.ts +9 -0
  12. package/dist/module-architecture.js +46 -14
  13. package/dist/parse-args.d.ts +2 -0
  14. package/dist/parse-args.js +7 -0
  15. package/dist/programmatic.js +12 -4
  16. package/dist/starter-grid.d.ts +4 -67
  17. package/dist/starter-grid.js +6 -84
  18. package/dist/surfaces.js +2 -3
  19. package/dist/template-manifest.d.ts +1 -1
  20. package/dist/template-manifest.js +5 -5
  21. package/package.json +6 -4
  22. package/release-scope.json +25 -0
  23. package/site-templates/designs/minimalism/sample/README.md +2 -2
  24. package/site-templates/designs/minimalism/sample/content/en/HomePage/home.mdx +1 -1
  25. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +4 -3
  26. package/templates/.claude/agents/web.md +10 -8
  27. package/templates/.claude/rules/architecture.md +10 -7
  28. package/templates/.claude/settings.json +12 -0
  29. package/templates/.env.example +24 -3
  30. package/templates/CLAUDE.md +38 -22
  31. package/templates/README.md +12 -12
  32. package/templates/apps/api/jest.config.cjs +1 -0
  33. package/templates/apps/api/package.json +1 -0
  34. package/templates/apps/mcp/CLAUDE.md +23 -10
  35. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +160 -17
  36. package/templates/apps/mcp/__tests__/index.test.ts +118 -1
  37. package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +425 -5
  38. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +67 -3
  39. package/templates/apps/mcp/__tests__/server.test.ts +162 -1
  40. package/templates/apps/mcp/src/index.ts +35 -3
  41. package/templates/apps/mcp/src/lib/commerce-claim.ts +193 -24
  42. package/templates/apps/mcp/src/server.ts +77 -5
  43. package/templates/apps/mcp/src/tools/purchase.ts +1 -1
  44. package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +15 -0
  45. package/templates/apps/web/app/.well-known/mcp.json/route.ts +10 -3
  46. package/templates/apps/web/src/lib/commerce-claim.ts +15 -6
  47. package/templates/content/_site.mdx +23 -4
  48. package/templates/database/CHANGELOG.md +7 -0
  49. package/templates/database/package.json +1 -1
  50. package/templates/package.json +2 -0
  51. package/versions.json +34 -33
  52. package/dist/modules/commerce/0.6.0.tar.gz +0 -0
  53. package/dist/modules/commerce/0.6.1.tar.gz +0 -0
  54. package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
  55. package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
  56. package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
  57. package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
  58. package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
  59. package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
  60. package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
  61. package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
  62. package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
  63. package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
  64. package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
  65. package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
  66. package/dist/modules/workspace/0.6.0.tar.gz +0 -0
  67. package/dist/modules/workspace/0.6.1.tar.gz +0 -0
  68. package/site-templates/aliases/minimalism-site.TEMPLATE-MANIFEST.json +0 -538
  69. package/templates/.claude/skills/README.md +0 -37
  70. package/templates/.claude/skills/add-auth/SKILL.md +0 -261
  71. package/templates/.claude/skills/add-auth/references/env-vars.md +0 -98
  72. package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +0 -172
  73. package/templates/.claude/skills/add-page/SKILL.md +0 -260
  74. package/templates/.claude/skills/add-page/references/page-types.md +0 -124
  75. package/templates/.claude/skills/add-page/scripts/site-pages.mjs +0 -87
  76. package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +0 -99
  77. package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +0 -18
  78. package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +0 -43
  79. package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +0 -52
  80. package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +0 -38
  81. package/templates/.claude/skills/check-site/SKILL.md +0 -235
  82. package/templates/.claude/skills/check-site/references/common-errors.md +0 -113
  83. package/templates/.claude/skills/check-site/references/findings-glossary.md +0 -140
  84. package/templates/.claude/skills/check-site/references/severity-levels.md +0 -114
  85. package/templates/.claude/skills/fill-page/SKILL.md +0 -199
  86. package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +0 -80
  87. package/templates/.claude/skills/fill-page/references/section-sources.md +0 -41
  88. package/templates/.claude/skills/setup-database/SKILL.md +0 -156
  89. package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +0 -154
  90. package/templates/.claude/skills/setup-deploy/SKILL.md +0 -275
  91. package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +0 -192
  92. package/templates/.claude/skills/setup-deploy/references/runbook-template.md +0 -204
  93. package/templates/.claude/skills/setup-deploy/references/vercel-json-template.md +0 -98
  94. package/templates/.claude/skills/update-page/SKILL.md +0 -117
  95. package/templates/.claude/skills/update-page/scripts/update-page.ts +0 -640
  96. package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +0 -31
  97. package/templates/.claude/skills/upgrade-plan/SKILL.md +0 -121
  98. package/templates/.claude/skills/upgrade-plan/references/options.md +0 -24
  99. package/templates/.claude/skills/upgrade-plan/scripts/upgrade-plan.ts +0 -527
  100. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +0 -8
  101. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +0 -12
  102. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +0 -12
  103. package/templates/apps/mcp/__tests__/lib/require-paid-tier.test.ts +0 -75
  104. package/templates/apps/mcp/src/lib/require-paid-tier.ts +0 -44
@@ -1,275 +0,0 @@
1
- ---
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).
4
- ---
5
-
6
- # setup-deploy
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
10
- `platform` value at v1. Other platforms (Netlify, Cloudflare, Render,
11
- Fly, self-host) reject with an explicit "not yet supported" message
12
- and emit nothing.
13
-
14
- ## When to use
15
-
16
- The consumer is preparing to deploy their AILK site for the first
17
- time, or wants to verify their deploy config is complete. Triggers:
18
-
19
- - "provision Vercel config" / "set up Vercel"
20
- - "what env vars do I need to deploy?"
21
- - "I'm ready to ship — what files do I need?"
22
- - "regenerate `vercel.json`" / "refresh `.env.example`"
23
-
24
- Skip this skill when:
25
-
26
- - The consumer is on a non-Vercel platform — emit the rejection
27
- message (see Step 1) and stop.
28
- - The consumer asks about runtime environment values
29
- (`process.env.X` debugging) — that's an app-level concern, not a
30
- config-emission concern.
31
- - The consumer is asking about Stripe live-mode setup — that's
32
- hard-floor blocked across AILK; sandbox-only at v1. Mention and stop.
33
-
34
- ## What this skill does (and does not do)
35
-
36
- **Does:**
37
-
38
- - Validate the `platform` parameter — only `vercel` is accepted at v1.
39
- - Detect existing `vercel.json`, `.env.example`, and `RUNBOOK.md` at
40
- the consumer's project root.
41
- - For each artifact, ask the consumer how to handle conflicts
42
- (merge / overwrite / skip) before writing.
43
- - Emit the three artifacts at the consumer's project root, derived
44
- from templates in `references/`.
45
- - Ask where leads go (Step 5a) — the email key, or a database via
46
- `setup-database` — and warn, verbatim, when neither is set.
47
- - 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).
50
-
51
- **Does not:**
52
-
53
- - Call any Vercel API. The consumer runs `vercel deploy` themselves.
54
- - Read or write live secrets. `.env.example` uses placeholder values
55
- only.
56
- - Configure Cloudflare anything (deploy target, KV, D1, R2). CF is
57
- deferred entirely as a coherent follow-up unit.
58
- - Emit Netlify / Render / Fly / self-host config. v1 is Vercel only.
59
- - Modify the consumer's actual `.env.local` or any other file
60
- containing real secrets.
61
-
62
- ## The mechanic
63
-
64
- ### Step 1 — Validate the platform parameter
65
-
66
- Default platform is `vercel`. If the consumer asks for any other
67
- platform, respond:
68
-
69
- > "`setup-deploy` is Vercel-only at v1. Netlify / Cloudflare /
70
- > Render / Fly / self-host support are tracked at the upstream repo —
71
- > file an issue at <https://github.com/working-theory-labs/ai-launch-kit/issues>
72
- > if your platform is missing.
73
- >
74
- > Cloudflare is deferred entirely (deploy target + KV/D1/R2 data
75
- > layer) as a coherent follow-up."
76
-
77
- Then stop. Do not emit any files.
78
-
79
- ### Step 2 — Detect existing artifacts
80
-
81
- Look for `vercel.json`, `.env.example`, and `RUNBOOK.md` at the
82
- consumer's project root. For each one, note:
83
-
84
- - **Missing** — will emit fresh.
85
- - **Present** — ask how to handle (Step 3).
86
-
87
- ### Step 3 — Conflict handling per file
88
-
89
- For each existing artifact, show the consumer:
90
-
91
- 1. The first ~10 lines of the existing file (preview).
92
- 2. A summary of what the skill would emit (template name + key
93
- fields).
94
- 3. Three options: **merge** (only for `RUNBOOK.md` and
95
- `.env.example` — see merge logic below), **overwrite**
96
- (replace contents), **skip** (leave existing file untouched).
97
-
98
- Wait for the consumer's choice per file. Do not blindly overwrite.
99
-
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.
104
-
105
- **Merge logic — `RUNBOOK.md`:** if the "Leads — where messages go"
106
- section (with its two headings, `Email (default)` and
107
- `Lead inbox (setup-database)`) is missing from the existing file,
108
- append it at the end. Existing sections are not modified.
109
-
110
- **Merge logic — `vercel.json`:** **not supported.** `vercel.json` is
111
- either overwritten or skipped — no field-level merge. Reason: the
112
- file is small and consumers are likely to have customized it
113
- intentionally; merging risks subtle config drift.
114
-
115
- ### Step 4 — Emit `vercel.json`
116
-
117
- Use the template at `references/vercel-json-template.md`. The
118
- emitted file has these fields:
119
-
120
- - `version: 2` — Vercel config schema version.
121
- - `framework: "nextjs"` — Vercel auto-detects `apps/web` as Next.js.
122
- - `buildCommand` — pnpm-aware build (typically
123
- `cd ../.. && pnpm install --frozen-lockfile && pnpm --filter ./apps/web build`
124
- for monorepo deploys, or `pnpm build` for single-app deploys).
125
- - `installCommand` — match the consumer's package manager.
126
- - `env` — env-var passthrough; AILK ships an empty `env: {}` and
127
- expects Vercel's project-level env-var dashboard to handle real
128
- values.
129
-
130
- After write, parse the JSON. If parse fails, the skill has a bug —
131
- report it to the consumer with the literal error.
132
-
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.
139
-
140
- The skill **does not** read live `.env` files. Placeholder values
141
- 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.
149
-
150
- ### Step 5a — Lead delivery
151
-
152
- Where a contact-form message goes is decided by the API project's
153
- environment (RUNBOOK § "Leads — where messages go"). Ask the consumer
154
- two questions:
155
-
156
- 1. **Will this site use a database?** If yes, point them to the
157
- `setup-database` skill — it provisions Postgres, sets
158
- `DATABASE_URL`, runs migrations and verifies a test lead reaches
159
- the inbox. Do not collect a connection string here.
160
- 2. **What email should messages go to?** Ask for
161
- `RESEND_API_KEY`, `AILK_LEAD_NOTIFICATION_TO` (their address) and
162
- `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.
167
-
168
- If the consumer provides neither a database nor all three email
169
- values, print this, verbatim:
170
-
171
- > ⚠ No lead destination is set. In production your contact page will show
172
- > your contact email instead of the form, and no messages will be collected.
173
- > Run setup-database, or set RESEND_API_KEY, AILK_LEAD_NOTIFICATION_TO and
174
- > AILK_LEAD_NOTIFICATION_FROM on the API project.
175
-
176
- Then continue — the warning does not stop the deploy config.
177
-
178
- ### Step 6 — Emit `RUNBOOK.md`
179
-
180
- Use the template at `references/runbook-template.md`. The emitted
181
- runbook has these sections:
182
-
183
- 1. **Pre-deploy checklist** — what to set in Vercel's project
184
- dashboard before clicking Deploy.
185
- 2. **Leads — where messages go** — the two lead destinations, in
186
- plain words:
187
- - **Email (default)** — no database; each message is emailed to
188
- the owner (`RESEND_API_KEY`, `AILK_LEAD_NOTIFICATION_TO`,
189
- `AILK_LEAD_NOTIFICATION_FROM` on the API project).
190
- - **Lead inbox (setup-database)** — `DATABASE_URL` set; messages
191
- land in `/leads` and newsletter signups are collected.
192
- With neither, production `/contact` shows the site's contact email
193
- instead of the form. On a non-Vercel host, the API process needs
194
- `NODE_ENV=production`.
195
- 3. **Custom domain + DNS** — pointer at Vercel's domain docs.
196
- 4. **Production callbacks for OAuth** — for consumers who used
197
- `add-auth` and need to register prod redirect URIs.
198
-
199
- After write, grep the RUNBOOK for the two lead-destination headings
200
- (`Email (default)`, `Lead inbox (setup-database)`). Both must be
201
- present. If either is missing, the skill has a bug — flag with the
202
- literal error.
203
-
204
- ### Step 7 — Closing summary
205
-
206
- Print:
207
-
208
- - Which artifacts were emitted vs skipped (per consumer's Step 3
209
- choices).
210
- - Where leads will go (email, the lead inbox, or — with the Step 5a
211
- warning repeated — nowhere), with a pointer to `RUNBOOK.md`'s
212
- "Leads — where messages go" section.
213
- - A reminder that Vercel project-level env-vars need to be set in
214
- the Vercel dashboard before deploy — `.env.example` is the
215
- contract, not the values.
216
- - The next step: `vercel deploy` (or `git push` if the consumer is
217
- using Vercel's GitHub integration).
218
-
219
- ## Re-invocation
220
-
221
- The skill is idempotent. Re-running on a project with all three
222
- artifacts present asks the consumer how to handle each conflict
223
- (per Step 3). A consumer who picks **skip** for all three gets a
224
- no-op run with a "all artifacts already present, nothing to do"
225
- message.
226
-
227
- ## Validation
228
-
229
- Before reporting "done":
230
-
231
- - `vercel.json` parses as JSON ✓
232
- - `.env.example` declares >= the count of vars in the template ✓
233
- - `RUNBOOK.md` contains both lead-destination headings
234
- (`Email (default)`, `Lead inbox (setup-database)`) ✓
235
- - Step 5a ran: the consumer chose a lead destination, or saw the
236
- no-destination warning ✓
237
-
238
- If any check fails, surface the failure to the consumer (not silent).
239
-
240
- ## What this skill does NOT validate
241
-
242
- - That the consumer's Vercel project actually deploys. That's
243
- `vercel deploy`'s job.
244
- - That env-var values in the consumer's Vercel dashboard are
245
- correct or live. The skill never reads dashboard state.
246
- - That OAuth callback URLs in `add-auth`'s RUNBOOK are
247
- registered in production OAuth apps. That's the consumer's job
248
- pre-launch.
249
-
250
- ## References
251
-
252
- - `references/vercel-json-template.md` — minimal viable `vercel.json`.
253
- - `references/env-vars-template.md` — `.env.example` structure with
254
- placeholder values per category.
255
- - `references/runbook-template.md` — `RUNBOOK.md` with the two lead
256
- destinations (Email (default), Lead inbox (setup-database)).
257
-
258
- ## Coordination
259
-
260
- - **`setup-database`** — takes a site from no database to a working
261
- lead inbox. Step 5a hands off to it; this skill never collects a
262
- connection string.
263
- - **`add-auth`** — produces its own `RUNBOOK.md`
264
- sections for OAuth setup (dev callback URLs). This skill's
265
- RUNBOOK adds production callback URLs and merges with any
266
- existing runbook content (not blindly overwrites).
267
- - **`@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_*`.
273
- - **Cloudflare deferred** — neither CF Pages (deploy target) nor
274
- CF KV / D1 / R2 (data layer) is in v1. Will ship as a coherent
275
- follow-up PR.
@@ -1,192 +0,0 @@
1
- # `.env.example` Template
2
-
3
- The structure the `setup-deploy` skill emits at the consumer's
4
- project root. Placeholder values only — the skill never echoes a
5
- real secret.
6
-
7
- When `@working-theory/env` ships a Zod schema (currently a placeholder
8
- package), this template should be revised to derive from that
9
- schema instead. Until then, this file is the source of truth for
10
- what env vars an AILK consumer site reads.
11
-
12
- ## Template
13
-
14
- ```bash
15
- # AI Launch Kit — environment template
16
- # Copy this file to `.env.local` (gitignored) and fill in values.
17
- # Production values live in your deploy platform's dashboard
18
- # (Vercel project settings → Environment Variables).
19
-
20
- # ── Marketing / canonical domain ─────────────────────────────────
21
- # Your site's canonical public domain (no protocol).
22
- AILK_PUBLIC_DOMAIN=your-domain.com
23
-
24
- # ── Content backend ──────────────────────────────────────────────
25
- # AILK's MDX adapter is the default. Other adapters ship as
26
- # additive PRs later.
27
- CONTENT_BACKEND=mdx
28
- # Override the content directory. Default is <repo-root>/content.
29
- # AILK_CONTENT_ROOT=
30
-
31
- # ── Lead delivery ────────────────────────────────────────────────
32
- # Where contact-form messages go (RUNBOOK.md § "Leads — where
33
- # messages go"). Set these on the API project.
34
- #
35
- # Lead inbox — set by the `setup-database` skill. With it, messages
36
- # land in /leads and newsletter signups are collected.
37
- # DATABASE_URL=postgres://user:pass@host:5432/db
38
- # DATABASE_URL_NON_POOLED=postgres://user:pass@host:5432/db
39
- #
40
- # Email (default) — with no database, each message is emailed to you.
41
- # All three are required; a key alone sends nothing.
42
- # RESEND_API_KEY=
43
- # AILK_LEAD_NOTIFICATION_TO=you@your-domain.com
44
- # AILK_LEAD_NOTIFICATION_FROM=leads@your-domain.com
45
- #
46
- # With neither, /contact shows your contact email (content/_site.mdx
47
- # `contactEmail`) instead of the form in production.
48
-
49
- # ── API origin checks + checkout gate (apps/api) ─────────────────
50
- # Set both on the API project. Unset in production, the API logs a
51
- # startup warning for each and keeps running, but:
52
- # - without FRONTEND_URL, CORS and cookie origin checks are pinned to
53
- # http://localhost:3000 and checkout answers 500 to a caller admitted
54
- # without X-Internal-Auth;
55
- # - without OSS_API_INTERNAL_SECRET, the checkout route admits callers
56
- # without the X-Internal-Auth header.
57
- # FRONTEND_URL is the site the browser loads (no trailing slash).
58
- # FRONTEND_URL=https://your-domain.com
59
- # Shared secret: the same value on the API and web projects.
60
- # Generate with: openssl rand -hex 32
61
- # OSS_API_INTERNAL_SECRET=
62
-
63
- # ── Auth — required env vars ─────────────────────────────────────
64
- # Set to "1" to require sign-in for protected routes; default is
65
- # auth-disabled / public.
66
- # AILK_AUTH_REQUIRED=1
67
- #
68
- # Better Auth secret — signs session cookies. REQUIRED in production:
69
- # apps/web/auth.ts throws in production without it. Generate with:
70
- # openssl rand -base64 32
71
- # Local dev (next dev) uses a development fallback.
72
- # BETTER_AUTH_SECRET=
73
- #
74
- # The site's public origin — Better Auth builds OAuth callback URLs on
75
- # it and trusts only it. Set it in production; local dev can leave it
76
- # unset.
77
- # BETTER_AUTH_URL=https://your-domain.com
78
-
79
- # ── Auth — email sign-in (Resend) ────────────────────────────────
80
- # Activated when both AUTH_EMAIL_SERVER and AUTH_EMAIL_FROM are set.
81
- # Get a Resend API key at https://resend.com/api-keys.
82
- # AUTH_EMAIL_SERVER=smtp://resend:re_yourkeyhere@smtp.resend.com:465
83
- # AUTH_EMAIL_FROM=onboarding@resend.dev
84
-
85
- # ── Auth — Google OAuth ──────────────────────────────────────────
86
- # Activated when both GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET set.
87
- # Set up at https://console.cloud.google.com/apis/credentials.
88
- # Production callback: https://your-domain.com/api/auth/callback/google
89
- # GOOGLE_CLIENT_ID=
90
- # GOOGLE_CLIENT_SECRET=
91
-
92
- # ── Auth — GitHub OAuth ──────────────────────────────────────────
93
- # Activated when both GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET set.
94
- # Set up at https://github.com/settings/developers.
95
- # Production callback: https://your-domain.com/api/auth/callback/github
96
- # GITHUB_CLIENT_ID=
97
- # GITHUB_CLIENT_SECRET=
98
-
99
- # ── Stripe (sandbox keys only — sk_test_* / pk_test_*) ───────────
100
- # AILK is sandbox-only at v1. Live keys (sk_live_*, pk_live_*) are
101
- # hook-blocked from appearing in source.
102
- # Get test keys at https://dashboard.stripe.com/test/apikeys.
103
- # STRIPE_SECRET_KEY=sk_test_...
104
- # NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
105
- # Webhook signing secret — see Stripe Dashboard → Developers →
106
- # Webhooks → <endpoint> → Signing secret. Format: whsec_*.
107
- # STRIPE_WEBHOOK_SECRET=
108
-
109
- # ── Analytics — all off by default ───────────────────────────────
110
- # Each provider is independent. Set the env var(s) to enable.
111
- #
112
- # Vercel Analytics — built-in dashboard for Vercel deploys.
113
- # Requires Vercel hosting. Set to "true" to enable. Requires redeploy
114
- # after change (NEXT_PUBLIC_* values bake at build time).
115
- # NEXT_PUBLIC_VERCEL_ANALYTICS_ENABLED=
116
- #
117
- # Google Analytics 4 — gtag.js measurement. Requires consent in EU/UK/CA.
118
- # Get the measurement ID from analytics.google.com → Admin → Data Streams.
119
- # Format: G-XXXXXXXXXX. Requires redeploy after change.
120
- # NEXT_PUBLIC_GA_MEASUREMENT_ID=
121
- #
122
- # GA4 Measurement Protocol — server-side analytics secret.
123
- # Required alongside NEXT_PUBLIC_GA_MEASUREMENT_ID for server-side
124
- # lead/purchase events.
125
- # GA_API_SECRET=
126
- #
127
- # Google Search Console — verification meta tag. No script, no consent.
128
- # Get the token from search.google.com/search-console → Settings →
129
- # Ownership verification → HTML tag. Paste only the content="..." value.
130
- # GOOGLE_SITE_VERIFICATION=
131
- ```
132
-
133
- ## Categories the skill emits
134
-
135
- The template above groups vars into seven categories. Every emitted
136
- `.env.example` should hit each category at least with its header
137
- comment, even if the consumer hasn't activated any vars in that
138
- category — the comment block tells future-them what's available.
139
-
140
- Categories:
141
-
142
- 1. Marketing / canonical domain
143
- 2. Content backend
144
- 3. Lead delivery (database or email)
145
- 4. API origin checks + checkout gate
146
- 5. Auth — required + per-provider
147
- 6. Stripe (sandbox-only)
148
- 7. Analytics
149
-
150
- ## What the skill never includes
151
-
152
- - Real secret values. All values are placeholders or commented
153
- examples.
154
- - Live Stripe keys. Sandbox-only at AILK v1.
155
- - Live Vercel deploy tokens. The Vercel CLI handles deploy auth via
156
- `vercel login`.
157
- - Database connection strings with embedded passwords. Comments
158
- show shape only.
159
-
160
- ## Counting vars for validation
161
-
162
- The skill's Step 5 validation counts the declared (uncommented) vars
163
- the template emits and confirms the count is non-zero. Empty
164
- `.env.example` is a bug. Currently declared vars in the template:
165
-
166
- - `AILK_PUBLIC_DOMAIN`
167
- - `CONTENT_BACKEND`
168
-
169
- (All other entries are commented optional vars.) The skill should
170
- not require the consumer to set every commented var — they're
171
- opt-in. The two declared entries are the minimum the AILK scaffold
172
- needs to boot, even on a static-content-only site.
173
-
174
- ## Merge logic
175
-
176
- If the consumer already has `.env.example`, the skill (per SKILL.md
177
- Step 3) offers merge / overwrite / skip. Merge logic:
178
-
179
- 1. Read the existing file.
180
- 2. For each line in this template that's not a comment-only line,
181
- check whether the var name already appears anywhere in the
182
- existing file (commented or uncommented).
183
- 3. Vars **already present** are not modified — the consumer's
184
- existing comments and value choices win.
185
- 4. Vars **missing** are appended at the end of the existing file
186
- under a new section:
187
- ```
188
- # ── Added by setup-deploy ────────────────────────────────
189
- ```
190
-
191
- This avoids duplicating vars while still surfacing additions the
192
- template gained since the consumer's last run.
@@ -1,204 +0,0 @@
1
- # `RUNBOOK.md` Template
2
-
3
- The `setup-deploy` skill emits this runbook at the consumer's
4
- project root. It documents pre-deploy steps and where the site's
5
- leads go — the two lead destinations, **Email (default)** and
6
- **Lead inbox (setup-database)**.
7
-
8
- The skill must verify both lead-destination headings are present
9
- after emit (per SKILL.md Step 6 validation). If either is missing,
10
- the skill has a bug.
11
-
12
- ## Template
13
-
14
- ```markdown
15
- # RUNBOOK — Production Operations
16
-
17
- This runbook is generated by the `setup-deploy` skill. It covers
18
- what to do before and after deploying to Vercel, plus the
19
- operational caveats AILK ships with.
20
-
21
- If you re-run `setup-deploy`, new sections may be appended at
22
- the end under "## Added by setup-deploy." Existing sections are
23
- not modified by the skill.
24
-
25
- ---
26
-
27
- ## Pre-deploy checklist
28
-
29
- Before you click Deploy in Vercel:
30
-
31
- - [ ] **Add a Vercel project** pointed at this repo
32
- (`vercel link` from the CLI, or the dashboard).
33
- - [ ] **Set environment variables** in Vercel's project dashboard
34
- (Settings → Environment Variables). Use `.env.example` as the
35
- contract — every variable listed there should have a value
36
- set in Vercel before deploy.
37
- - [ ] **Configure your custom domain** if you have one (Vercel
38
- Project → Settings → Domains). Vercel handles TLS automatically.
39
- - [ ] **Pick where leads go** — see "Leads — where messages go"
40
- below. With neither an email key nor a database, your contact
41
- page shows your contact email instead of the form in
42
- production, and no messages are collected.
43
- - [ ] **On a host other than Vercel**, set `NODE_ENV=production` on
44
- the API process — that is how it knows it is in production.
45
- - [ ] **Register production OAuth callbacks** if you used
46
- `add-auth` and activated Google or GitHub. Each provider
47
- needs the prod callback URL added to its OAuth app settings.
48
-
49
- ---
50
-
51
- ## Leads — where messages go
52
-
53
- Where a contact-form message goes depends only on what you set on
54
- the **API** project:
55
-
56
- | You set | A message… |
57
- | ----------------------------------------- | -------------------------------------------- |
58
- | `DATABASE_URL` | lands in your lead inbox at `/leads` |
59
- | the three email variables, no database | is emailed to you |
60
- | neither (production) | is not collected — `/contact` shows your contact email instead of the form |
61
- | neither (`pnpm dev`) | is written to a local file, for testing |
62
-
63
- A newsletter signup needs the database: without one, `/newsletter`
64
- offers no signup form. A visitor is never told a message was sent
65
- when it reached nobody.
66
-
67
- ### Email (default)
68
-
69
- **When to pick:** you want messages in your inbox with no database
70
- to run. This is the default for a new site.
71
-
72
- **Setup:**
73
-
74
- 1. Create an API key at <https://resend.com/api-keys> and verify the
75
- domain you will send from (Resend Dashboard → Domains).
76
- 2. On the **API** project in Vercel (Settings → Environment
77
- Variables), set:
78
- - `RESEND_API_KEY` — the key.
79
- - `AILK_LEAD_NOTIFICATION_TO` — the address messages go to (yours).
80
- - `AILK_LEAD_NOTIFICATION_FROM` — a sender on your verified domain.
81
- 3. Redeploy the API.
82
-
83
- All three are required: a key without both addresses sends nothing.
84
- If Resend refuses a message, the visitor is told it could not be
85
- sent, so they can try again or email you directly.
86
-
87
- ### Lead inbox (setup-database)
88
-
89
- **When to pick:** you want every message kept, searchable, in a
90
- lead inbox you review signed in — and newsletter signups collected.
91
-
92
- **Setup:** run the `setup-database` skill ("set up the database"). It
93
- walks you through provisioning Postgres, setting `DATABASE_URL`,
94
- running migrations, pinning you as the owner
95
- (`AILK_OPERATOR_EMAIL`), and sending one test message that must
96
- appear in `/leads` before it reports done. If the email variables
97
- are also set, you still get an email for each new lead.
98
-
99
- ---
100
-
101
- ## Custom domain + DNS
102
-
103
- Vercel handles TLS automatically once a domain is added to your
104
- project. Two paths:
105
-
106
- - **Vercel-managed DNS** — let Vercel handle nameservers. Easiest;
107
- Vercel Dashboard → Project → Settings → Domains → Add → "Manage
108
- DNS Records."
109
- - **External DNS** — add an A record (or CNAME for subdomains)
110
- pointing at Vercel's IP, then add the domain to your project.
111
- Vercel docs walk through it.
112
-
113
- For email-sending domains (Resend, magic-link), you'll also need
114
- to verify the sending domain in Resend's dashboard before
115
- production magic-link emails will deliver. Resend Dashboard →
116
- Domains → Add → DNS records → wait for verification.
117
-
118
- ---
119
-
120
- ## Production callbacks for OAuth (if you used `add-auth`)
121
-
122
- If you activated Google or GitHub OAuth via `add-auth`,
123
- those activations used dev callback URLs (`localhost:3000`). For
124
- production, add the prod callback URLs to each OAuth app:
125
-
126
- ### Google
127
-
128
- 1. Open the Google Cloud Console OAuth client you created
129
- (<https://console.cloud.google.com/apis/credentials>).
130
- 2. Under **Authorized redirect URIs**, add:
131
- `https://<your-prod-domain>/api/auth/callback/google`
132
- 3. Save.
133
-
134
- ### GitHub
135
-
136
- 1. Open the GitHub OAuth App you created
137
- (<https://github.com/settings/developers>).
138
- 2. Edit either:
139
- - The same app's **Authorization callback URL** to add a second
140
- line for prod (GitHub allows multiple).
141
- - Or create a separate OAuth App for production.
142
- 3. Update the env vars in Vercel if you created a separate app.
143
-
144
- ---
145
-
146
- ## When to redeploy
147
-
148
- - After changing any `NEXT_PUBLIC_*` env var (those bake at build
149
- time).
150
- - After running database migrations (data shape changed).
151
- - After updating `vercel.json` (deploy config changed).
152
-
153
- You do **not** need to redeploy after:
154
-
155
- - Adding a non-`NEXT_PUBLIC_*` env var in Vercel's dashboard
156
- (server-side reads pick it up on next request).
157
- - Editing MDX content in `content/` and pushing — Vercel rebuilds
158
- on push.
159
-
160
- ---
161
-
162
- ## Troubleshooting
163
-
164
- - **"My contact page shows an email address instead of the form"**
165
- → the API has no lead destination. Set the three email variables,
166
- or run `setup-database` (see "Leads — where messages go").
167
- - **"OAuth login redirects to localhost in production"** → you
168
- haven't added the production callback URL to the OAuth app
169
- (see above).
170
- - **"Magic-link emails aren't arriving in production"** → your
171
- Resend sender domain isn't verified yet (Resend Dashboard →
172
- Domains).
173
-
174
- ---
175
- ```
176
-
177
- ## Section headings the validation must find
178
-
179
- After emit, the skill must grep for these two headings (verbatim
180
- match). Both must be present:
181
-
182
- - `### Email (default)`
183
- - `### Lead inbox (setup-database)`
184
-
185
- If either is missing, the template was edited in a way that broke
186
- the contract. Surface the failure to the consumer (not silent).
187
-
188
- ## Merge logic
189
-
190
- If the consumer already has `RUNBOOK.md`, the skill (per SKILL.md
191
- Step 3) offers merge / overwrite / skip. Merge logic:
192
-
193
- 1. Read the existing file.
194
- 2. Check whether the "Leads — where messages go" section and its two
195
- lead-destination headings are already present.
196
- 3. Headings already present → not modified.
197
- 4. Headings missing → append at the end of the existing file under:
198
- ```
199
- ## Added by setup-deploy
200
- ```
201
-
202
- The pre-deploy checklist, custom-domain, and OAuth-prod-callbacks
203
- sections are also appended if missing. Sections that are already
204
- present (even with different content) are not modified.