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,261 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: add-auth
|
|
3
|
-
description: Activate auth providers (magic-link via Resend, Google OAuth, GitHub OAuth) on an AILK consumer site. Use when the user says "wire up auth", "add login", "set up sign-in", "I need users to log in", or asks how to enable any of magic-link / Google / GitHub auth on their AILK site. The skill writes env vars for whichever subset of providers the consumer activates and prints (plus saves) an OAuth-app-setup runbook. It does NOT modify `auth.config.ts` and does NOT emit any pages.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# add-auth
|
|
7
|
-
|
|
8
|
-
Activate one or more auth providers on an AILK site by writing the env
|
|
9
|
-
vars NextAuth reads to detect them, plus a `RUNBOOK.md` that documents
|
|
10
|
-
the OAuth-app-creation steps for the consumer's records.
|
|
11
|
-
|
|
12
|
-
## When to use
|
|
13
|
-
|
|
14
|
-
The user has a working AILK site (post-`pnpm create ailk`) and wants
|
|
15
|
-
to gate routes behind sign-in, send magic-link emails, or accept
|
|
16
|
-
Google / GitHub OAuth. Phrases that should trigger this skill:
|
|
17
|
-
|
|
18
|
-
- "wire up auth" / "add login" / "set up sign-in"
|
|
19
|
-
- "I want users to log in"
|
|
20
|
-
- "enable Google sign-in" / "enable GitHub login"
|
|
21
|
-
- "set up magic-link auth"
|
|
22
|
-
- "add OAuth"
|
|
23
|
-
|
|
24
|
-
Skip this skill when:
|
|
25
|
-
|
|
26
|
-
- The user wants a `/login` or `/account` _page_ — those are pages, not
|
|
27
|
-
auth wiring. Use `add-page` for that.
|
|
28
|
-
- The user is asking about a third-party provider that isn't in the
|
|
29
|
-
AILK locked set (Apple, Microsoft, Twitter, etc.). The locked set is
|
|
30
|
-
magic-link + Google + GitHub at v1; broader provider support is a
|
|
31
|
-
future PR. Acknowledge the request and stop.
|
|
32
|
-
- The user is in production and needs production callback URLs. v1
|
|
33
|
-
ships dev-mode callbacks (`http://localhost:3000`) only —
|
|
34
|
-
production callback setup is deferred to `setup-deploy`
|
|
35
|
-
or a future deploy skill. Note this and stop.
|
|
36
|
-
|
|
37
|
-
## What this skill does (and does not do)
|
|
38
|
-
|
|
39
|
-
**Does:**
|
|
40
|
-
|
|
41
|
-
- Reads `.env.local` to see which providers are already activated.
|
|
42
|
-
- Asks the consumer which of the three locked providers
|
|
43
|
-
(magic-link, Google, GitHub) they want to activate _this session_.
|
|
44
|
-
- For each picked provider, walks the consumer through
|
|
45
|
-
OAuth-app-creation (Google / GitHub) or Resend-key setup
|
|
46
|
-
(magic-link), then writes the resulting secrets to `.env.local`.
|
|
47
|
-
- Auto-detects whether `@working-theory/database` is installed with User /
|
|
48
|
-
Session models (Prisma adapter mode) or not (JWT-only mode), and
|
|
49
|
-
states which mode the site is in.
|
|
50
|
-
- Writes (or merges) a `RUNBOOK.md` in the consumer's repo root
|
|
51
|
-
with the same setup instructions the consumer just followed, so
|
|
52
|
-
they can refer back later or hand to a collaborator.
|
|
53
|
-
|
|
54
|
-
**Does not:**
|
|
55
|
-
|
|
56
|
-
- Modify `auth.config.ts`. The locked-set providers are env-var-driven
|
|
57
|
-
— present env vars activate the matching provider in
|
|
58
|
-
`auth.config.ts`'s `buildProviders()`. No code changes are needed.
|
|
59
|
-
- Create any new files under `app/`, `pages/`, or `content/`. The
|
|
60
|
-
emit is limited to `.env.local` writes and a `RUNBOOK.md` write.
|
|
61
|
-
- Set up production callback URLs. Dev-mode (`http://localhost:3000`)
|
|
62
|
-
only at v1.
|
|
63
|
-
- Add, remove, or modify any provider entry in `auth.config.ts`
|
|
64
|
-
outside of magic-link / Google / GitHub. Consumer-added providers
|
|
65
|
-
(e.g., Apple) are preserved as-is and never touched by this skill.
|
|
66
|
-
- Accept production OAuth credentials. If the consumer pastes a
|
|
67
|
-
production-looking secret, that's acceptable, but the runbook still
|
|
68
|
-
documents only the dev callback URL.
|
|
69
|
-
|
|
70
|
-
## The mechanic
|
|
71
|
-
|
|
72
|
-
### Step 1 — Show the menu
|
|
73
|
-
|
|
74
|
-
Greet the consumer and present the three locked providers, marking
|
|
75
|
-
which are already activated (env vars present in `.env.local`):
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
Which auth providers do you want to activate?
|
|
79
|
-
|
|
80
|
-
[ ] magic-link (passwordless email login via Resend)
|
|
81
|
-
[ ] Google OAuth
|
|
82
|
-
[ ] GitHub OAuth
|
|
83
|
-
|
|
84
|
-
You can pick any subset, including "none of the above" (in which case
|
|
85
|
-
this skill exits without writing anything). You can also re-run this
|
|
86
|
-
skill later to activate more providers — already-activated providers
|
|
87
|
-
will be skipped automatically.
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
If `.env.local` already has any of these activated, mark them:
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
[x] magic-link (already activated — AUTH_EMAIL_SERVER + AUTH_EMAIL_FROM are set)
|
|
94
|
-
[ ] Google OAuth
|
|
95
|
-
[ ] GitHub OAuth
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Wait for the consumer to pick a subset. Then, for each picked
|
|
99
|
-
provider, run the matching sub-flow.
|
|
100
|
-
|
|
101
|
-
### Step 2 — Run per-provider sub-flows
|
|
102
|
-
|
|
103
|
-
#### magic-link sub-flow
|
|
104
|
-
|
|
105
|
-
1. Tell the consumer: _"Magic-link uses Resend as the email provider
|
|
106
|
-
at AILK v1. Other email providers ship as additive future PRs.
|
|
107
|
-
You'll need a Resend API key (free tier is fine for development).
|
|
108
|
-
Get one at <https://resend.com/api-keys>."_
|
|
109
|
-
2. Wait for the consumer to paste the API key.
|
|
110
|
-
3. Ask for the `AUTH_EMAIL_FROM` address. This must be a verified
|
|
111
|
-
sender on the consumer's Resend account. For development it's
|
|
112
|
-
common to use `onboarding@resend.dev` (Resend's shared dev
|
|
113
|
-
sender). Mention that.
|
|
114
|
-
4. Construct `AUTH_EMAIL_SERVER` as
|
|
115
|
-
`smtp://resend:<API_KEY>@smtp.resend.com:465`.
|
|
116
|
-
5. Write to `.env.local`:
|
|
117
|
-
```
|
|
118
|
-
AUTH_EMAIL_SERVER=smtp://resend:re_...@smtp.resend.com:465
|
|
119
|
-
AUTH_EMAIL_FROM=onboarding@resend.dev
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
#### Google OAuth sub-flow
|
|
123
|
-
|
|
124
|
-
1. Tell the consumer the steps in chat AND queue the same content for
|
|
125
|
-
the runbook (see Step 3). Steps:
|
|
126
|
-
- Go to <https://console.cloud.google.com/apis/credentials>.
|
|
127
|
-
- Click **Create Credentials → OAuth client ID**. If prompted,
|
|
128
|
-
configure the OAuth consent screen first (**External** → fill
|
|
129
|
-
name, support email, developer contact email; scopes are
|
|
130
|
-
auto-populated by NextAuth).
|
|
131
|
-
- Application type: **Web application**.
|
|
132
|
-
- Name: anything (e.g., "AILK dev").
|
|
133
|
-
- **Authorized redirect URIs** — add exactly:
|
|
134
|
-
`http://localhost:3000/api/auth/callback/google`
|
|
135
|
-
- Click **Create**. Copy the **Client ID** and **Client secret**
|
|
136
|
-
from the dialog.
|
|
137
|
-
2. Wait for the consumer to paste both values.
|
|
138
|
-
3. Write to `.env.local`:
|
|
139
|
-
```
|
|
140
|
-
GOOGLE_CLIENT_ID=...
|
|
141
|
-
GOOGLE_CLIENT_SECRET=...
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
#### GitHub OAuth sub-flow
|
|
145
|
-
|
|
146
|
-
1. Tell the consumer the steps in chat AND queue the same content for
|
|
147
|
-
the runbook. Steps:
|
|
148
|
-
- Go to <https://github.com/settings/developers>.
|
|
149
|
-
- Click **New OAuth App**.
|
|
150
|
-
- Application name: anything (e.g., "AILK dev").
|
|
151
|
-
- Homepage URL: `http://localhost:3000`
|
|
152
|
-
- **Authorization callback URL** — add exactly:
|
|
153
|
-
`http://localhost:3000/api/auth/callback/github`
|
|
154
|
-
- Click **Register application**. Generate a new client secret.
|
|
155
|
-
Copy the **Client ID** and **Client secret**.
|
|
156
|
-
2. Wait for the consumer to paste both values.
|
|
157
|
-
3. Write to `.env.local`:
|
|
158
|
-
```
|
|
159
|
-
GITHUB_CLIENT_ID=...
|
|
160
|
-
GITHUB_CLIENT_SECRET=...
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Step 3 — Write the RUNBOOK
|
|
164
|
-
|
|
165
|
-
After all picked providers are activated, write
|
|
166
|
-
`RUNBOOK.md` (or merge into existing) at the consumer's repo root.
|
|
167
|
-
The runbook captures the OAuth-app-creation steps and Resend setup
|
|
168
|
-
the consumer just walked through, so they can hand it to a teammate
|
|
169
|
-
or refer back later.
|
|
170
|
-
|
|
171
|
-
Use `references/oauth-app-setup.md` as the template. Replace
|
|
172
|
-
`<provider>` headings as appropriate, and only include sections for
|
|
173
|
-
providers actually activated this session. If `RUNBOOK.md` already
|
|
174
|
-
exists with sections for already-activated providers, do not
|
|
175
|
-
duplicate — add only the new sections beneath any existing content.
|
|
176
|
-
|
|
177
|
-
### Step 4 — Detect the database adapter mode
|
|
178
|
-
|
|
179
|
-
Before printing the closing summary, check the consumer's setup:
|
|
180
|
-
|
|
181
|
-
- If `package.json` lists `@working-theory/database` as a dependency AND
|
|
182
|
-
`database/prisma/schema.prisma` defines `User` and `Session` models
|
|
183
|
-
→ **Prisma adapter mode**. Sessions persist across server restarts.
|
|
184
|
-
- Otherwise → **JWT-only mode**. Sessions are cookies, no database.
|
|
185
|
-
|
|
186
|
-
State the mode in the closing summary so the consumer is never
|
|
187
|
-
surprised:
|
|
188
|
-
|
|
189
|
-
> "Your site is running in **Prisma adapter mode** — sessions persist
|
|
190
|
-
> in the `User` and `Session` tables. Run `pnpm db:push` after this
|
|
191
|
-
> skill if you haven't applied the migration yet."
|
|
192
|
-
|
|
193
|
-
or
|
|
194
|
-
|
|
195
|
-
> "Your site is running in **JWT-only mode** — sessions are
|
|
196
|
-
> cookie-only and don't require a database. To switch to persistent
|
|
197
|
-
> sessions, install `@working-theory/database` and add the `User` / `Session`
|
|
198
|
-
> models from `database/prisma/schema.prisma`."
|
|
199
|
-
|
|
200
|
-
### Step 5 — Closing summary
|
|
201
|
-
|
|
202
|
-
Print:
|
|
203
|
-
|
|
204
|
-
- Which providers are now active (subset picked this session +
|
|
205
|
-
already-activated providers).
|
|
206
|
-
- The database adapter mode (Prisma or JWT).
|
|
207
|
-
- A reminder to set `AILK_AUTH_REQUIRED=1` in `.env.local` if they
|
|
208
|
-
want protected routes (default is auth-disabled / public).
|
|
209
|
-
- A pointer to `RUNBOOK.md` for future reference.
|
|
210
|
-
- A pointer to `setup-deploy` for production callback URL
|
|
211
|
-
setup when the consumer is ready to deploy.
|
|
212
|
-
|
|
213
|
-
## Re-invocation
|
|
214
|
-
|
|
215
|
-
The skill is idempotent. On a second run, the menu in Step 1 marks
|
|
216
|
-
already-activated providers with `[x]` (read from `.env.local`), and
|
|
217
|
-
the per-provider sub-flows skip those and only run for the new ones.
|
|
218
|
-
The closing summary lists everything, not just what changed this
|
|
219
|
-
session.
|
|
220
|
-
|
|
221
|
-
If the consumer wants to _change_ a previously-activated provider's
|
|
222
|
-
secrets (e.g., rotated their Google Client Secret), they should pick
|
|
223
|
-
that provider in the menu and the sub-flow will overwrite the
|
|
224
|
-
existing values in `.env.local`. Confirm before overwriting.
|
|
225
|
-
|
|
226
|
-
## Customization preservation
|
|
227
|
-
|
|
228
|
-
If `auth.config.ts` has been modified by the consumer to add a
|
|
229
|
-
third-party provider (e.g., Apple), this skill leaves that file
|
|
230
|
-
completely untouched. The skill never reads, edits, or even opens
|
|
231
|
-
`auth.config.ts`. Activation of the AILK locked set happens entirely
|
|
232
|
-
through env vars — `getActiveProviderIds()` in
|
|
233
|
-
`apps/web/lib/auth-env.ts` is what reads them at startup.
|
|
234
|
-
|
|
235
|
-
## What "activation" means under the hood
|
|
236
|
-
|
|
237
|
-
- **Provider list is computed at startup from env-var presence** in
|
|
238
|
-
`apps/web/auth.config.ts` → `buildProviders()`.
|
|
239
|
-
- A provider is included only when every required env var is set:
|
|
240
|
-
- `email` (magic-link): `AUTH_EMAIL_SERVER` + `AUTH_EMAIL_FROM`
|
|
241
|
-
- `google`: `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET`
|
|
242
|
-
- `github`: `GITHUB_CLIENT_ID` + `GITHUB_CLIENT_SECRET`
|
|
243
|
-
- A site with zero auth env vars boots cleanly with no active
|
|
244
|
-
providers (`apps/web/lib/auth-env.ts` returns an empty array).
|
|
245
|
-
|
|
246
|
-
This means the skill's job is purely env-var wiring + documentation.
|
|
247
|
-
|
|
248
|
-
## References
|
|
249
|
-
|
|
250
|
-
- `references/oauth-app-setup.md` — RUNBOOK template the skill instantiates per session.
|
|
251
|
-
- `references/env-vars.md` — env-var contract (which vars activate which provider).
|
|
252
|
-
|
|
253
|
-
## Coordination
|
|
254
|
-
|
|
255
|
-
- **`add-page`** — `/login` or `/account` pages. This skill
|
|
256
|
-
emits no pages.
|
|
257
|
-
- **`setup-deploy`** — production callback URL setup. v1
|
|
258
|
-
is dev-only.
|
|
259
|
-
- **`@working-theory/database`** — Prisma adapter detection. Install
|
|
260
|
-
`@working-theory/database` separately to upgrade from JWT-only to persistent
|
|
261
|
-
sessions.
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# Auth Env-Var Contract
|
|
2
|
-
|
|
3
|
-
Source of truth for which env vars activate which auth provider on
|
|
4
|
-
an AILK consumer site. Read by the `add-auth` skill before
|
|
5
|
-
asking the consumer to paste secrets.
|
|
6
|
-
|
|
7
|
-
The activation logic lives in `apps/web/lib/auth-env.ts` →
|
|
8
|
-
`getActiveProviderIds()`. A provider is active **only when every
|
|
9
|
-
required var is set to a non-empty value**. Partial wiring (e.g.,
|
|
10
|
-
`GOOGLE_CLIENT_ID` set but `GOOGLE_CLIENT_SECRET` missing) is treated
|
|
11
|
-
as inactive — `apps/web/auth.ts` never constructs that provider.
|
|
12
|
-
|
|
13
|
-
The site's auth library is **Better Auth** (`apps/web/auth.ts`,
|
|
14
|
-
`betterAuth({ secret, baseURL, socialProviders, … })`).
|
|
15
|
-
|
|
16
|
-
## Provider activation table
|
|
17
|
-
|
|
18
|
-
| Provider ID | Required env vars | Source |
|
|
19
|
-
| ----------- | -------------------------------------------- | ---------------------------- |
|
|
20
|
-
| `email` | `AUTH_EMAIL_SERVER` + `AUTH_EMAIL_FROM` | Email sign-in (Resend)¹ |
|
|
21
|
-
| `google` | `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` | Google OAuth |
|
|
22
|
-
| `github` | `GITHUB_CLIENT_ID` + `GITHUB_CLIENT_SECRET` | GitHub OAuth |
|
|
23
|
-
|
|
24
|
-
¹ Better Auth core ships no magic-link provider, so `email` is an
|
|
25
|
-
env-presence signal: it switches on the password method
|
|
26
|
-
(`emailAndPassword`) in `apps/web/auth.ts`, not a wired magic link.
|
|
27
|
-
|
|
28
|
-
## Auxiliary auth env vars
|
|
29
|
-
|
|
30
|
-
| Var | Default | Effect |
|
|
31
|
-
| ---------------------- | ------- | ------------------------------------------------------------------------------------- |
|
|
32
|
-
| `AILK_AUTH_REQUIRED` | unset | Read by `isAuthRequired()` in `apps/web/lib/auth-env.ts` (`"1"` or `"true"`). Default is auth-disabled / public, so a fresh scaffold boots without requiring any auth wiring. |
|
|
33
|
-
| `BETTER_AUTH_URL` | unset | The site's public origin (e.g. `https://your-domain.com`). Better Auth builds OAuth callback URLs on it and it is the one trusted origin; unset, Better Auth derives both from each request. Set it in production. Local dev can leave it unset. |
|
|
34
|
-
| `BETTER_AUTH_SECRET` | unset | Signs session cookies and email-verification tokens. **Required in production** — `apps/web/auth.ts` throws when it is unset there, rather than fall back to the development secret published in the source. Generate with `openssl rand -base64 32`. Optional for `next dev`. |
|
|
35
|
-
|
|
36
|
-
The skill writes none of these auxiliary vars on its own. It mentions
|
|
37
|
-
them in the closing summary so the consumer is aware:
|
|
38
|
-
|
|
39
|
-
- `AILK_AUTH_REQUIRED` is the consumer's call (skill always defaults
|
|
40
|
-
to leaving it unset).
|
|
41
|
-
- `BETTER_AUTH_URL` and `BETTER_AUTH_SECRET` are deferred to
|
|
42
|
-
production-time setup (`setup-deploy`), and a production deploy
|
|
43
|
-
fails without `BETTER_AUTH_SECRET`.
|
|
44
|
-
|
|
45
|
-
## Env-var formats — what valid values look like
|
|
46
|
-
|
|
47
|
-
### `AUTH_EMAIL_SERVER` (email sign-in via Resend)
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
smtp://resend:<RESEND_API_KEY>@smtp.resend.com:465
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
The Resend API key starts with `re_`. The literal username is the
|
|
54
|
-
string `resend` (Resend's SMTP convention). Port 465 is implicit-TLS
|
|
55
|
-
SMTP.
|
|
56
|
-
|
|
57
|
-
### `AUTH_EMAIL_FROM` (email sign-in via Resend)
|
|
58
|
-
|
|
59
|
-
A verified sender address on the consumer's Resend account. For
|
|
60
|
-
development, `onboarding@resend.dev` works without verification.
|
|
61
|
-
|
|
62
|
-
### `GOOGLE_CLIENT_ID` / `GITHUB_CLIENT_ID`
|
|
63
|
-
|
|
64
|
-
Public identifiers issued by Google / GitHub. Typically:
|
|
65
|
-
|
|
66
|
-
- Google: ends in `.apps.googleusercontent.com`
|
|
67
|
-
- GitHub: 20-character hex string
|
|
68
|
-
|
|
69
|
-
Either can be safely committed to a public template; production
|
|
70
|
-
secrets stay in `.env.local`.
|
|
71
|
-
|
|
72
|
-
### `GOOGLE_CLIENT_SECRET` / `GITHUB_CLIENT_SECRET`
|
|
73
|
-
|
|
74
|
-
Sensitive values. Treat as passwords. Never commit. The skill writes
|
|
75
|
-
these only to `.env.local` (which is in the consumer scaffold's
|
|
76
|
-
`.gitignore` by default).
|
|
77
|
-
|
|
78
|
-
## Detection of "already activated"
|
|
79
|
-
|
|
80
|
-
The skill's Step 1 menu marks providers as `[x]` when both required
|
|
81
|
-
vars are set in `.env.local`. The detection is presence-only — the
|
|
82
|
-
skill does not validate that the values actually work (no Google
|
|
83
|
-
API ping, no GitHub API ping, no test SMTP connection). A consumer
|
|
84
|
-
who pasted typos will get a runtime auth error from Better Auth on
|
|
85
|
-
their first sign-in attempt; the fix is to re-run the skill and
|
|
86
|
-
overwrite.
|
|
87
|
-
|
|
88
|
-
## Where these vars are read
|
|
89
|
-
|
|
90
|
-
- `apps/web/lib/auth-env.ts` — `getActiveProviderIds()` and
|
|
91
|
-
`isAuthRequired()`.
|
|
92
|
-
- `apps/web/auth.ts` — `buildSocialProviders()` consumes the
|
|
93
|
-
active-provider list and builds Better Auth's `socialProviders`
|
|
94
|
-
from the matching env vars; `resolveSecret()` reads
|
|
95
|
-
`BETTER_AUTH_SECRET`, and `baseURL` is `BETTER_AUTH_URL`.
|
|
96
|
-
|
|
97
|
-
The skill never modifies any of those files. All activation is
|
|
98
|
-
env-var-driven.
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# OAuth + Magic-Link Setup — RUNBOOK Template
|
|
2
|
-
|
|
3
|
-
The `add-auth` skill writes (or merges into) `RUNBOOK.md` at the
|
|
4
|
-
consumer's repo root using the per-provider sections below. Only the
|
|
5
|
-
sections for providers actually activated this session are emitted.
|
|
6
|
-
|
|
7
|
-
The skill **substitutes nothing** in these blocks at runtime — they're
|
|
8
|
-
copy-paste ready as-is. The only per-session variation is which
|
|
9
|
-
sections appear in the final runbook.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Provider section: magic-link (Resend)
|
|
14
|
-
|
|
15
|
-
```markdown
|
|
16
|
-
## Auth — magic-link (Resend)
|
|
17
|
-
|
|
18
|
-
Magic-link sign-in uses Resend as the email provider. Activation is
|
|
19
|
-
keyed off two env vars in `.env.local`:
|
|
20
|
-
|
|
21
|
-
- `AUTH_EMAIL_SERVER` — `smtp://resend:<API_KEY>@smtp.resend.com:465`
|
|
22
|
-
- `AUTH_EMAIL_FROM` — verified sender address on your Resend account
|
|
23
|
-
|
|
24
|
-
### One-time setup
|
|
25
|
-
|
|
26
|
-
1. Sign up at <https://resend.com> (free tier is fine for development).
|
|
27
|
-
2. Create an API key: <https://resend.com/api-keys>. Save it
|
|
28
|
-
somewhere safe — you'll only see it once.
|
|
29
|
-
3. Use a verified sender. For development, `onboarding@resend.dev` is
|
|
30
|
-
Resend's shared dev sender and works without verification. For
|
|
31
|
-
production, verify your own sending domain in the Resend dashboard.
|
|
32
|
-
|
|
33
|
-
### `.env.local` entries
|
|
34
|
-
|
|
35
|
-
\`\`\`
|
|
36
|
-
AUTH_EMAIL_SERVER=smtp://resend:re_yourapikeyhere@smtp.resend.com:465
|
|
37
|
-
AUTH_EMAIL_FROM=onboarding@resend.dev
|
|
38
|
-
\`\`\`
|
|
39
|
-
|
|
40
|
-
### Rotating the API key
|
|
41
|
-
|
|
42
|
-
If you rotate the Resend API key, update `AUTH_EMAIL_SERVER` in
|
|
43
|
-
`.env.local` and restart the dev server.
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## Provider section: Google OAuth
|
|
49
|
-
|
|
50
|
-
```markdown
|
|
51
|
-
## Auth — Google OAuth
|
|
52
|
-
|
|
53
|
-
Google sign-in is activated when both env vars are present in
|
|
54
|
-
`.env.local`:
|
|
55
|
-
|
|
56
|
-
- `GOOGLE_CLIENT_ID`
|
|
57
|
-
- `GOOGLE_CLIENT_SECRET`
|
|
58
|
-
|
|
59
|
-
### One-time setup
|
|
60
|
-
|
|
61
|
-
1. Open <https://console.cloud.google.com/apis/credentials>.
|
|
62
|
-
2. If you haven't yet, configure the OAuth consent screen:
|
|
63
|
-
- User type: **External** (unless you're inside a Workspace org).
|
|
64
|
-
- Fill in app name, support email, and developer contact email.
|
|
65
|
-
- Scopes are requested by Better Auth at runtime — leave the
|
|
66
|
-
consent screen scope list empty.
|
|
67
|
-
3. Click **Create Credentials → OAuth client ID**.
|
|
68
|
-
4. Application type: **Web application**.
|
|
69
|
-
5. Name: anything (e.g., "AILK dev").
|
|
70
|
-
6. **Authorized redirect URIs** — add exactly:
|
|
71
|
-
`http://localhost:3000/api/auth/callback/google`
|
|
72
|
-
7. Click **Create**. Copy the Client ID and Client secret from the
|
|
73
|
-
dialog (you can return to copy them later via the Credentials page).
|
|
74
|
-
|
|
75
|
-
### `.env.local` entries
|
|
76
|
-
|
|
77
|
-
\`\`\`
|
|
78
|
-
GOOGLE_CLIENT_ID=...
|
|
79
|
-
GOOGLE_CLIENT_SECRET=...
|
|
80
|
-
\`\`\`
|
|
81
|
-
|
|
82
|
-
### Production callback URL
|
|
83
|
-
|
|
84
|
-
The `localhost` callback above is dev-only. For production, you'll
|
|
85
|
-
need to add a second redirect URI to the same OAuth client (or
|
|
86
|
-
create a separate prod client) of the form
|
|
87
|
-
`https://<your-prod-domain>/api/auth/callback/google`. The
|
|
88
|
-
`setup-deploy` skill or your future deploy skill will help you
|
|
89
|
-
wire this when you're ready to ship.
|
|
90
|
-
|
|
91
|
-
### Rotating the client secret
|
|
92
|
-
|
|
93
|
-
In the Google Console, find the OAuth client, generate a new secret,
|
|
94
|
-
update `GOOGLE_CLIENT_SECRET` in `.env.local`, and restart the dev
|
|
95
|
-
server. The Client ID stays the same.
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Provider section: GitHub OAuth
|
|
101
|
-
|
|
102
|
-
```markdown
|
|
103
|
-
## Auth — GitHub OAuth
|
|
104
|
-
|
|
105
|
-
GitHub sign-in is activated when both env vars are present in
|
|
106
|
-
`.env.local`:
|
|
107
|
-
|
|
108
|
-
- `GITHUB_CLIENT_ID`
|
|
109
|
-
- `GITHUB_CLIENT_SECRET`
|
|
110
|
-
|
|
111
|
-
### One-time setup
|
|
112
|
-
|
|
113
|
-
1. Open <https://github.com/settings/developers>.
|
|
114
|
-
2. Click **New OAuth App**.
|
|
115
|
-
3. Application name: anything (e.g., "AILK dev").
|
|
116
|
-
4. Homepage URL: `http://localhost:3000`
|
|
117
|
-
5. **Authorization callback URL** — add exactly:
|
|
118
|
-
`http://localhost:3000/api/auth/callback/github`
|
|
119
|
-
6. Click **Register application**.
|
|
120
|
-
7. On the resulting app page, click **Generate a new client secret**
|
|
121
|
-
and copy it immediately (GitHub shows it once).
|
|
122
|
-
8. Copy the Client ID from the same page.
|
|
123
|
-
|
|
124
|
-
### `.env.local` entries
|
|
125
|
-
|
|
126
|
-
\`\`\`
|
|
127
|
-
GITHUB_CLIENT_ID=...
|
|
128
|
-
GITHUB_CLIENT_SECRET=...
|
|
129
|
-
\`\`\`
|
|
130
|
-
|
|
131
|
-
### Production callback URL
|
|
132
|
-
|
|
133
|
-
The `localhost` callback above is dev-only. For production, either
|
|
134
|
-
register a separate OAuth App with a `https://<your-prod-domain>/...`
|
|
135
|
-
callback, or update this app's callback (GitHub allows multiple).
|
|
136
|
-
The `setup-deploy` skill or your future deploy skill will help
|
|
137
|
-
you wire this when you're ready to ship.
|
|
138
|
-
|
|
139
|
-
### Rotating the client secret
|
|
140
|
-
|
|
141
|
-
Generate a new client secret on the app's GitHub page, update
|
|
142
|
-
`GITHUB_CLIENT_SECRET` in `.env.local`, and restart the dev server.
|
|
143
|
-
The Client ID stays the same.
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## Closing section (always emitted at the end of the runbook)
|
|
149
|
-
|
|
150
|
-
```markdown
|
|
151
|
-
## Activation summary
|
|
152
|
-
|
|
153
|
-
| Provider | Env vars | Active |
|
|
154
|
-
| ----------- | ------------------------------------------------- | ------ |
|
|
155
|
-
| magic-link | `AUTH_EMAIL_SERVER` + `AUTH_EMAIL_FROM` | <fill> |
|
|
156
|
-
| Google | `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` | <fill> |
|
|
157
|
-
| GitHub | `GITHUB_CLIENT_ID` + `GITHUB_CLIENT_SECRET` | <fill> |
|
|
158
|
-
|
|
159
|
-
A provider is **active** when both required env vars are set in
|
|
160
|
-
`.env.local`. The provider list is computed at server startup from env
|
|
161
|
-
vars only (`getActiveProviderIds()` in `apps/web/lib/auth-env.ts`) — there
|
|
162
|
-
are no `apps/web/auth.ts` edits to make.
|
|
163
|
-
|
|
164
|
-
To require sign-in for protected routes, set in `.env.local`:
|
|
165
|
-
|
|
166
|
-
\`\`\`
|
|
167
|
-
AILK_AUTH_REQUIRED=1
|
|
168
|
-
\`\`\`
|
|
169
|
-
|
|
170
|
-
Default (unset or `0`) is auth-disabled / public — useful while
|
|
171
|
-
building.
|
|
172
|
-
```
|