@aotter/mantle 0.0.11-alpha.25 → 0.0.11-alpha.27

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
@@ -31,7 +31,11 @@ import { mountServerEndpoints } from "@aotter/mantle/cloudflare";
31
31
 
32
32
  ## Getting started
33
33
 
34
- Recommended path: open the Mantle landing page, pick an archetype and theme, then paste the generated prompt into Claude Code / Cursor / Codex. The install Skill asks the right follow-up questions and then runs the scaffolder for you.
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
39
 
36
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.
37
41
 
@@ -242,17 +242,20 @@ The pivot point — when to extract — is when the second adapter (`mantle-netl
242
242
 
243
243
  None. Pre-v0.1.0 has no external consumers. Existing demo deployments tear down + re-bootstrap from the migrated `0.0.x-alpha` release.
244
244
 
245
- ### Skills + prompts
245
+ ### Skills + launch handoff
246
246
 
247
- `docs/prompts/publication.{en,zh-TW}.md` reference `<worker_url>/staff/mcp` for staff-targeted MCP handoff. `skills/install/SKILL.md` and `skills/provision/SKILL.md` document the dual handoff. Provision Skill's final report distinguishes:
247
+ The Mantle landing launch session and generated repo-local
248
+ `mantle:provision` skill document the dual MCP handoff. Provision's final
249
+ report distinguishes:
248
250
 
249
251
  ```
250
252
  Public site: https://<worker>.workers.dev/
251
- Staff MCP URL: https://<worker>.workers.dev/staff/mcp (give to your owner agent)
253
+ Staff MCP URL: https://<worker>.workers.dev/mcp/staff (give to your owner agent)
252
254
  User MCP URL: https://<worker>.workers.dev/mcp (give to visitors / their agents)
253
255
  ```
254
256
 
255
- The publication starter repo's production smoke recipe uses `/staff/mcp` for the MCP operator smoke step.
257
+ The publication starter repo's production smoke recipe uses `/mcp/staff`
258
+ for the MCP operator smoke step.
256
259
 
257
260
  ### Future-proof for v0.2
258
261
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aotter/mantle",
3
- "version": "0.0.11-alpha.25",
3
+ "version": "0.0.11-alpha.27",
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.25",
51
- "@aotter/mantle-runtime": "0.0.11-alpha.25",
52
- "@aotter/mantle-spec": "0.0.11-alpha.25",
53
- "@aotter/mantle-cloudflare": "0.0.11-alpha.25"
50
+ "@aotter/mantle-admin-ui": "0.0.11-alpha.27",
51
+ "@aotter/mantle-cloudflare": "0.0.11-alpha.27",
52
+ "@aotter/mantle-runtime": "0.0.11-alpha.27",
53
+ "@aotter/mantle-spec": "0.0.11-alpha.27"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@cloudflare/workers-oauth-provider": "^0.7.0",
@@ -1,13 +1,16 @@
1
1
  ---
2
2
  name: mantle install
3
- description: Install a mantle consumer project. Preferred path consumes a landing-created launch session and scaffolds immediately via create-mantle; fallback path is interview-driven, elicits the user's purpose/audience/timing/identity, then scaffolds deterministically and continues to provision. Use when the user pasted a launch command/session URL, a composed-skill URL generated by the landing page, or when starting from an empty repo.
3
+ description: Install a mantle consumer project. Preferred path consumes a landing-created launch session and scaffolds immediately via create-mantle. Manual fallback collects the exact create-mantle flags, scaffolds deterministically, then continues to provision. Use when the user pasted a launch command/session URL or when starting from an empty repo.
4
4
  when_to_invoke: |
5
- Empty repo + landing-page launch command/session URL; empty repo + landing-page composed-skill prompt; or the user describes a site they want to build. A composed URL may inline the per-archetype hint with this brief.
5
+ Empty repo + landing-page launch command/session URL, or empty repo + user wants to create a Mantle site without landing.
6
6
  ---
7
7
 
8
8
  # mantle install
9
9
 
10
- You're installing a mantle site for the user. If the user arrived from the landing launch flow, a short-lived launch session already carries the launch-critical values. If the user arrived from the older composed-prompt flow, the composed URL inlined this brief plus the per-archetype hint — archetype-specific register cues are in the same document.
10
+ You're installing a mantle site for the user. If the user arrived from
11
+ the landing launch flow, a short-lived launch session already carries
12
+ the launch-critical values. Treat that session as the source of truth
13
+ and scaffold first.
11
14
 
12
15
  ## Ground truth
13
16
 
@@ -94,7 +97,7 @@ After it returns:
94
97
 
95
98
  Do not ask content/voice questions before scaffold. The natural point for user conversation is after the site exists locally and, preferably, after provision has produced a working URL. If the user explicitly wants to revise content before provision, keep it to the same small adjustment window described later in this Skill.
96
99
 
97
- ## Preflight — before the fallback interview
100
+ ## Preflight — before manual fallback
98
101
 
99
102
  Verify the environment can run the flow. Don't waste the user's time interviewing for a site we can't build:
100
103
 
@@ -111,13 +114,17 @@ If any is missing or below the minimum, surface install hints once and stop unti
111
114
 
112
115
  Also confirm the current working directory is an appropriate parent directory for the new project, and that no child directory already exists with the authorized `<<PROJECT_NAME>>`. `create-mantle` writes into `./<<PROJECT_NAME>>`; collisions with pre-existing files are surprising and rarely what the user wanted.
113
116
 
114
- Don't proceed to the fallback interview until preflight passes.
117
+ Do not proceed to manual fallback until preflight passes.
115
118
 
116
- ## The interview
119
+ ## Manual fallback
117
120
 
118
- Use this section only when there is no valid launch session. With a launch session, the landing flow already supplied the scaffold values and the agent should run launch first.
121
+ Use this only when there is no valid launch session. The manual path is
122
+ for development, recovery, or a user who did not start from landing. It
123
+ is not the primary UX.
119
124
 
120
- There's no fixed question list. The archetype hint above (composed in by landing) carries **Interview probes to emphasize** — 4 archetype-tailored questions written for this specific archetype's concerns. That's your spine. Free-form follow-ups based on what surfaces. You decide order. You decide when you have enough.
125
+ Ask only for the values that the `create-mantle` command truly needs.
126
+ Keep it one question at a time and confirm the exact values before
127
+ running the command.
121
128
 
122
129
  ### Goal — what you must land before dispatch
123
130
 
@@ -125,22 +132,25 @@ Listed in discovery order — purpose comes first, brand near the end. **Do not
125
132
 
126
133
  | Value | For |
127
134
  |---|---|
128
- | **purpose / audience / emotional weight** | site summary + future content direction; surfaces through the archetype probes |
135
+ | **purpose / audience** | one-line description and locale choice |
129
136
  | **audience scope + locales** | `--locales` (count + first is canonical) |
130
137
  | **description** | `--description` — one-line site identity, agent-drafted in user's language |
131
138
  | **summary** | `--summary` — one-line install-moment marker, agent-drafted in user's language |
132
139
  | **brand** | `--brand` — proposed by you after purpose + audience texture is in; user picks or supplies their own |
133
- | **github identity** | `--github-owner` pure config; ask near the end |
140
+ | **github identity** | `--github-owner` and optional `--admin-github-login` |
134
141
 
135
- archetype is already known (the composed URL pinned it). Every value above must be set with the user's **explicit confirmation** before you dispatch — never guess from email / folder name / archetype name.
142
+ Every value above must be set with the user's explicit confirmation
143
+ before you dispatch. Do not guess from email, folder name, or the
144
+ language of the conversation.
136
145
 
137
146
  ### Multi-round purpose discovery — start here, not with brand
138
147
 
139
- Open with **what's this site for** — not the brand name. Don't ask cold ("describe your site in your own words"); that puts the user on the spot. Use the archetype hint's **Interview probes** (composed in below) as your discovery spine. Ask the first probe naturally, in the user's language, as an open question — don't fabricate multiple-choice options if the probe is written as open-ended. The picker step already happened at the landing page (`?type=` and `?theme=` in the URL); the probes here are about texture, not branching.
148
+ Open with **what's this site for** — not the brand name. Don't ask cold
149
+ for a full brief. Ask one simple question, summarize back, then move to
150
+ the next required value.
140
151
 
141
- User answers react ask the next probe. **One probe per turn, not all four at once.** This is the multi-round shape. After 2–4 turns you have enough texture to propose brand candidates (Brand stance below) and synthesize description + summary drafts.
142
-
143
- If a probe is phrased with options in the archetype hint, you may offer them as a picker — but most presence / publication / intake probes are intentionally open. Translate every probe (and your framing) into the user's language before presenting.
152
+ User answers -> react -> ask the next missing value. One question per
153
+ turn. Stop as soon as the command values are known.
144
154
 
145
155
  ### Stances (the few non-archetype rules)
146
156
 
@@ -196,34 +206,55 @@ Invoking the `create-mantle` release tarball is **not low-risk work**. The comma
196
206
 
197
207
  Wrong values ship into the user's first-load impression and cannot be cleanly walked back without wiping the scaffold and re-scaffolding from empty.
198
208
 
199
- **Auto Mode's contract has four clauses. Clauses 1–3 say "execute immediately / minimize interruptions / prefer action". Clause 4 is the carve-out: do not take overly destructive actions without authorization.** This Skill classifies the scaffolder invocation under clause 4. Each marker (`<<...>>`) in the composed `## Run this` block (see end of this document) must be a value the user has personally seen and nodded on. Auto-derivation — from the user's email, the current working directory's name, the archetype query, the theme query, or "the locale of the message the user wrote to me" — is **not** authorization. That kind of inference is what Auto Mode's clauses 1–3 want for low-risk work. This Skill specifically does not accept it for these marker values.
209
+ **Auto Mode's contract has four clauses. Clauses 1–3 say "execute immediately / minimize interruptions / prefer action". Clause 4 is the carve-out: do not take overly destructive actions without authorization.** This Skill classifies the scaffolder invocation under clause 4. Each create-time value must be either carried by a valid landing session or explicitly confirmed by the user. Auto-derivation — from the user's email, the current working directory's name, the archetype query, the theme query, or "the locale of the message the user wrote to me" — is **not** authorization. That kind of inference is what Auto Mode's clauses 1–3 want for low-risk work. This Skill specifically does not accept it for scaffolding values.
200
210
 
201
211
  If you have not had a turn where the user looked at the exact value and replied affirmatively (or supplied a replacement), the value is unauthorized.
202
212
 
203
- Launch-session exception: when the user hands you a landing-created `create-mantle launch --session ...` command, the landing session is the explicit authorization for those scaffold values. Your job is to validate/run it, not to repeat the full interview before scaffold. If the session is invalid or expired, stop and ask the user to regenerate it from the landing page; do not infer replacement values.
213
+ Launch-session exception: when the user hands you a landing-created
214
+ `create-mantle launch --session ...` command, the landing session is the
215
+ explicit authorization for those scaffold values. Your job is to
216
+ validate/run it, not to repeat manual fallback before scaffold. If the
217
+ session is invalid or expired, stop and ask the user to regenerate it
218
+ from the landing page; do not infer replacement values.
204
219
 
205
220
  ### Prerequisites — each parameter must be user-authorized before invocation
206
221
 
207
222
  Same discovery order as the Goal table above — purpose first, brand later. The order matters because it reflects the interview shape, not arbitrary alphabetization.
208
223
 
209
- | Value | Marker | Authorized when |
210
- |---|---|---|
211
- | **purpose / audience / emotional weight** | (not a CLI flag) | enough texture to summarize the site intent — surfaced through the archetype probes (open-question discovery), not inferred |
212
- | **audience scope** | (drives `<<LOCALES>>`) | user explicitly stated: domestic (which country / region) OR international (which language[s]) |
213
- | **locales** | `<<LOCALES>>` | derived from audience scope; user nodded on the resulting BCP 47 list |
214
- | **description** | `<<DESCRIPTION>>` | agent-drafted in user's language; user nodded on the exact one-liner |
215
- | **summary** | `<<SUMMARY>>` | agent-drafted in user's language; user nodded on the exact one-liner |
216
- | **brand** | `<<BRAND>>` | you proposed 2–3 candidates (Brand stance, after purpose + audience texture is in); user picked one or supplied their own |
217
- | **project-name** | `<<PROJECT_NAME>>` | lowercase-hyphenated slug of brand; show the slug to user in the rehearsal (step 1) and confirm; user can override if they prefer a different repo / dir name |
218
- | **github owner** | `<<GITHUB_OWNER>>` | user explicitly stated their GitHub login (not derived from email) |
224
+ | Value | Authorized when |
225
+ |---|---|
226
+ | **purpose / audience** | enough texture to summarize the site intent, not inferred |
227
+ | **audience scope** | user explicitly stated domestic/international audience and languages |
228
+ | **locales** | derived from audience scope; user nodded on the resulting BCP 47 list |
229
+ | **description** | agent-drafted in user's language; user nodded on the exact one-liner |
230
+ | **summary** | agent-drafted in user's language; user nodded on the exact one-liner |
231
+ | **brand** | user picked one, supplied one, or accepted your proposal |
232
+ | **project-name** | lowercase-hyphenated slug shown to user and confirmed |
233
+ | **github owner** | user explicitly stated their GitHub login/org, not derived from email |
219
234
 
220
235
  If any value is unauthorized — including auto-derivation that "looks reasonable" — the work is still in the interview. Return there. Step 1 below IS the rehearsal back to the user in their language; it is not the moment you collect authorization for unfilled values.
221
236
 
222
237
  1. **Confirm the synthesized draft.** User accepts or corrects.
223
238
 
224
- 2. **Run the composed `## Run this` block.** Scroll to the `## Run this` section at the bottom of this composed document — the landing composer baked the archetype, theme, and any preselected feature literals into the command. Copy it verbatim, fill the 6 `<<...>>` markers from your authorized interview values (see Prerequisites table above), and run it.
239
+ 2. **Run `create-mantle`.** Use the release tarball URL supplied by the
240
+ landing page, release notes, or Mantle starter docs. Fill flags only
241
+ from confirmed values:
225
242
 
226
- Do not modify the literal flags or the archetype positional. Do not invent additional `--feature` flags from vibes; features must come from the composed command or an explicit user request. If a marker has no authorized value, you're still in the interview — return there.
243
+ ```bash
244
+ npx <create-mantle-tarball> <archetype> \
245
+ --project-name <project-name> \
246
+ --brand "<brand>" \
247
+ --description "<description>" \
248
+ --locales "<locale[,locale]>" \
249
+ --github-owner <github-owner> \
250
+ --admin-github-login <admin-login> \
251
+ --summary "<summary>" \
252
+ [--theme <theme>] \
253
+ [--feature <feature>]
254
+ ```
255
+
256
+ Do not invent `--theme` or `--feature` flags. They must come from
257
+ landing, a starter doc, or an explicit user request.
227
258
 
228
259
  The CLI fetches `sources.json` at runtime from the requested starter ref (`--ref` / `--starter-ref`; release commands should pin a tag or explicit ref), downloads the starters tarball, merges `_common/` + `<archetype>/` + selected feature overlays + (optional) `themes/<theme>/`, fills `{{PLACEHOLDER}}` macros, renames `.template` files, runs `git init` and `pnpm install`. RUN_NOTES JSON arrives on stdout, including `features` when overlays were selected.
229
260
 
@@ -256,14 +287,13 @@ If any value is unauthorized — including auto-derivation that "looks reasonabl
256
287
 
257
288
  When the public home route is empty/404, tell the user plainly: "the worker is running; the public homepage has no content yet." Then ask whether they want a **local preview seed** so they can see the homepage and, for post-shaped archetypes, a couple of sample posts in the browser. Do not run generic test fixtures or seed content without explicit consent. If they say yes, keep the seed preview-only and local: use user-approved copy from the interview or step 6 drafting, make it clear it is not production content, and do not commit local DB/KV artifacts or `.dev.vars`. If they say no, continue with the install flow; production content can be created later through `/admin` or MCP.
258
289
 
259
- 6. **Write the deterministic `mantle/site.md` notes in your normal register.**
260
-
261
- Keep this short and practical. The goal is to persist what the user authorized so the next agent is not guessing, not to finish brand prose before deploy.
290
+ 6. **Keep `mantle/site.md` deterministic.**
262
291
 
263
- - `## site` one paragraph reflecting why this site exists.
264
- - `## voice` a few honest register markers only when the user gave you real language or reactions. If voice did not surface, write short.
265
- - `## history` one paragraph: what was decided, what the user said in their words, and what's still open.
266
- - `## editor first_prompt:` body — mechanical fill. Copy the archetype hint's `Editor first-prompt template` block, substitute `<<BRAND>>` with the actual brand, paste as plain text under the YAML `first_prompt: |` key (indented properly).
292
+ The scaffold already records the launch description and open
293
+ provision items. Do not block first deploy on polishing voice, welcome
294
+ copy, or editor prompts. If the user gave concrete notes, add a short
295
+ `## history` paragraph and validate. Otherwise leave content work for
296
+ the post-deploy coding/content agent.
267
297
 
268
298
  7. **Run deploy validation.**
269
299
 
@@ -275,7 +305,12 @@ If any value is unauthorized — including auto-derivation that "looks reasonabl
275
305
 
276
306
  8. **Commit.** If step 4 produced an adjustment, that's its own commit. Then the main commit: `mantle: deterministic scaffold`.
277
307
 
278
- 9. **Continue to provision — don't push a URL onto the user.** Provision is the next phase in the same conversation. If you came from the fallback composed-prompt path, replace `install` with `provision` in the composed URL you read at the start, keep the same `?type=`, `?theme=`, and future `?feature=` query values, fetch that URL, follow it. If you came from launch-session path, read `.mantle/launch-state.json` for the GitHub owner/admin metadata, then fetch `https://raw.githubusercontent.com/aotter/mantle/develop/skills/provision/SKILL.md` unless the landing origin supplied a provision URL.
308
+ 9. **Continue to provision — don't push a URL onto the user.** Provision
309
+ is the next phase in the same conversation. Read
310
+ `.mantle/launch-state.json` for GitHub owner/admin metadata when it
311
+ exists, then use the repo-local `mantle:provision` skill generated
312
+ into the scaffold. If it is missing, fetch
313
+ `https://raw.githubusercontent.com/aotter/mantle/develop/skills/provision/SKILL.md`.
279
314
 
280
315
  The current provision shape is deterministic first: create/push the private GitHub repo, guide the user through Cloudflare's GitHub-backed first deploy, then use Wrangler to take over follow-up bindings/secrets/migrations. If GitHub CLI auth is invalid, the user's next involvement is re-auth first; after they reply that it is fixed, re-run `gh auth status` and then continue provision. Don't promise production-readiness until provision completes and a second agent connects through MCP.
281
316
 
@@ -6,27 +6,27 @@ when_to_invoke: |
6
6
  applies_to: mantle@v0.1.0
7
7
  ---
8
8
 
9
- # Provision a mantle project
9
+ # Provision a Mantle Project
10
10
 
11
11
  You're taking an installed consumer project from local files to a
12
12
  user-owned GitHub repo and Cloudflare Worker.
13
13
 
14
- The base flow is dashboard-first:
14
+ The base flow is deterministic first, provider-browser second:
15
15
 
16
- 1. The user's coding agent scaffolds and pushes a private GitHub repo.
17
- 2. The user opens Cloudflare Dashboard and creates a Worker from that
18
- GitHub repo. Cloudflare performs the first deploy and owns automatic
19
- first-deploy resource provisioning for id-less bindings.
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.
20
21
  3. The user reports the deployed Worker URL back to the agent.
21
22
  4. The user creates the per-site GitHub OAuth App.
22
23
  5. The agent runs `pnpm run provision:up` to write non-secret config,
23
24
  set Worker secrets through Wrangler, and update local handoff files.
24
25
 
25
26
  Mantle landing is not the executor. It provides launch context and a
26
- complete handoff; provider authority stays with the user and their
27
- coding agent.
27
+ handoff; provider authority stays with the user and their coding agent.
28
28
 
29
- ## End state
29
+ ## End State
30
30
 
31
31
  - The scaffold is committed and pushed to the user's private GitHub repo.
32
32
  - Cloudflare has deployed the Worker from that repo at least once.
@@ -45,210 +45,98 @@ created after owner sign-in through Staff MCP / admin authoring.
45
45
 
46
46
  ## Principles
47
47
 
48
- 1. **Use the user's accounts.** The repo belongs to the user's GitHub
48
+ 1. Use the user's accounts. The repo belongs to the user's GitHub
49
49
  account or org. The Worker belongs to the user's Cloudflare account.
50
- Do not make Mantle a central runtime dependency.
51
-
52
- 2. **No Cloudflare API token in the base flow.** The base provision path
53
- does not ask for `CLOUDFLARE_API_TOKEN` and does not call Cloudflare
54
- resource APIs directly. Cloudflare Dashboard + Workers Builds handle
55
- the first deploy; Wrangler handles secrets after the user logs in.
56
-
57
- 3. **GitHub OAuth is per-site and user-owned.** The user creates a
58
- GitHub OAuth App for this generated site. The exact callback URL is:
59
- `<worker-url>/api/auth/callback/github`
60
-
61
- 4. **Same GitHub login for admin.** `gh auth status`, the OAuth App
62
- owner, and `ADMIN_GITHUB_LOGIN` should line up unless the user
63
- intentionally chose an org repo with a separate admin login.
64
-
65
- 5. **Launch state is context, not provider authority.** If install came
66
- from Mantle landing, read `.mantle/launch-state.json`. It can supply
67
- owner, admin login, repo name, locales, archetype, theme, and
68
- selected features. It does not authorize Cloudflare operations,
50
+ 2. Do not ask for a Cloudflare API token in the base flow. Cloudflare
51
+ Dashboard plus Workers Builds handle the first deploy; Wrangler
52
+ handles secrets after the user logs in.
53
+ 3. GitHub OAuth is per-site and user-owned. The callback URL is exactly
54
+ `<worker-url>/api/auth/callback/github`.
55
+ 4. Launch state is context, not provider authority. `.mantle/launch-state.json`
56
+ may supply owner, admin login, repo name, locales, archetype, theme,
57
+ and selected features. It does not authorize Cloudflare operations,
69
58
  billing-gated features, OAuth secrets, or custom domains.
59
+ 5. `BETTER_AUTH_SECRET` is load-bearing. Preserve an existing secret;
60
+ rotating it invalidates sessions.
70
61
 
71
- 6. **Feature overlays can add optional provider steps.** Read
72
- `.mantle/features.json` before provision. For example, `media-r2`
73
- may ask the operator to make an explicit R2/billing choice after the
74
- base site is online.
75
-
76
- 7. **`BETTER_AUTH_SECRET` is load-bearing.** The shared provision runner
77
- leaves an existing `BETTER_AUTH_SECRET` in place and creates one only
78
- when missing. Rotating it invalidates sessions and may make stored
79
- JWK rows unreadable. Do not rotate casually.
62
+ ## Flow
80
63
 
81
- ## CLI surface
64
+ Run from the generated project root.
82
65
 
83
- Run from the generated project root:
66
+ 1. Preflight:
84
67
 
85
68
  ```bash
69
+ pnpm install --frozen-lockfile
86
70
  pnpm validate
87
71
  pnpm typecheck
88
- pnpm run provision:plan
89
- pnpm exec wrangler login
90
- pnpm run provision:up -- --worker-url <worker-url> --github-username <gh-login> --client-id <client-id>
72
+ if node -e "process.exit(require('./package.json').scripts?.test ? 0 : 1)"; then
73
+ pnpm test
74
+ else
75
+ echo "No pnpm test script; skipping."
76
+ fi
77
+ git status --short
78
+ gh auth status
91
79
  ```
92
80
 
93
- `provision:plan` is read-only. It prints the Cloudflare dashboard
94
- first-deploy steps, the GitHub OAuth App fields, the Wrangler login
95
- requirement, and feature-specific notes.
96
-
97
- `provision:up` requires:
81
+ If GitHub CLI auth is missing or points at the wrong login, pause and
82
+ ask the user to switch/login before creating the repo.
98
83
 
99
- - `--worker-url <worker-url>`: the deployed Cloudflare Worker URL.
100
- - `--github-username <gh-login>`: the bootstrap admin GitHub login.
101
- - `--client-id <client-id>`: GitHub OAuth App Client ID.
102
- - `GITHUB_CLIENT_SECRET` in the environment or stdin.
84
+ 2. Create a private GitHub repo in the selected owner, add the remote,
85
+ commit the scaffold, and push. Use the user's GitHub auth context.
103
86
 
104
- It writes non-secret config, sets Worker secrets with Wrangler, updates
105
- `mantle/site.md` and `AGENTS.md`, then prints public/admin/MCP and
106
- operator setup URLs.
87
+ 3. Hand the user directly to Cloudflare's Git import path:
107
88
 
108
- Do not pass `GITHUB_CLIENT_SECRET` as a visible command argument.
109
-
110
- ```bash
111
- read -rsp "GitHub OAuth client secret: " GITHUB_CLIENT_SECRET && export GITHUB_CLIENT_SECRET && printf "\n"
112
- pnpm run provision:up -- --worker-url <worker-url> --github-username <gh-login> --client-id <client-id>
89
+ ```text
90
+ https://dash.cloudflare.com/?to=%2F%3Aaccount%2Fworkers-and-pages
113
91
  ```
114
92
 
115
- ## Presenting browser steps (non-coder handoff)
116
-
117
- Flow steps 3 and 5 hand the user into a browser. That user is usually a
118
- non-coder who is trusting the agent — present those steps the way you'd
119
- guide someone over the phone, not as a terse engineer checklist. The
120
- plan that `provision:plan` prints is *your* reference; re-present it, do
121
- not paste it through.
122
-
123
- Rules:
124
-
125
- - **One task at a time.** Send the Cloudflare deploy, wait for the URL,
126
- *then* send the GitHub OAuth App. Never dump both browser tasks in one
127
- message.
128
- - **Number only what they see.** Label the block `STEP 1 of 2` /
129
- `STEP 2 of 2`. Do not leak your internal plan numbering — a user
130
- seeing "Step 2" and "Step 4" with gaps assumes they missed something.
131
- - **Lead with one plain "why".** A single sentence on what the step
132
- accomplishes ("this is what puts your site on the internet").
133
- - **Full-sentence click paths, not arrows.** "Click *Create
134
- application*, then open the *Import a repository* tab" — not
135
- `Create application → Import a repository`. Quote the exact labels the
136
- user sees on screen.
137
- - **Say what they'll see and what to copy.** Name the landmark and the
138
- success signal ("a link ending in `.workers.dev` — copy that"), and a
139
- rough time ("about a minute").
140
- - **Ask for values in plain language.** "Paste me the live link, and
141
- the Client ID." Never ask for `KEY=value` shell syntax, and never make
142
- them type literal `<...>` placeholders.
143
- - **Protect the secret in words, not jargon.** Tell them to copy the
144
- Client Secret and keep it on their clipboard, and that you'll ask for
145
- it privately so it never lands in the chat. Don't say "stdin" or "env".
146
- - **Give an escape hatch.** "If a screen doesn't match what I describe,
147
- paste a screenshot and I'll point you to the right button."
148
-
149
- Keep agent-internal correctness rules out of the user-facing text. The
150
- `localhost` / `127.0.0.1` callback rule (see Don't) governs what *you*
151
- write; a dashboard user is handed the real Worker URL and never needs to
152
- hear that warning.
153
-
154
- ## Flow
155
-
156
- 1. **Preflight.** Read `.mantle/launch-state.json` if present, then
157
- confirm the expected repo owner/admin login. Run:
158
-
159
- ```bash
160
- pnpm install --frozen-lockfile
161
- pnpm validate
162
- pnpm typecheck
163
- git status --short
164
- gh auth status
165
- ```
93
+ Ask them to create a Worker from the pushed GitHub repo, keep the Worker
94
+ name equal to `wrangler.toml` `name`, wait for deploy, and send back the
95
+ live `*.workers.dev` URL.
166
96
 
167
- If GitHub CLI auth is missing or points at the wrong login, pause
168
- and ask the user to switch/login before creating the repo.
97
+ 4. Print the deterministic plan:
169
98
 
170
- 2. **Push the repo.** Create a private GitHub repo in the selected
171
- owner, add the remote, commit the scaffold, and push. Use the user's
172
- GitHub auth context.
173
-
174
- 3. **Ask the user to run Cloudflare first deploy.** They should open
175
- Cloudflare Dashboard, create a Worker, choose GitHub as source, pick
176
- the repo, keep the Worker name aligned with the repo/project name,
177
- and run the first deploy. They report the deployed Worker URL back.
178
- Present this as `STEP 1 of 2` per **Presenting browser steps** above,
179
- and wait for the Worker URL before moving on.
180
-
181
- 4. **Print the plan.**
182
-
183
- ```bash
184
- pnpm run provision:plan
185
- ```
186
-
187
- Read any feature-specific notes out loud. If the project uses queues
188
- or another Cloudflare resource that Dashboard cannot infer, follow
189
- the plan's explicit instructions.
190
-
191
- 5. **Create the GitHub OAuth App.** Ask the user to create it under the
192
- account/org that should own site auth:
193
-
194
- - Application name: project/site name
195
- - Homepage URL: `<worker-url>`
196
- - Authorization callback URL:
197
- `<worker-url>/api/auth/callback/github`
198
- - Device Flow: unchecked
199
-
200
- Present this as `STEP 2 of 2` per **Presenting browser steps** above.
201
- Ask for the Client ID in chat; have them keep the Client Secret on
202
- the clipboard for the hidden prompt in step 6 — do not ask them to
203
- paste the secret in chat.
204
-
205
- 6. **Authorize Wrangler and run provision.**
99
+ ```bash
100
+ pnpm run provision:plan
101
+ ```
206
102
 
207
- ```bash
208
- pnpm exec wrangler login
209
- read -rsp "GitHub OAuth client secret: " GITHUB_CLIENT_SECRET && export GITHUB_CLIENT_SECRET && printf "\n"
210
- pnpm run provision:up -- --worker-url <worker-url> --github-username <gh-login> --client-id <client-id>
211
- unset GITHUB_CLIENT_SECRET
212
- ```
103
+ Read only the values needed for the current project. Do not dump
104
+ internal notes or placeholder syntax onto a non-coder.
213
105
 
214
- 7. **Commit provision outputs.** Confirm and commit local changes:
106
+ 5. Ask the user to create the per-site GitHub OAuth App after the Worker
107
+ URL is known:
215
108
 
216
- ```bash
217
- git status --short -- wrangler.toml src/mantleConfig.ts mantle/site.md AGENTS.md
218
- ```
109
+ - Homepage URL: `<worker-url>`
110
+ - Authorization callback URL: `<worker-url>/api/auth/callback/github`
111
+ - Device Flow: unchecked
219
112
 
220
- 8. **Smoke test.**
113
+ Ask for the Client ID in chat. Keep the Client Secret out of chat and
114
+ pass it through the hidden shell prompt below.
221
115
 
222
- ```bash
223
- BASE='<worker-url>'
224
- curl -s -o /dev/null -w '%{http_code}\n' "$BASE/mcp" # unauthenticated should reject
225
- curl -s -o /dev/null -w '%{http_code}\n' "$BASE/" # redirect or 200
226
- curl -s -o /dev/null -w '%{http_code}\n' "$BASE/admin/sign-in" # 200/302 auth entry
227
- ```
116
+ 6. Authorize Wrangler and apply provision:
228
117
 
229
- Then ask the user to sign in through GitHub at
230
- `<worker-url>/admin/sign-in` and connect an MCP-capable client to
231
- `<worker-url>/mcp/staff`.
118
+ ```bash
119
+ pnpm exec wrangler login
120
+ read -rsp "GitHub OAuth client secret: " GITHUB_CLIENT_SECRET && export GITHUB_CLIENT_SECRET && printf "\n"
121
+ pnpm run provision:up -- --worker-url <worker-url> --github-username <gh-login> --client-id <client-id>
122
+ unset GITHUB_CLIENT_SECRET
123
+ ```
232
124
 
233
- 9. **Operator setup proof.** Open the operator setup URL:
125
+ 7. Commit and push generated non-secret outputs:
234
126
 
235
- ```text
236
- https://mantle.tools/connect?site=<url-encoded-worker-url>
237
- ```
127
+ ```bash
128
+ git status --short -- wrangler.toml src/mantleConfig.ts mantle/site.md AGENTS.md
129
+ ```
238
130
 
239
- Confirm it shows the Staff MCP URL, User MCP URL, Claude connector
240
- entry, and `mantle-companion-upload` plugin install commands. The
241
- companion upload path must pass file references/metadata only; large
242
- binary payloads go through Mantle upload sessions and signed URLs,
243
- not base64 MCP tool arguments.
131
+ 8. Smoke test:
244
132
 
245
- 10. **Second-agent proof.** Connect a second agent through Staff MCP and
246
- run the starter's core workflow: list collections, create/update a
247
- draft, publish or submit the starter's natural operation, and confirm
248
- a public read path. Do not create throwaway production submissions
249
- unless the user explicitly accepts those records.
133
+ - public home route;
134
+ - `/admin/sign-in`;
135
+ - GitHub admin sign-in;
136
+ - `/mcp/staff` with an agent client when available;
137
+ - a starter-specific core workflow.
250
138
 
251
- ## Feature overlays
139
+ ## Feature Overlays
252
140
 
253
141
  If `.mantle/features.json` lists features, run the repo-local feature
254
142
  overlay skill first:
@@ -257,25 +145,24 @@ overlay skill first:
257
145
  .agent/skills/mantle-feature-overlays/SKILL.md
258
146
  ```
259
147
 
260
- Feature scripts are starter lifecycle scripts, not Mantle CLI
261
- commands. Run them only when the feature is present and the user
262
- accepts any extra provider/billing requirement.
148
+ Feature scripts are starter lifecycle scripts, not Mantle CLI commands.
149
+ Run them only when the feature is present and the user accepts any extra
150
+ provider/billing requirement.
263
151
 
264
152
  ## Handoff
265
153
 
266
154
  After smoke checks pass, render a short final handoff in the user's
267
- language, in plain words (no `wrangler.toml` / secret / CLI jargon):
155
+ language:
268
156
 
269
157
  - Public URL.
270
158
  - Admin sign-in URL.
271
159
  - Staff MCP URL.
272
- - Operator setup URL (`https://mantle.tools/connect?site=...`) for
273
- Staff/User MCP connection and the companion upload plugin.
160
+ - Operator setup URL (`https://mantle.tools/connect?site=...`).
274
161
  - What changed locally and what was committed.
275
162
  - Any intentionally deferred feature setup.
276
163
 
277
- Point future agents at `mantle/site.md`, `AGENTS.md`, and the
278
- repo-local `.agent/skills/` directory.
164
+ Point future agents at `mantle/site.md`, `AGENTS.md`, and the repo-local
165
+ `.agent/skills/` directory.
279
166
 
280
167
  ## Diagnostics
281
168
 
@@ -297,7 +184,3 @@ repo-local `.agent/skills/` directory.
297
184
  locally and the real Worker URL in production.
298
185
  - Don't use `/admin/auth/github/callback`; the Better Auth callback path
299
186
  is `/api/auth/callback/github`.
300
- - Don't recite a browser step to a non-coder as a terse `A → B → C`
301
- breadcrumb, a `KEY=value` reply contract, a `<placeholder>` they might
302
- paste literally, or an internal correctness warning (e.g. the
303
- `127.0.0.1` rule). See **Presenting browser steps**.
@@ -1,55 +0,0 @@
1
- # Starting prompts
2
-
3
- Localized two-URL starting-prompt drafts, one per archetype + locale.
4
-
5
- ## What these are
6
-
7
- The single sentence the user pastes into Claude Code / Cursor / Codex / any MCP-capable agent to bootstrap a new mantle project. Format is always:
8
-
9
- ```
10
- <localized verb> <SKILL_INSTALL_URL> <localized connector> <SKILL_ARCHETYPE_URL> <localized "for this purpose">: <Archetype name>.
11
- ```
12
-
13
- Two URLs, no YAML, no form fields. The skill reads both URLs, then [Mantle](../../skills/install/SKILL.md) conducts a soft conversation to gather the rest. The official landing page at the Mantle landing page (source: [`aotter/mantle-landing`](https://github.com/aotter/mantle-landing)) generates this string dynamically from `src/starterArchetypes.ts` — the files in this directory are direct-paste fallbacks and references for documentation.
14
-
15
- ## File naming
16
-
17
- ```
18
- docs/prompts/<archetype>.<locale>.md
19
- ```
20
-
21
- - `<archetype>` matches a file in [`skills/install/archetypes/`](../../skills/install/archetypes/).
22
- - `<locale>` follows BCP 47. The locale of the prompt only affects the verb / connector phrasing; the site's canonical locale is set later through Mantle's interview.
23
-
24
- ## URL convention
25
-
26
- - `SKILL_INSTALL_URL` = `https://raw.githubusercontent.com/aotter/mantle/<ref>/skills/install/SKILL.md`
27
- - `SKILL_ARCHETYPE_URL` = `https://raw.githubusercontent.com/aotter/mantle/<ref>/skills/install/archetypes/<archetype>.md`
28
-
29
- `<ref>` is a pinned release tag (preferred) or `main`. The landing page uses the pinned tag.
30
-
31
- ## What the prompt does NOT carry
32
-
33
- These used to live in a `mantle_request:` YAML block. They are now gathered by Mantle's interview:
34
-
35
- - `project_name`
36
- - `brand`
37
- - `description`
38
- - `github_username`
39
- - `locales`
40
-
41
- The Mantle thesis says the runtime carries complexity — Mantle, here, gathers what install needs without a pre-flight form.
42
-
43
- ## Adding a prompt
44
-
45
- When a new archetype lands in [`skills/install/archetypes/`](../../skills/install/archetypes/):
46
-
47
- 1. Add `docs/prompts/<archetype>.<locale>.md` for each supported locale.
48
- 2. Update `mantle-landing/src/starterArchetypes.ts` `promptEn` / `promptZh` for the same archetype.
49
- 3. Keep the format consistent across locales — only the verb / connector localize.
50
-
51
- ## See also
52
-
53
- - [Epic #97](https://github.com/aotter/mantle/issues/97) — landing-page-prompt no-YAML pivot.
54
- - [`skills/install/SKILL.md`](../../skills/install/SKILL.md) — what the agent does after receiving the prompt.
55
- - [ADR-0013](../adr/0013-agent-provisioned-consumer-projects.md) — the broader install / provision / handoff flow.
@@ -1 +0,0 @@
1
- Use https://raw.githubusercontent.com/aotter/mantle/{template_ref}/skills/install/SKILL.md and https://raw.githubusercontent.com/aotter/mantle/{template_ref}/skills/install/archetypes/publication.md to build: Publication.
@@ -1 +0,0 @@
1
- 用 https://raw.githubusercontent.com/aotter/mantle/{template_ref}/skills/install/SKILL.md 跟 https://raw.githubusercontent.com/aotter/mantle/{template_ref}/skills/install/archetypes/publication.md 架設:Publication 網站。