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.
- package/README.md +10 -5
- package/dist/cli.js +17 -2
- package/dist/content-payloads.d.ts +37 -0
- package/dist/content-payloads.js +64 -0
- package/dist/lib/fetch-module.d.ts +3 -3
- package/dist/lib/fetch-module.js +11 -5
- package/dist/lib/fetch-template.d.ts +1 -1
- package/dist/lib/fetch-template.js +7 -4
- package/dist/lib/module-license-gate.d.ts +29 -23
- package/dist/lib/module-license-gate.js +98 -0
- package/dist/module-architecture.d.ts +9 -0
- package/dist/module-architecture.js +46 -14
- package/dist/parse-args.d.ts +2 -0
- package/dist/parse-args.js +7 -0
- package/dist/programmatic.js +12 -4
- package/dist/starter-grid.d.ts +4 -67
- package/dist/starter-grid.js +6 -84
- package/dist/surfaces.js +2 -3
- package/dist/template-manifest.d.ts +1 -1
- package/dist/template-manifest.js +5 -5
- package/package.json +6 -4
- package/release-scope.json +25 -0
- package/site-templates/designs/minimalism/sample/README.md +2 -2
- package/site-templates/designs/minimalism/sample/content/en/HomePage/home.mdx +1 -1
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +4 -3
- package/templates/.claude/agents/web.md +10 -8
- package/templates/.claude/rules/architecture.md +10 -7
- package/templates/.claude/settings.json +12 -0
- package/templates/.env.example +24 -3
- package/templates/CLAUDE.md +38 -22
- package/templates/README.md +12 -12
- package/templates/apps/api/jest.config.cjs +1 -0
- package/templates/apps/api/package.json +1 -0
- package/templates/apps/mcp/CLAUDE.md +23 -10
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +160 -17
- package/templates/apps/mcp/__tests__/index.test.ts +118 -1
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +425 -5
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +67 -3
- package/templates/apps/mcp/__tests__/server.test.ts +162 -1
- package/templates/apps/mcp/src/index.ts +35 -3
- package/templates/apps/mcp/src/lib/commerce-claim.ts +193 -24
- package/templates/apps/mcp/src/server.ts +77 -5
- package/templates/apps/mcp/src/tools/purchase.ts +1 -1
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +15 -0
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +10 -3
- package/templates/apps/web/src/lib/commerce-claim.ts +15 -6
- package/templates/content/_site.mdx +23 -4
- package/templates/database/CHANGELOG.md +7 -0
- package/templates/database/package.json +1 -1
- package/templates/package.json +2 -0
- package/versions.json +34 -33
- package/dist/modules/commerce/0.6.0.tar.gz +0 -0
- package/dist/modules/commerce/0.6.1.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
- package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
- package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
- package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
- package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
- package/dist/modules/workspace/0.6.0.tar.gz +0 -0
- package/dist/modules/workspace/0.6.1.tar.gz +0 -0
- package/site-templates/aliases/minimalism-site.TEMPLATE-MANIFEST.json +0 -538
- package/templates/.claude/skills/README.md +0 -37
- package/templates/.claude/skills/add-auth/SKILL.md +0 -261
- package/templates/.claude/skills/add-auth/references/env-vars.md +0 -98
- package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +0 -172
- package/templates/.claude/skills/add-page/SKILL.md +0 -260
- package/templates/.claude/skills/add-page/references/page-types.md +0 -124
- package/templates/.claude/skills/add-page/scripts/site-pages.mjs +0 -87
- package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +0 -99
- package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +0 -18
- package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +0 -43
- package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +0 -52
- package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +0 -38
- package/templates/.claude/skills/check-site/SKILL.md +0 -235
- package/templates/.claude/skills/check-site/references/common-errors.md +0 -113
- package/templates/.claude/skills/check-site/references/findings-glossary.md +0 -140
- package/templates/.claude/skills/check-site/references/severity-levels.md +0 -114
- package/templates/.claude/skills/fill-page/SKILL.md +0 -199
- package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +0 -80
- package/templates/.claude/skills/fill-page/references/section-sources.md +0 -41
- package/templates/.claude/skills/setup-database/SKILL.md +0 -156
- package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +0 -154
- package/templates/.claude/skills/setup-deploy/SKILL.md +0 -275
- package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +0 -192
- package/templates/.claude/skills/setup-deploy/references/runbook-template.md +0 -204
- package/templates/.claude/skills/setup-deploy/references/vercel-json-template.md +0 -98
- package/templates/.claude/skills/update-page/SKILL.md +0 -117
- package/templates/.claude/skills/update-page/scripts/update-page.ts +0 -640
- package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +0 -31
- package/templates/.claude/skills/upgrade-plan/SKILL.md +0 -121
- package/templates/.claude/skills/upgrade-plan/references/options.md +0 -24
- package/templates/.claude/skills/upgrade-plan/scripts/upgrade-plan.ts +0 -527
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +0 -8
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +0 -12
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +0 -12
- package/templates/apps/mcp/__tests__/lib/require-paid-tier.test.ts +0 -75
- 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.
|