@aotter/mantle 0.0.11-alpha.32 → 0.0.11-alpha.34

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 CHANGED
@@ -32,12 +32,13 @@ import { mountServerEndpoints } from "@aotter/mantle/cloudflare";
32
32
  ## Getting started
33
33
 
34
34
  Recommended path: open the Mantle landing page, answer the launch
35
- questions, sign in with GitHub, then paste the generated launch command
36
- into Claude Code / Cursor / Codex. The short-lived launch session carries
37
- the scaffold values, so the agent can run `create-mantle launch` first
38
- and continue with provisioning.
35
+ questions, and sign in with GitHub and Cloudflare. Landing provisions the
36
+ site server-side it creates the private GitHub repo, commits a blank
37
+ deployable Mantle site, and connects the first Cloudflare deploy. Then
38
+ point your coding agent (Claude Code / Cursor / Codex) at the provisioned
39
+ repo to continue.
39
40
 
40
- Available starter keys and direct scaffolder usage live in [`aotter/mantle-starters`](https://github.com/aotter/mantle-starters): `presence`, `publication`, `intake`, `transaction`, and `blank`. See `skills/install` in the [Mantle repo](https://github.com/aotter/mantle/tree/develop/skills/install) for the full agent-driven install flow.
41
+ Starter source and provision bundles live in [`aotter/mantle-starters`](https://github.com/aotter/mantle-starters); launch starts from the blank base and the agent applies the selected type as a post-launch overlay. See `skills/install` in the [Mantle repo](https://github.com/aotter/mantle/tree/develop/skills/install) for how the agent continues a provisioned repo.
41
42
 
42
43
  ## Adapter targets
43
44
 
@@ -47,9 +47,9 @@ encode step to where it already runs in a real Node-like runtime:
47
47
  - Scaffolders, ops scripts, the admin SPA's local helper, and MCP
48
48
  agents (Claude Code, etc.) all execute in environments where
49
49
  `sharp` works.
50
- - A dedicated `@aotter/mantle-media-tools` package ships agent-side
51
- CLI + library helpers that take a source file, produce the format
52
- set, call `create_media_upload`, upload every variant, and call
50
+ - The MCP client or operator tooling runs the agent-side image
51
+ processor: take a source file, produce the format set, call
52
+ `create_media_upload`, upload every variant, and call
53
53
  `commit_media_upload`.
54
54
  - The Worker only **enforces policy**: required mime set, per-mime
55
55
  byte caps, suspicious-shape heuristic (modern format must not be
@@ -178,4 +178,4 @@ use case layer via the repository. The R2 adapter:
178
178
  - `packages/mantle-runtime/src/infrastructure/persistence/DatabaseMediaAssetRepository.ts`
179
179
  - `packages/mantle-spec/src/domain/model/SiteConfig.ts` (MediaPurposePolicy)
180
180
  - `packages/adapters/cloudflare/src/bindings/R2MediaStorage.ts`
181
- - `mantle-starters/packages/mantle-media-tools/` (agent-side helper)
181
+ - MCP client / operator-side image processing tools
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aotter/mantle",
3
- "version": "0.0.11-alpha.32",
3
+ "version": "0.0.11-alpha.34",
4
4
  "description": "Umbrella entry for @aotter/mantle. Adopters install this one package and import from subpaths: /spec, /runtime, /cloudflare, /admin-ui. Sub-packages remain individually installable on npm for tooling / alt-adapter authors. The Netlify adapter ships as a private workspace stub in v0.1 — its subpath will be added when the impl lands in v0.2.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://mantle.tools/",
@@ -47,10 +47,10 @@
47
47
  "README.md"
48
48
  ],
49
49
  "dependencies": {
50
- "@aotter/mantle-admin-ui": "0.0.11-alpha.32",
51
- "@aotter/mantle-runtime": "0.0.11-alpha.32",
52
- "@aotter/mantle-spec": "0.0.11-alpha.32",
53
- "@aotter/mantle-cloudflare": "0.0.11-alpha.32"
50
+ "@aotter/mantle-cloudflare": "0.0.11-alpha.34",
51
+ "@aotter/mantle-admin-ui": "0.0.11-alpha.34",
52
+ "@aotter/mantle-runtime": "0.0.11-alpha.34",
53
+ "@aotter/mantle-spec": "0.0.11-alpha.34"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@cloudflare/workers-oauth-provider": "^0.7.0",
package/skills/README.md CHANGED
@@ -4,10 +4,10 @@ Agent-readable skill briefs for consumers of `@aotter/mantle-*`. Discoverable by
4
4
 
5
5
  | Skill | When to invoke |
6
6
  |---|---|
7
- | [`install`](install/SKILL.md) | User wants to start a new mantle project. Preferred path consumes a landing-created launch session and runs the generated `create-mantle` command from the [starters monorepo](https://github.com/aotter/mantle-starters), including any selected source feature overlays. |
7
+ | [`install`](install/SKILL.md) | User wants to start or continue a Mantle site. Sites launch on [Mantle landing](https://mantle.tools), which provisions the GitHub repo and first Cloudflare deploy; this brief orients the agent to take over and continue the provisioned repo. |
8
8
  | [`customize-design`](customize-design/SKILL.md) | User wants to rebrand or restyle a publication starter project. Walks the L1–L4 theme stack (tokens / extraCss+icons+i18n / Header+Footer / whole-template). |
9
9
  | [`extend`](extend/SKILL.md) | User has an existing project and wants to add a Schema / View / Procedure / Trigger or wire a feature (contact form, search, newsletter signup). |
10
- | [`provision`](provision/SKILL.md) | User wants to deploy to production through starter-owned lifecycle scripts: OAuth verifier swap, secrets, prod D1/KV, custom domain, and explicitly selected feature resources. |
10
+ | [`provision`](provision/SKILL.md) | User wants production fully usable after a landing launch. Verify the Cloudflare deploy, wire per-site staff auth (GitHub OAuth App + Worker secrets), smoke test, and hand off the operator setup URL. |
11
11
 
12
12
  The skills target `mantle@v0.1.0`. Each one names its assumed grammar version in the front-matter `applies_to:` field; future versions add a sibling SKILL.md or update the existing one.
13
13
 
@@ -1,26 +1,24 @@
1
1
  ---
2
2
  name: mantle install
3
- description: Install a Mantle consumer project from a landing-created launch command/session, then continue into deterministic provision. Use when the user pasted a Mantle launch command or session URL.
3
+ description: Orient and continue a Mantle site that Mantle landing has provisioned. Mantle sites launch on Mantle landing (mantle.tools), which creates the GitHub repo and the first Cloudflare deploy; the agent takes over the provisioned repo to complete the selected type, first pages, and content. Use when the user pasted a Mantle launch / after-launch context, opened a landing-provisioned repo, or wants to start a new Mantle site.
4
4
  when_to_invoke: |
5
- The user has a Mantle landing launch command/session URL and wants a new Mantle site scaffolded.
5
+ The user wants a new Mantle site, pasted a Mantle landing launch / after-launch context, or opened a repo that Mantle landing provisioned and wants help continuing it.
6
6
  ---
7
7
 
8
8
  # mantle install
9
9
 
10
- You are installing a Mantle site for the user. The normal path is:
10
+ Mantle sites are launched on **Mantle landing** (`https://mantle.tools`),
11
+ not scaffolded locally. Landing asks the launch questions, then provisions
12
+ server-side: it creates the user's private GitHub repo, commits a blank
13
+ deployable Mantle site, and connects Cloudflare Workers CI for the first
14
+ deploy. Your job is to **continue that provisioned repo** — complete the
15
+ selected type, first pages, and content — not to scaffold from scratch.
11
16
 
12
- 1. Mantle landing asks the launch questions.
13
- 2. Landing renders a short-lived launch session and `create-mantle`
14
- command.
15
- 3. You run that command from the parent directory where the project
16
- should be created.
17
- 4. You validate the generated repo, push it to the user's GitHub, then
18
- continue with repo-local `mantle:provision`.
19
-
20
- Do not rebuild the old interview harness in chat. If the user has no
21
- landing-created launch command/session, send them back to Mantle landing
22
- to create one. Manual flag-by-flag scaffolding is for maintainers
23
- debugging the scaffolder, not the user-facing install UX.
17
+ There is no local scaffolder to run. The `create-mantle` CLI was retired
18
+ when provisioning moved into landing. If the user has not launched yet,
19
+ send them to `https://mantle.tools` to launch, then resume here once the
20
+ repo exists. Do not rebuild the old manual interview / prompt-composition
21
+ harness.
24
22
 
25
23
  ## Ground Truth
26
24
 
@@ -39,125 +37,62 @@ consumer project from these four atoms plus user TypeScript. Full grammar
39
37
  reference:
40
38
  <https://raw.githubusercontent.com/aotter/mantle/develop/docs/design-atoms.md>.
41
39
 
42
- After `create-mantle` runs, the scaffold's ground truth lives in:
40
+ A landing-provisioned repo carries its launch context and ground truth in:
43
41
 
44
42
  | Path | Contents |
45
43
  |---|---|
44
+ | `.mantle/launch-state.json` | Non-secret launch choices: type, purpose, locales, repo, owner, suggested overlay |
45
+ | `.mantle/features.json` | Selected feature overlays and applied state |
46
+ | `.mantle/handoff.md` | The launch handoff note written for you |
46
47
  | `manifests/*.yaml` | Schemas / Views / Procedures / Triggers |
47
48
  | `src/mantleConfig.ts` | Site defaults, handler registration, runtime bindings |
48
49
  | `src/handlers/` | Handler implementations |
49
- | `src/.mantle/generated.*.ts` | Scaffolder-owned feature glue |
50
- | `.mantle/features.json` | Selected feature overlays |
51
- | `.mantle/launch-state.json` | Non-secret launch choices from landing |
52
50
  | `AGENTS.md` | Cross-tool agent entry |
51
+ | `.agent/skills/` + `.claude/skills/` | Repo-local skills: `mantle:develop`, `mantle:overlay`, `mantle:theme`, `mantle:update` |
53
52
 
54
- ## Accepted Inputs
55
-
56
- Use the launch-session fast path when the prompt contains either:
57
-
58
- - a command shaped like `npx <tarball> launch --session <url-or-file>`;
59
- - a command shaped like `npx <tarball> <archetype> ...` generated by
60
- Mantle landing;
61
- - a launch session URL/file plus instructions to run `create-mantle
62
- launch`.
63
-
64
- Landing already collected the launch-critical values. Treat those values
65
- as user-authorized for scaffolding. Do not ask content, voice, repo, or
66
- locale questions again before scaffold.
67
-
68
- The launch session/command authorizes only initial scaffold values:
69
-
70
- - project name;
71
- - brand / site name;
72
- - archetype;
73
- - theme and selected feature overlays;
74
- - locales and canonical locale;
75
- - GitHub owner / admin login;
76
- - install description and summary.
77
-
78
- It does not authorize Cloudflare resources, provider billing, OAuth
79
- secrets, custom domains, or production deploy.
80
-
81
- ## Preflight
82
-
83
- Run these before creating files:
84
-
85
- ```bash
86
- node --version # need >= 22
87
- pnpm --version # need >= 9
88
- git --version
89
- ```
90
-
91
- Confirm the current working directory is the parent directory where the
92
- new project should appear. If the child project directory already exists,
93
- stop and ask the user whether to choose another empty directory. Do not
94
- merge a fresh scaffold into an existing project.
95
-
96
- ## Scaffold
97
-
98
- Run the launch command exactly as supplied. Do not rewrite values. Only
99
- replace an obvious local file path if the user gave the file out of band.
53
+ ## Take Over a Provisioned Repo
100
54
 
101
- Examples:
55
+ The repo was already created and deployed by landing. Continue it:
102
56
 
103
- ```bash
104
- npx <create-mantle-tarball> launch --session <session-url-or-file>
105
- ```
106
-
107
- ```bash
108
- npx <create-mantle-tarball> <archetype> \
109
- --project-name <project-name> \
110
- --brand "<brand>" \
111
- --description "<description>" \
112
- --locales "<locale[,locale]>" \
113
- --github-owner <github-owner> \
114
- --admin-github-login <admin-login> \
115
- --summary "<summary>"
116
- ```
117
-
118
- `create-mantle` validates the session before filesystem writes,
119
- downloads the requested starter ref, merges `_common/` + `<archetype>/`
120
- + feature overlays + theme overlays, fills placeholders, runs
121
- `git init`, runs `pnpm install`, writes `.mantle/launch-state.json`, and
122
- prints RUN_NOTES JSON.
123
-
124
- After it returns:
125
-
126
- 1. Read RUN_NOTES.
127
- 2. Read `.mantle/launch-state.json`.
128
- 3. Walk the ground-truth files above.
129
- 4. Continue with local validation.
130
-
131
- ## Local Validation
132
-
133
- From the generated project root:
57
+ 1. Confirm repository access through an available GitHub connector or MCP
58
+ tool. Use GitHub CLI only if it is already authenticated.
59
+ 2. Clone or open the repo, then read `.mantle/launch-state.json`,
60
+ `.mantle/features.json`, and `.mantle/handoff.md`.
61
+ 3. Inspect the four-atoms manifest, the type overlay notes, pages, and
62
+ seed data before changing code.
63
+ 4. Validate locally before editing:
134
64
 
135
65
  ```bash
66
+ pnpm install --frozen-lockfile
136
67
  pnpm validate
137
68
  pnpm typecheck
138
- if node -e "process.exit(require('./package.json').scripts?.test ? 0 : 1)"; then
139
- pnpm test
140
- else
141
- echo "No pnpm test script; skipping."
142
- fi
143
- ```
144
-
145
- Run deploy validation if the starter exposes it:
146
-
147
- ```bash
148
- if node -e "process.exit(require('./package.json').scripts?.['validate:deploy'] ? 0 : 1)"; then
149
- pnpm validate:deploy
150
- else
151
- pnpm validate --phase deploy
152
- fi
153
69
  ```
154
70
 
155
71
  Diagnostics are structured JSON with `code` and `suggestion` fields.
156
72
  Surface both verbatim when validation fails.
157
73
 
74
+ ## Continue With Repo-Local Skills
75
+
76
+ The generated repo ships its own skills under `.agent/skills/` and
77
+ `.claude/skills/`. Hand off to the one that fits the work:
78
+
79
+ - **`mantle:overlay`** — apply the selected launch type as a small
80
+ post-launch overlay (first useful pages plus tiny seed data in the
81
+ user's language). This is the usual first step on a fresh blank launch.
82
+ - **`mantle:develop`** — manifest, runtime, content-model, layout,
83
+ bug-fix, and validation work on the site.
84
+ - **`mantle:theme`** — brand and visual direction via Mantle / Kiwa tokens
85
+ and source. There is no premade theme picker; visual direction is agent
86
+ work after launch.
87
+ - **`mantle:update`** — compare the repo against its upstream provision
88
+ bundle.
89
+
90
+ Remove the placeholder blank homepage once the selected type ships a real
91
+ homepage.
92
+
158
93
  ## Local Preview
159
94
 
160
- If the user wants to see the scaffold locally:
95
+ To see the site locally before pushing:
161
96
 
162
97
  ```bash
163
98
  [ -f .dev.vars.example ] && cp .dev.vars.example .dev.vars
@@ -165,64 +100,28 @@ openssl rand -hex 32
165
100
  pnpm dev
166
101
  ```
167
102
 
168
- Paste the generated random value into `.dev.vars` as
169
- `BETTER_AUTH_SECRET`. This secret is local only and must not be reused
170
- for production. Use `localhost`, not `127.0.0.1`, in local examples.
103
+ Paste the generated random value into `.dev.vars` as `BETTER_AUTH_SECRET`.
104
+ This secret is local only and must not be reused for production. Use
105
+ `localhost`, not `127.0.0.1`, in local examples. A fresh blank site may
106
+ return 404 on the public home route until the type overlay adds one; treat
107
+ that as an empty-site state, not a failure, when validation and admin
108
+ routes are alive.
171
109
 
172
- A fresh scaffold may legitimately return 404 for the public home route
173
- because production content is not seeded yet. Treat that as an empty-site
174
- state, not a failed install, when validation and admin routes are alive.
110
+ ## Production
175
111
 
176
- ## Provision Handoff
177
-
178
- Commit the deterministic scaffold:
179
-
180
- ```bash
181
- git status --short
182
- git add .
183
- git commit -m "mantle: deterministic scaffold"
184
- ```
185
-
186
- Then continue in the same conversation with the repo-local provision
112
+ Landing already created the GitHub repo and the first Cloudflare deploy.
113
+ To finish production — verify the deploy, wire per-site staff auth, smoke
114
+ test, and hand off the operator setup URL — continue with the provision
187
115
  skill:
188
-
189
- ```text
190
- .agent/skills/mantle-provision/SKILL.md
191
- ```
192
-
193
- The current provision shape is provider-first:
194
-
195
- 1. The agent creates/pushes the user's private GitHub repo.
196
- 2. The user creates the first Cloudflare Worker deploy from that GitHub
197
- repo in Cloudflare Dashboard.
198
- 3. The user reports the Worker URL.
199
- 4. The user creates the per-site GitHub OAuth App.
200
- 5. The agent runs `pnpm run provision:up` to write non-secret config,
201
- set Worker secrets with Wrangler, commit, push, redeploy, and smoke
202
- test.
203
-
204
- Do not stop at "here is a URL". Walk the provider steps with the user
205
- until the deployed Worker, GitHub owner sign-in, and Staff MCP endpoint
206
- are verified.
207
-
208
- ## Small Adjustments
209
-
210
- Before provision, only make small deterministic edits that come directly
211
- from the landing answers or the user's explicit request:
212
-
213
- - delete an unused manifest;
214
- - add one clearly requested field to an existing Schema;
215
- - correct site defaults in `src/mantleConfig.ts`;
216
- - fix a typo in `AGENTS.md`.
217
-
218
- Run `pnpm validate` after every edit. Route larger feature work to
219
- `mantle:development` after production provision.
116
+ <https://raw.githubusercontent.com/aotter/mantle/develop/skills/provision/SKILL.md>.
220
117
 
221
118
  ## Don't
222
119
 
223
- - Don't resurrect the manual interview / prompt-composition harness.
224
- - Don't block first deploy on polishing prose or writing a site letter.
225
- - Don't ask for a Cloudflare API token in the base first-run path.
120
+ - Don't run or look for `create-mantle`; it was retired with provisioning v2.
121
+ - Don't rebuild the manual interview / prompt-composition harness.
122
+ - Don't scaffold a project from scratch locally; launch happens on landing.
123
+ - Don't block the first useful page on polishing prose or writing a site letter.
124
+ - Don't ask for a Cloudflare API token in the base flow.
226
125
  - Don't commit provider secrets.
227
- - Don't use `127.0.0.1` in OAuth callback examples; use `localhost`
228
- locally and the real Worker URL in production.
126
+ - Don't use `127.0.0.1` in OAuth callback examples; use `localhost` locally
127
+ and the real Worker URL in production.
@@ -1,174 +1,128 @@
1
1
  ---
2
2
  name: mantle provision
3
- description: Finish production deployment for an installed Mantle consumer project. Use after the install skill has produced a standalone project and the user wants the service online through their own GitHub and Cloudflare accounts.
3
+ description: Finish production for a Mantle site after Mantle landing has provisioned it. Landing already created the private GitHub repo and the first Cloudflare Worker deploy; this skill covers verifying that deploy, wiring per-site staff auth (GitHub OAuth App + Worker secrets), smoke testing, and handing off the operator setup URL.
4
4
  when_to_invoke: |
5
- Project exists, `pnpm validate` + `pnpm typecheck` pass, the scaffold is ready to push to GitHub, and the user wants a production Cloudflare Worker.
5
+ Mantle landing has created the repo and the first Cloudflare deploy, the user wants production fully usable, and staff sign-in / MCP still needs wiring.
6
6
  applies_to: mantle@v0.1.0
7
7
  ---
8
8
 
9
9
  # Provision a Mantle Project
10
10
 
11
- You're taking an installed consumer project from local files to a
12
- user-owned GitHub repo and Cloudflare Worker.
11
+ Provisioning is landing-driven. **Mantle landing is the executor for the
12
+ first deploy**: it creates the user's private GitHub repo, commits the
13
+ blank deployable site, connects Cloudflare Workers CI, and triggers the
14
+ first build. You pick up after that to make production fully usable.
13
15
 
14
- The base flow is deterministic first, provider-browser second:
16
+ The Worker boots before staff auth is configured it serves public routes
17
+ and returns a clean `503 setup_incomplete` on auth-gated routes until the
18
+ GitHub OAuth App and Worker secrets are set. Your remaining job is to
19
+ finish that wiring, verify, and hand off.
15
20
 
16
- 1. The coding agent validates the scaffold and pushes a private GitHub
17
- repo.
18
- 2. The user creates the first Cloudflare Worker deploy from that GitHub
19
- repo in Cloudflare Dashboard. Cloudflare owns automatic first-deploy
20
- resource provisioning for id-less bindings.
21
- 3. The user reports the deployed Worker URL back to the agent.
22
- 4. The user creates the per-site GitHub OAuth App.
23
- 5. The agent runs `pnpm run provision:up` to write non-secret config,
24
- set Worker secrets through Wrangler, and update local handoff files.
25
-
26
- Mantle landing is not the executor. It provides launch context and a
27
- handoff; provider authority stays with the user and their coding agent.
28
-
29
- Do deterministic work before interrupting the user. When provider UI is
30
- required, give one exact browser task at a time: link, button path,
31
- expected result, and what value the user should report back.
21
+ Keep provisioning boring: set the few secrets, commit non-secret config,
22
+ let Cloudflare CI redeploy. Do not re-create the repo, re-run the first
23
+ deploy, or resurrect a heavy `provision:up` orchestrator both retired
24
+ with v2.
32
25
 
33
26
  ## End State
34
27
 
35
- - The scaffold is committed and pushed to the user's private GitHub repo.
36
- - Cloudflare has deployed the Worker from that repo at least once.
37
- - `wrangler.toml` contains `PUBLIC_ORIGIN`, `GITHUB_CLIENT_ID`,
28
+ - Cloudflare has deployed the Worker from the repo (landing's first build,
29
+ plus your redeploy after config).
30
+ - `wrangler.toml` carries `PUBLIC_ORIGIN`, `GITHUB_CLIENT_ID`,
38
31
  `ADMIN_GITHUB_LOGIN`, and the correct Worker name.
39
- - Worker secrets are set: `GITHUB_CLIENT_SECRET`,
40
- `BETTER_AUTH_SECRET`, and optional feature/provider secrets.
32
+ - Worker secrets are set: `GITHUB_CLIENT_SECRET`, `BETTER_AUTH_SECRET`,
33
+ and any optional feature/provider secrets.
41
34
  - `AGENTS.md` `Public site:` points at the deployed Worker URL.
42
- - Staff MCP and browser admin sign-in are ready to test.
43
- - Operator setup URL is ready to hand to the owner:
35
+ - Staff MCP and browser admin sign-in work.
36
+ - Operator setup URL handed to the owner:
44
37
  `https://mantle.tools/connect?site=<url-encoded-worker-url>`.
45
38
 
46
- Provision does not seed production content. First real content is
47
- created after owner sign-in through Staff MCP / admin authoring.
39
+ Provision does not seed production content. First real content is created
40
+ after owner sign-in through Staff MCP / admin authoring.
48
41
 
49
42
  ## Principles
50
43
 
51
- 1. Use the user's accounts. The repo belongs to the user's GitHub
52
- account or org. The Worker belongs to the user's Cloudflare account.
53
- 2. Do not ask for a Cloudflare API token in the base flow. Cloudflare
54
- Dashboard plus Workers Builds handle the first deploy; Wrangler
55
- handles secrets after the user logs in.
44
+ 1. Use the user's accounts. The repo and Worker belong to the user's
45
+ GitHub and Cloudflare accounts.
46
+ 2. No Cloudflare API token in the base flow. Prefer a Cloudflare MCP
47
+ connector for provider work; use `wrangler login` as a fallback after
48
+ the user agrees.
56
49
  3. GitHub OAuth is per-site and user-owned. The callback URL is exactly
57
50
  `<worker-url>/api/auth/callback/github`.
58
- 4. Launch state is context, not provider authority. `.mantle/launch-state.json`
59
- may supply owner, admin login, repo name, locales, archetype, theme,
60
- and selected features. It does not authorize Cloudflare operations,
61
- billing-gated features, OAuth secrets, or custom domains.
62
- 5. `BETTER_AUTH_SECRET` is load-bearing. Preserve an existing secret;
63
- rotating it invalidates sessions.
51
+ 4. Launch state is context, not provider authority.
52
+ `.mantle/launch-state.json` may supply owner, admin login, repo name,
53
+ locales, and type. It does not authorize Cloudflare operations, OAuth
54
+ secrets, or custom domains.
55
+ 5. `BETTER_AUTH_SECRET` is load-bearing. Set it once and preserve it;
56
+ rotating it invalidates every session.
64
57
 
65
58
  ## Flow
66
59
 
67
60
  Run from the generated project root.
68
61
 
69
- 1. Preflight:
62
+ 1. Verify the landing deploy. Confirm Cloudflare Workers CI built and
63
+ deployed from GitHub, and capture the live `*.workers.dev` URL. The
64
+ public site should respond; auth-gated routes return `503
65
+ setup_incomplete` until step 4 — that is expected, not a failure.
66
+
67
+ 2. Confirm the local repo is clean and valid before changing config:
70
68
 
71
69
  ```bash
72
70
  pnpm install --frozen-lockfile
73
71
  pnpm validate
74
72
  pnpm typecheck
75
- if node -e "process.exit(require('./package.json').scripts?.test ? 0 : 1)"; then
76
- pnpm test
77
- else
78
- echo "No pnpm test script; skipping."
79
- fi
80
73
  git status --short
81
- gh auth status
82
- ```
83
-
84
- If GitHub CLI auth is missing or points at the wrong login, pause and
85
- ask the user to switch/login before creating the repo.
86
-
87
- 2. Create a private GitHub repo in the selected owner, add the remote,
88
- commit the scaffold, and push. Use the user's GitHub auth context.
89
-
90
- 3. Print the deterministic browser plan:
91
-
92
- ```bash
93
- pnpm run provision:plan
94
- ```
95
-
96
- 4. Hand the user directly to Cloudflare's Git import path:
97
-
98
- ```text
99
- https://dash.cloudflare.com/?to=%2F%3Aaccount%2Fworkers-and-pages
100
74
  ```
101
75
 
102
- Ask them to create a Worker from the pushed GitHub repo, keep the Worker
103
- name equal to `wrangler.toml` `name`, wait for deploy, and send back the
104
- live `*.workers.dev` URL. Ask for the Worker name only if Cloudflare
105
- forced a name different from the repo/project name.
106
-
107
- 5. After the Worker URL is known, print the worker-specific plan:
108
-
109
- ```bash
110
- pnpm run provision:plan -- --worker-url <worker-url>
111
- ```
112
-
113
- Read only the values needed for the current project. Do not dump
114
- internal notes or placeholder syntax onto a non-coder.
115
-
116
- 6. Ask the user to create the per-site GitHub OAuth App after the Worker
76
+ 3. Ask the user to create the per-site GitHub OAuth App once the Worker
117
77
  URL is known:
118
78
 
119
79
  - Homepage URL: `<worker-url>`
120
80
  - Authorization callback URL: `<worker-url>/api/auth/callback/github`
121
81
  - Device Flow: unchecked
122
82
 
123
- Ask for the Client ID in chat. Keep the Client Secret out of chat and
124
- pass it through the hidden shell prompt below.
83
+ Ask for the Client ID in chat. Keep the Client Secret out of chat and pass
84
+ it through the hidden shell prompt below.
125
85
 
126
- 7. Authorize Wrangler and apply provision:
86
+ 4. Write non-secret production config into `wrangler.toml`
87
+ (`PUBLIC_ORIGIN=<worker-url>`, `GITHUB_CLIENT_ID`, `ADMIN_GITHUB_LOGIN`,
88
+ and the correct Worker `name`), then set the Worker secrets. Prefer a
89
+ Cloudflare MCP connector; otherwise use Wrangler after the user agrees
90
+ to `wrangler login`:
127
91
 
128
92
  ```bash
129
93
  pnpm exec wrangler login
130
- read -rsp "GitHub OAuth client secret: " GITHUB_CLIENT_SECRET && export GITHUB_CLIENT_SECRET && printf "\n"
131
- pnpm run provision:up -- --worker-url <worker-url> --github-username <gh-login> --client-id <client-id>
94
+ read -rsp "GitHub OAuth client secret: " GITHUB_CLIENT_SECRET && printf "\n"
95
+ printf '%s' "$GITHUB_CLIENT_SECRET" | pnpm exec wrangler secret put GITHUB_CLIENT_SECRET
96
+ openssl rand -hex 32 | pnpm exec wrangler secret put BETTER_AUTH_SECRET
132
97
  unset GITHUB_CLIENT_SECRET
133
98
  ```
134
99
 
135
- 8. Commit and push generated non-secret outputs:
100
+ Set `BETTER_AUTH_SECRET` only on the first run; reuse the existing value on
101
+ later runs.
102
+
103
+ 5. Commit and push the non-secret config so Cloudflare CI redeploys:
136
104
 
137
105
  ```bash
138
- git status --short -- wrangler.toml src/mantleConfig.ts AGENTS.md
139
- git add wrangler.toml src/mantleConfig.ts AGENTS.md
106
+ git add wrangler.toml AGENTS.md
140
107
  git commit -m "mantle: wire production provision"
141
108
  git push
142
109
  ```
143
110
 
144
- Wait for Cloudflare Workers Builds to redeploy from the pushed commit. If
145
- the dashboard build is unavailable, run `pnpm deploy` from this repo as a
146
- fallback and explain that fallback to the user.
111
+ Wait for Workers Builds to redeploy from the pushed commit. If the
112
+ dashboard build is unavailable, run `pnpm deploy` as a fallback and explain
113
+ that to the user.
147
114
 
148
- 9. Smoke test:
115
+ 6. Smoke test:
149
116
 
150
117
  - public home route;
151
118
  - `/admin/sign-in`;
152
119
  - GitHub admin sign-in;
153
120
  - `/mcp/staff` with an agent client when available;
154
- - a starter-specific core workflow.
121
+ - a type-specific core workflow.
155
122
 
156
123
  A fresh site may have no public home content yet. A 404 on the locale
157
124
  homepage is acceptable only after the Worker boots, `/admin/sign-in`
158
- loads, and auth/MCP boundaries behave correctly.
159
-
160
- ## Feature Overlays
161
-
162
- If `.mantle/features.json` lists features, run the repo-local feature
163
- overlay skill first:
164
-
165
- ```text
166
- .agent/skills/mantle-feature-overlays/SKILL.md
167
- ```
168
-
169
- Feature scripts are starter lifecycle scripts, not Mantle CLI commands.
170
- Run them only when the feature is present and the user accepts any extra
171
- provider/billing requirement.
125
+ loads, and auth / MCP boundaries behave correctly.
172
126
 
173
127
  ## Handoff
174
128
 
@@ -180,28 +134,31 @@ language:
180
134
  - Staff MCP URL.
181
135
  - Operator setup URL (`https://mantle.tools/connect?site=...`).
182
136
  - What changed locally and what was committed.
183
- - Any intentionally deferred feature setup.
137
+ - Any intentionally deferred feature / provider setup.
184
138
 
185
139
  Point future agents at `AGENTS.md`, `.mantle/launch-state.json`, and the
186
- repo-local `.agent/skills/` directory.
140
+ repo-local `.agent/skills/` directory (`mantle:develop`, `mantle:overlay`,
141
+ `mantle:theme`, `mantle:update`).
187
142
 
188
143
  ## Diagnostics
189
144
 
190
145
  | Symptom | Likely cause | Fix |
191
146
  |---|---|---|
192
- | Cloudflare first deploy cannot infer a binding | Starter uses a resource Dashboard cannot auto-create | Follow `provision:plan` notes, then redeploy. |
193
- | `provision:up` cannot infer Worker name | Custom domain or non-workers.dev URL | Add `--worker-name <cloudflare-worker-name>`. |
194
- | `wrangler secret put` targets wrong account | Wrangler logged into another Cloudflare account | Re-run `pnpm exec wrangler login` and confirm account. |
147
+ | Auth-gated routes return `503 setup_incomplete` | GitHub OAuth + secrets not wired yet | Expected before step 3-4; finish the OAuth App + secrets, then redeploy. |
148
+ | `wrangler secret put` targets the wrong account | Wrangler logged into another Cloudflare account | Re-run `pnpm exec wrangler login` and confirm the account. |
195
149
  | GitHub OAuth callback mismatch | OAuth App callback URL is wrong | Set it exactly to `<worker-url>/api/auth/callback/github`. |
196
- | Owner signs in but admin/MCP returns 403 | `ADMIN_GITHUB_LOGIN` does not match signed-in GitHub login | Re-run `provision:up` with the correct `--github-username`, or update the secret. |
197
- | Worker boots but sessions fail after rerun | `BETTER_AUTH_SECRET` changed or was deleted | Restore the old secret if available; otherwise users must sign in again. |
150
+ | Owner signs in but admin / MCP returns 403 | `ADMIN_GITHUB_LOGIN` does not match the signed-in GitHub login | Fix the `ADMIN_GITHUB_LOGIN` value and redeploy. |
151
+ | Worker boots but sessions fail after a rerun | `BETTER_AUTH_SECRET` changed or was deleted | Restore the old secret if available; otherwise users must sign in again. |
198
152
 
199
153
  ## Don't
200
154
 
201
155
  - Don't ask for a Cloudflare API token in the base first-run path.
202
- - Don't create Cloudflare resources from Mantle landing.
156
+ - Don't re-create the repo or re-run the first deploy from the agent;
157
+ landing owns first provisioning.
158
+ - Don't resurrect `provision:up` / `provision:plan` as a second
159
+ provisioner; those scripts were retired with v2.
203
160
  - Don't commit provider secrets.
204
- - Don't use `127.0.0.1` in OAuth callback examples; use `localhost`
205
- locally and the real Worker URL in production.
206
- - Don't use `/admin/auth/github/callback`; the Better Auth callback path
207
- is `/api/auth/callback/github`.
161
+ - Don't use `127.0.0.1` in OAuth callback examples; use `localhost` locally
162
+ and the real Worker URL in production.
163
+ - Don't use `/admin/auth/github/callback`; the Better Auth callback path is
164
+ `/api/auth/callback/github`.