@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 +5 -1
- package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +7 -4
- package/package.json +5 -5
- package/skills/install/SKILL.md +72 -37
- package/skills/provision/SKILL.md +79 -196
- package/docs/prompts/README.md +0 -55
- package/docs/prompts/publication.en.md +0 -1
- package/docs/prompts/publication.zh-TW.md +0 -1
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,
|
|
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 +
|
|
245
|
+
### Skills + launch handoff
|
|
246
246
|
|
|
247
|
-
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
51
|
-
"@aotter/mantle-
|
|
52
|
-
"@aotter/mantle-
|
|
53
|
-
"@aotter/mantle-
|
|
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",
|
package/skills/install/SKILL.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
117
|
+
Do not proceed to manual fallback until preflight passes.
|
|
115
118
|
|
|
116
|
-
##
|
|
119
|
+
## Manual fallback
|
|
117
120
|
|
|
118
|
-
Use this
|
|
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
|
-
|
|
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
|
|
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`
|
|
140
|
+
| **github identity** | `--github-owner` and optional `--admin-github-login` |
|
|
134
141
|
|
|
135
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 |
|
|
210
|
-
|
|
211
|
-
| **purpose / audience
|
|
212
|
-
| **audience scope** |
|
|
213
|
-
| **locales** |
|
|
214
|
-
| **description** |
|
|
215
|
-
| **summary** |
|
|
216
|
-
| **brand** |
|
|
217
|
-
| **project-name** |
|
|
218
|
-
| **github owner** |
|
|
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
|
|
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
|
-
|
|
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. **
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
|
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
|
|
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
|
|
14
|
+
The base flow is deterministic first, provider-browser second:
|
|
15
15
|
|
|
16
|
-
1. The
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
27
|
-
coding agent.
|
|
27
|
+
handoff; provider authority stays with the user and their coding agent.
|
|
28
28
|
|
|
29
|
-
## End
|
|
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.
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
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
|
-
|
|
64
|
+
Run from the generated project root.
|
|
82
65
|
|
|
83
|
-
|
|
66
|
+
1. Preflight:
|
|
84
67
|
|
|
85
68
|
```bash
|
|
69
|
+
pnpm install --frozen-lockfile
|
|
86
70
|
pnpm validate
|
|
87
71
|
pnpm typecheck
|
|
88
|
-
|
|
89
|
-
pnpm
|
|
90
|
-
|
|
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
|
-
|
|
94
|
-
|
|
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
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
168
|
-
and ask the user to switch/login before creating the repo.
|
|
97
|
+
4. Print the deterministic plan:
|
|
169
98
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
208
|
-
|
|
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
|
-
|
|
106
|
+
5. Ask the user to create the per-site GitHub OAuth App after the Worker
|
|
107
|
+
URL is known:
|
|
215
108
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
109
|
+
- Homepage URL: `<worker-url>`
|
|
110
|
+
- Authorization callback URL: `<worker-url>/api/auth/callback/github`
|
|
111
|
+
- Device Flow: unchecked
|
|
219
112
|
|
|
220
|
-
|
|
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
|
-
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
-
|
|
125
|
+
7. Commit and push generated non-secret outputs:
|
|
234
126
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
127
|
+
```bash
|
|
128
|
+
git status --short -- wrangler.toml src/mantleConfig.ts mantle/site.md AGENTS.md
|
|
129
|
+
```
|
|
238
130
|
|
|
239
|
-
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
|
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
|
-
|
|
262
|
-
|
|
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
|
|
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=...`)
|
|
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
|
-
|
|
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**.
|
package/docs/prompts/README.md
DELETED
|
@@ -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 網站。
|