create-ailk 0.26.0 → 0.27.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 (34) hide show
  1. package/README.md +2 -2
  2. package/dist/module-architecture.js +2 -0
  3. package/dist/surfaces.js +7 -2
  4. package/dist/update.js +52 -2
  5. package/package.json +3 -3
  6. package/templates/.env.example +7 -0
  7. package/templates/CLAUDE.md +20 -20
  8. package/templates/README.md +19 -19
  9. package/templates/apps/api/.env.example +7 -0
  10. package/templates/apps/api/CLAUDE.md +21 -5
  11. package/templates/apps/api/vercel.json +7 -1
  12. package/templates/apps/web/.env.example +13 -0
  13. package/templates/apps/web/CLAUDE.md +13 -6
  14. package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/next-path.test.ts +24 -1
  15. package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +51 -0
  16. package/templates/apps/web/app/[locale]/(auth)/sign-in/next-path.ts +13 -0
  17. package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +10 -4
  18. package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/page.test.tsx +197 -4
  19. package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +23 -7
  20. package/templates/apps/web/app/[locale]/layout.tsx +15 -0
  21. package/templates/apps/web/app/api/auth/hub/authorize/__tests__/route.test.ts +118 -0
  22. package/templates/apps/web/app/api/auth/hub/authorize/route.ts +14 -0
  23. package/templates/apps/web/app/api/hub-session/__tests__/routes.test.ts +51 -0
  24. package/templates/apps/web/app/api/hub-session/sign-in/route.ts +13 -0
  25. package/templates/apps/web/lib/__tests__/relay.test.ts +289 -1
  26. package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +22 -2
  27. package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +11 -8
  28. package/templates/apps/web/lib/relay.ts +116 -1
  29. package/templates/apps/web/lib/sign-up-agreements.ts +17 -6
  30. package/templates/apps/web/messages/en.json +86 -1
  31. package/templates/apps/web/middleware.ts +8 -1
  32. package/templates/apps/web/next.config.mjs +9 -1
  33. package/templates/apps/web/package.json +2 -1
  34. package/versions.json +47 -47
package/README.md CHANGED
@@ -245,8 +245,8 @@ present, and this is the sign-in/account shell" from "always present, and
245
245
  this is the marketing core." A gateable surface's routes (`blog`, `docs`,
246
246
  `flows`, …) are checked only when the site carries that surface; a surface
247
247
  gated off at scaffold time is listed as skipped, not missing — its absence is
248
- deliberate, not drift. Add a surface with `--sync-architecture` and the
249
- `add-page` skill, not with `sync-routes`.
248
+ deliberate, not drift. Add a surface with `--sync-architecture` and
249
+ `/ailk:growth-ops page add`, not with `sync-routes`.
250
250
 
251
251
  **The local-module dependency contract (#5014, #9406).** Some routes import
252
252
  files OUTSIDE their own route directory — `purchase/success/page.tsx` imports
@@ -842,6 +842,8 @@ export const MODULE_SLICES = {
842
842
  "apps/web/app/[locale]/(authed)/admin/magnets/new/[kind]/page.tsx",
843
843
  "apps/web/app/[locale]/(authed)/admin/meetings/page.tsx",
844
844
  "apps/web/app/[locale]/(authed)/admin/meetings/[slug]/page.tsx",
845
+ // #9851 — the Integrations tab.
846
+ "apps/web/app/[locale]/(authed)/admin/integrations/page.tsx",
845
847
  ],
846
848
  // patches — the dependency add that delivers the shared package to the
847
849
  // buyer's apps/web, mirroring docs-blog's own fumadocs-schema merge-keys
package/dist/surfaces.js CHANGED
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * The default (`--modules marketing`) enables NO gateable surface: every one of
22
22
  * them is a claim about the business that the scaffolder cannot make. The path
23
- * from there is the `/ailk:add-page` skill in the `ailk` Claude Code plugin.
23
+ * from there is `/ailk:growth-ops page add`, from the `ailk` Claude Code plugin.
24
24
  *
25
25
  * Zero runtime dependencies — create-ailk is a published, standalone CLI.
26
26
  *
@@ -731,6 +731,8 @@ export const ROUTE_SINCE = {
731
731
  "(authed)/admin/magnets/new/[kind]": "0.46.0",
732
732
  "(authed)/admin/meetings": "0.46.0",
733
733
  "(authed)/admin/meetings/[slug]": "0.46.0",
734
+ // #9851 D7 — the Integrations tab, attached at today's fixed-group version.
735
+ "(authed)/admin/integrations": "0.48.0",
734
736
  // #5977 — the Pro content host's editor routes (spec 5872 FR1/FR2), added
735
737
  // to apps/web by #5957. Genuinely new route directories, so they attach at
736
738
  // today's fixed-group version, the same "attach at today's version" rule
@@ -1083,6 +1085,8 @@ export const ROUTE_DEPENDENCIES = {
1083
1085
  "(authed)/admin/magnets/new/[kind]": ADMIN_PANEL_ROUTE_DEPENDENCIES,
1084
1086
  "(authed)/admin/meetings": ADMIN_PANEL_ROUTE_DEPENDENCIES,
1085
1087
  "(authed)/admin/meetings/[slug]": ADMIN_PANEL_ROUTE_DEPENDENCIES,
1088
+ // #9851 D7 — the Integrations tab: the nav plus the Slack bindings.
1089
+ "(authed)/admin/integrations": ADMIN_PANEL_ROUTE_DEPENDENCIES,
1086
1090
  "(authed)/waitlist": ["apps/web/lib/server-api.ts"],
1087
1091
  // #8843 D6 — the booking pages share one builder over the meetings read;
1088
1092
  // `/private` returns the index frame that lives under `meet/`.
@@ -1144,6 +1148,7 @@ export const ROUTE_MESSAGE_NAMESPACES = {
1144
1148
  "(authed)/admin/magnets/new/[kind]": ["admin"],
1145
1149
  "(authed)/admin/meetings": ["admin"],
1146
1150
  "(authed)/admin/meetings/[slug]": ["admin"],
1151
+ "(authed)/admin/integrations": ["admin"],
1147
1152
  "(authed)/waitlist": ["waitlistDashboard.gate"],
1148
1153
  // #7744 — the /team hub's empty state reads the `team` namespace.
1149
1154
  team: ["team"],
@@ -1415,7 +1420,7 @@ export function renderNavConfig(enabled, options) {
1415
1420
  // below it, the nav is yours and add-module reports the change it wanted
1416
1421
  // instead.
1417
1422
  //
1418
- // Adding a link: scaffold the page (the \`/ailk:add-page\` skill), then add an
1423
+ // Adding a link: scaffold the page (\`/ailk:growth-ops page add\`), then add an
1419
1424
  // entry below with a \`labelKey\` that exists in the \`nav\` namespace of
1420
1425
  // \`apps/web/messages/<locale>.json\`. Paths are locale-agnostic — Nav prefixes
1421
1426
  // them with the active locale at render.
package/dist/update.js CHANGED
@@ -736,6 +736,47 @@ function planApiMove(targetDir, templatesDir, bootSet, recorded, versions) {
736
736
  move.review = unrecorded.review;
737
737
  return move;
738
738
  }
739
+ // ── The web app's carried dependencies (#9889 D9) ─────────────────────────
740
+ const WEB_PACKAGE_JSON = "apps/web/package.json";
741
+ /**
742
+ * The third-party packages `update` adds to a site's `apps/web/package.json`
743
+ * because template-owned web code imports them: `package.json` is never
744
+ * recorded, so without this a site updated onto that code would not build.
745
+ * Frozen; a name joins only with a spec.
746
+ */
747
+ const WEB_CARRIED_DEPENDENCIES = Object.freeze(["botid"]);
748
+ /**
749
+ * The site's `apps/web/package.json` with each carried dependency the running
750
+ * template declares and the site does not (in `dependencies` or
751
+ * `devDependencies`, at any range) added at the template's range, or
752
+ * `undefined` when there is nothing to add or no web app. Throws before any
753
+ * write when the site's file is not valid JSON.
754
+ */
755
+ function planWebDependencies(targetDir, templatesDir) {
756
+ const sitePath = join(targetDir, ...WEB_PACKAGE_JSON.split("/"));
757
+ const templatePath = join(templatesDir, ...WEB_PACKAGE_JSON.split("/"));
758
+ if (!existsSync(sitePath) || !existsSync(templatePath))
759
+ return undefined;
760
+ let pkg;
761
+ try {
762
+ pkg = JSON.parse(readFileSync(sitePath, "utf8"));
763
+ }
764
+ catch (err) {
765
+ throw new UpdateRefusedError(`${WEB_PACKAGE_JSON} is not valid JSON: ${err.message}`);
766
+ }
767
+ const templateDeps = JSON.parse(readFileSync(templatePath, "utf8")).dependencies ?? {};
768
+ const entries = {};
769
+ for (const name of WEB_CARRIED_DEPENDENCIES) {
770
+ const range = templateDeps[name];
771
+ if (range === undefined)
772
+ continue;
773
+ if (Object.hasOwn(pkg.dependencies ?? {}, name) || Object.hasOwn(pkg.devDependencies ?? {}, name)) {
774
+ continue;
775
+ }
776
+ entries[name] = range;
777
+ }
778
+ return Object.keys(entries).length > 0 ? withDependencies(pkg, entries) : undefined;
779
+ }
739
780
  export async function updateSite(opts) {
740
781
  const targetDir = resolve(opts.targetDir);
741
782
  const version = opts.version;
@@ -905,6 +946,9 @@ export async function updateSite(opts) {
905
946
  const apiMove = existsSync(apiPkgPath)
906
947
  ? planApiMove(targetDir, opts.templatesDir, new Set([...newMap.keys()].filter((path) => path.startsWith(`${API_SRC}/`))), new Set(Object.keys(record.files)), opts.versions ?? {})
907
948
  : undefined;
949
+ // ── The web app's carried dependencies (#9889 D9), planned before the
950
+ // first write so an unparseable apps/web/package.json refuses the run.
951
+ const webPackageJson = planWebDependencies(targetDir, opts.templatesDir);
908
952
  // ── Every recorded row (D4) ────────────────────────────────────────────
909
953
  const updated = [];
910
954
  const merged = [];
@@ -1201,6 +1245,11 @@ export async function updateSite(opts) {
1201
1245
  moved.updated.push(API_PACKAGE_JSON);
1202
1246
  pruneEmptyDirs(join(targetDir, ...API_SRC.split("/")));
1203
1247
  }
1248
+ // #9889 D9 — the web app's carried dependencies, after the record's writes.
1249
+ if (webPackageJson !== undefined) {
1250
+ writeFileSync(join(targetDir, ...WEB_PACKAGE_JSON.split("/")), webPackageJson);
1251
+ moved.updated.push(WEB_PACKAGE_JSON);
1252
+ }
1204
1253
  return {
1205
1254
  targetDir,
1206
1255
  version,
@@ -1254,8 +1303,9 @@ export function formatUpdateReport(result) {
1254
1303
  return `[create-ailk] Already up to date (create-ailk ${result.version}).\n`;
1255
1304
  }
1256
1305
  // #9567 / #9566 — the MCP and API moves add dependencies (the mcp README
1257
- // § Move, step 7, names the install; the API half says the same).
1258
- for (const pkgJson of [MCP_PACKAGE_JSON, API_PACKAGE_JSON]) {
1306
+ // § Move, step 7, names the install; the API half says the same), and so
1307
+ // does the web app's carried-dependency step (#9889 D9).
1308
+ for (const pkgJson of [MCP_PACKAGE_JSON, API_PACKAGE_JSON, WEB_PACKAGE_JSON]) {
1259
1309
  if (result.updated.includes(pkgJson)) {
1260
1310
  lines.push(`${pkgJson} gained dependencies: run \`pnpm install\`.`);
1261
1311
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-ailk",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Scaffolder for AI Launch Kit — `pnpm create ailk@latest <dir>` produces a starter repo consuming @working-theory/* from npm (per ADR 0007).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,8 +28,8 @@
28
28
  "tar": "^7.5.21"
29
29
  },
30
30
  "devDependencies": {
31
- "@working-theory/schema": "0.48.0",
32
- "@working-theory/templates": "0.48.0"
31
+ "@working-theory/schema": "0.49.0",
32
+ "@working-theory/templates": "0.49.0"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",
@@ -469,6 +469,13 @@ CONTENT_ADAPTER=mdx
469
469
  # header against (#6085). Unset makes the receiver answer 503 and accept
470
470
  # nothing — the same fail-closed posture an unset STRIPE_WEBHOOK_SECRET has.
471
471
  # CAL_WEBHOOK_SECRET=
472
+ # The prospect-channel archive cron's secret (#9855). Vercel Cron sends it as
473
+ # `Authorization: Bearer <CRON_SECRET>` to GET /v1/cron/prospect-channel-archive
474
+ # (the scheduling module; the scaffold's apps/api/vercel.json schedules it
475
+ # daily). Generate it with `openssl rand -hex 32`. Unset, or shorter than 32
476
+ # characters, makes the route answer 503 and archive nothing. The bin
477
+ # (`prospect-channel-archive:sweep`) needs no secret.
478
+ # CRON_SECRET=
472
479
  # SCHEDULING_PUBLIC_BASE_URL=https://cal.com
473
480
  # SCHEDULING_PROVIDER=cal
474
481
 
@@ -73,7 +73,7 @@ your module set; `pnpm architecture` enforces it, and a hook in
73
73
  | Diff hygiene when editing existing files | `CONVENTIONS.md` § Commit + diff hygiene |
74
74
  | Code style, testing, security | `CONVENTIONS.md` |
75
75
  | Environment variables and what they unlock | `.env.example` |
76
- | Deploy configuration | `apps/api/vercel.json`; the `/ailk:setup-deploy` skill |
76
+ | Deploy configuration | `apps/api/vercel.json`; `/ailk:growth-ops deploy` |
77
77
  | Verification before push | `pnpm preflight` (see § Checks) |
78
78
 
79
79
  <!-- /ailk:template id="resource-map" -->
@@ -82,30 +82,30 @@ your module set; `pnpm architecture` enforces it, and a hook in
82
82
 
83
83
  ## Skills
84
84
 
85
- The AI Launch Kit skills come from the `ailk` Claude Code plugin, not from
86
- this repo. `.claude/settings.json` names its marketplace and enables it, so
87
- Claude Code loads it once you trust this folder. To install it by hand, run
88
- these two lines in a Claude Code session:
85
+ The AI Launch Kit skill, `growth-ops`, comes from the `ailk` Claude Code
86
+ plugin, not from this repo. `.claude/settings.json` names its marketplace and
87
+ enables it, so Claude Code loads it once you trust this folder. To install it
88
+ by hand, run these two lines in a Claude Code session:
89
89
 
90
90
  ```
91
91
  /plugin marketplace add working-theory-labs/claude-plugins
92
92
  /plugin install ailk@working-theory
93
93
  ```
94
94
 
95
- | Skill | Use when |
96
- | ---------------------- | ----------------------------------------------------------------- |
97
- | `/ailk:add-page` | You need a new page, or extra JSON-LD on an existing one |
98
- | `/ailk:update-page` | A page should live at a different URL, or needs a new title |
99
- | `/ailk:fill-page` | A page still carries `{placeholder}` copy |
100
- | `/ailk:check-site` | You want the site's citation-readiness score and findings |
101
- | `/ailk:setup-database` | Leads should land in a database inbox at `/leads` |
102
- | `/ailk:setup-deploy` | You are ready to deploy to Vercel |
103
- | `/ailk:add-auth` | Visitors need to sign in (email, Google, GitHub) |
104
- | `/ailk:upgrade-plan` | You are weighing Free against a paid level or the commerce add-on |
105
-
106
- A repo scaffolded by an earlier create-ailk also carries its own older
107
- copies of these skills. Once the plugin is installed, delete those copies;
108
- keep scaffold-commerce, which the commerce module delivers.
95
+ | Command | Use when |
96
+ | ------------------------------ | ----------------------------------------------------------------- |
97
+ | `/ailk:growth-ops page add` | You need a new page, or extra JSON-LD on an existing one |
98
+ | `/ailk:growth-ops page rename` | A page should live at a different URL, or needs a new title |
99
+ | `/ailk:growth-ops page fill` | A page still carries `{placeholder}` copy |
100
+ | `/ailk:growth-ops audit` | You want the site's citation-readiness score and findings |
101
+ | `/ailk:growth-ops database` | Leads should land in a database inbox at `/leads` |
102
+ | `/ailk:growth-ops deploy` | You are ready to deploy to Vercel |
103
+ | `/ailk:growth-ops auth` | Visitors need to sign in (email, Google, GitHub) |
104
+ | `/ailk:growth-ops plan` | You are weighing Free against a paid level or the commerce add-on |
105
+
106
+ Ask in plain words and `growth-ops` picks the verb. An older scaffold also
107
+ carries its own copies of these jobs as skills: once the plugin is installed,
108
+ delete them; keep scaffold-commerce, which the commerce module delivers.
109
109
 
110
110
  For design work, the third-party impeccable plugin is optional:
111
111
  `/plugin marketplace add pbakaus/impeccable`, then
@@ -125,7 +125,7 @@ For design work, the third-party impeccable plugin is optional:
125
125
  | `pnpm type-check` | Type errors in every workspace |
126
126
  | `pnpm lint` | Lint errors in every workspace |
127
127
  | `pnpm test` | Failing unit tests |
128
- | `/ailk:check-site` skill | Missing or invalid JSON-LD, weak citation-readiness |
128
+ | `/ailk:growth-ops audit` | Missing or invalid JSON-LD, weak citation-readiness |
129
129
 
130
130
  `.github/workflows/ci.yml` runs the preflight checks and `pnpm test` on every
131
131
  pull request as the `preflight` status check. One step is yours: make
@@ -77,7 +77,7 @@ A page marked `--shape organization-product` is in your site when you scaffolded
77
77
 
78
78
  To customize the home page, edit [`content/en/HomePage/home.mdx`](./content/en/HomePage/home.mdx). Save and reload the dev server. No build step.
79
79
 
80
- To add a new page, ask Claude Code to run the `/ailk:add-page` skill — it writes the page's content file and nav link in one confirm-before-write pass, and adds a missing route with `create-ailk add-route` first. See [Skills](#skills).
80
+ To add a new page, ask Claude Code to run `/ailk:growth-ops page add` — it writes the page's content file and nav link in one confirm-before-write pass, and adds a missing route with `create-ailk add-route` first. See [Skills](#skills).
81
81
 
82
82
  > `content/_site.mdx` stays at the top level (not under `content/en/`) — site identity is locale-blind.
83
83
 
@@ -135,12 +135,12 @@ Set `AILK_PUBLIC_DOMAIN` to your own domain. `STEALTH=true` keeps a fresh deploy
135
135
 
136
136
  You need Postgres once you turn on one of these:
137
137
 
138
- | Surface | What it stores |
139
- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
140
- | **Auth** — `/sign-in`, `/sign-up`, `/account` | users, sessions, accounts |
141
- | **Lead inbox** — `/leads` | submitted leads, for you to review signed in, and newsletter signups. Without a database, lead capture emails each contact-form message to you instead (`RESEND_API_KEY` + `AILK_LEAD_NOTIFICATION_TO` + `AILK_LEAD_NOTIFICATION_FROM` on the API); with neither in production, `/contact` shows your `_site.mdx` `contactEmail` instead of the form. The `setup-database` skill walks you from no database to a working inbox. |
142
- | **Checkout returns** — `/purchase/success`, `/purchase/cancel` | the paid checkouts the Stripe webhook records. These pages serve only on a site licensed for commerce. |
143
- | **`CONTENT_ADAPTER=database`** | pages authored in the Artifact store rather than in `content/*.mdx` |
138
+ | Surface | What it stores |
139
+ | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
140
+ | **Auth** — `/sign-in`, `/sign-up`, `/account` | users, sessions, accounts |
141
+ | **Lead inbox** — `/leads` | submitted leads, for you to review signed in, and newsletter signups. Without a database, lead capture emails each contact-form message to you instead (`RESEND_API_KEY` + `AILK_LEAD_NOTIFICATION_TO` + `AILK_LEAD_NOTIFICATION_FROM` on the API); with neither in production, `/contact` shows your `_site.mdx` `contactEmail` instead of the form. `/ailk:growth-ops database` walks you from no database to a working inbox. |
142
+ | **Checkout returns** — `/purchase/success`, `/purchase/cancel` | the paid checkouts the Stripe webhook records. These pages serve only on a site licensed for commerce. |
143
+ | **`CONTENT_ADAPTER=database`** | pages authored in the Artifact store rather than in `content/*.mdx` |
144
144
 
145
145
  ### One command to get one
146
146
 
@@ -165,7 +165,7 @@ That is the whole setup. `pnpm db:studio` opens a browser UI over the data, and
165
165
 
166
166
  ## Deploy
167
167
 
168
- Ask Claude Code to run the `setup-deploy` skill. It writes a Vercel deploy configuration at the project root — `vercel.json`, an `.env.example` covering the variables production needs, and a `RUNBOOK.md` with the steps — and asks before overwriting any file you already have. Vercel is the one platform it supports today. `apps/api` already ships its own `vercel.json`.
168
+ Ask Claude Code to run `/ailk:growth-ops deploy`. It writes a Vercel deploy configuration at the project root — `vercel.json`, an `.env.example` covering the variables production needs, and a `RUNBOOK.md` with the steps — and asks before overwriting any file you already have. Vercel is the one platform it supports today. `apps/api` already ships its own `vercel.json`.
169
169
 
170
170
  The [deploy guide](https://ailaunchkit.ai/docs/guides/deploy-to-production) is where the full production walkthrough will live; until it is published, the skill's `RUNBOOK.md` is the checklist. Remember to set `STEALTH=false` on the hosting platform when you launch.
171
171
 
@@ -208,17 +208,17 @@ The AI Launch Kit skills come from the `ailk` Claude Code plugin; `.claude/setti
208
208
 
209
209
  <!-- generated:begin skills -->
210
210
 
211
- | Skill | What it does |
212
- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
213
- | `/ailk:add-auth` | Activate the site's sign-in providers (email-and-password, Google OAuth, GitHub OAuth) and write the env vars for the ones you pick. |
214
- | `/ailk:add-page` | Add a new page — its content file, its structured data and its nav link — in one confirm-before-write pass. |
215
- | `/ailk:check-site` | Run `ailk-audit` on the site and explain the score and findings in plain language. It never edits files. |
216
- | `/ailk:extend-site` | Explain the five ways this site may be extended, walk you to the right one, and record a site-authored file in `customizations.yaml` with its build-in decision. |
217
- | `/ailk:fill-page` | Fill one existing page's section content from a category profile: labelled sample content, or your own first draft from a short intake. |
218
- | `/ailk:setup-database` | Take the site from no database to a working lead inbox, and prove it with one test message that must appear in the inbox. |
219
- | `/ailk:setup-deploy` | Emit deploy configuration — `vercel.json` and `RUNBOOK.md`, plus an env checklist read from the site's own `.env.example`. |
220
- | `/ailk:update-page` | Rename a page — its URL, its title, or both — in one plan-then-confirm pass, with a permanent redirect from the old URL. |
221
- | `/ailk:upgrade-plan` | Explain the AI Launch Kit options side by side, recommend one option for this site, and link the public pricing page for prices. |
211
+ | Command | What it does |
212
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
213
+ | `/ailk:growth-ops page add` | Add a new page — its content file, its structured data and its nav link — in one confirm-before-write pass. |
214
+ | `/ailk:growth-ops page rename` | Rename a page — its URL, its title, or both — in one plan-then-confirm pass, with a permanent redirect from the old URL. |
215
+ | `/ailk:growth-ops page fill` | Fill one existing page's section content from a category profile: labelled sample content, or your own first draft from a short intake. |
216
+ | `/ailk:growth-ops audit` | Run `ailk-audit` on the site and explain the score and findings in plain language. It never edits files. |
217
+ | `/ailk:growth-ops extend` | Explain the five ways this site may be extended, walk you to the right one, and record a site-authored file in `customizations.yaml` with its build-in decision. |
218
+ | `/ailk:growth-ops auth` | Activate the site's sign-in providers (email-and-password, Google OAuth, GitHub OAuth) and write the env vars for the ones you pick. |
219
+ | `/ailk:growth-ops database` | Take the site from no database to a working lead inbox, and prove it with one test message that must appear in the inbox. |
220
+ | `/ailk:growth-ops deploy` | Emit deploy configuration — `vercel.json` and `RUNBOOK.md`, plus an env checklist read from the site's own `.env.example`. |
221
+ | `/ailk:growth-ops plan` | Explain the AI Launch Kit options side by side, recommend one option for this site, and link the public pricing page for prices. |
222
222
 
223
223
  <!-- generated:end -->
224
224
 
@@ -170,6 +170,13 @@ STRIPE_WEBHOOK_SECRET=whsec_xxx
170
170
  # equals the caller's own workspace id: the receiver writes under
171
171
  # AILK_SITE_ID, the read scopes to the tenant's workspace, and a mismatch
172
172
  # fails EMPTY, never wide.
173
+ # The prospect-channel archive cron's secret (#9855). Vercel Cron sends it as
174
+ # `Authorization: Bearer <CRON_SECRET>` to GET /v1/cron/prospect-channel-archive
175
+ # (the scheduling module; the scaffold's apps/api/vercel.json schedules it
176
+ # daily). Generate it with `openssl rand -hex 32`. Unset, or shorter than 32
177
+ # characters, makes the route answer 503 and archive nothing. The bin
178
+ # (`prospect-channel-archive:sweep`) needs no secret.
179
+ # CRON_SECRET=
173
180
 
174
181
  # =============================================================================
175
182
  # Paid modules (D-44, #5368)