@aotter/mantle 0.1.3 → 0.1.4
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 -5
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +1 -1
- package/dist/cli/skills.js +1 -1
- package/dist/cli/skills.js.map +1 -1
- package/docs/adr/0001-four-atom-manifest-model.md +3 -2
- package/docs/adr/0013-agent-provisioned-consumer-projects.md +4 -4
- package/docs/adr/0016-site-semantic-layer.md +5 -4
- package/docs/adr/0018-core-starters-repository-boundary.md +1 -1
- package/docs/adr/README.md +2 -2
- package/docs/agent-prompts.md +5 -4
- package/docs/assets/mantle-admin-developer.png +0 -0
- package/docs/examples/README.md +1 -1
- package/docs/examples/host-chatgpt-sites/README.md +29 -12
- package/docs/examples/host-chatgpt-sites/drizzle/0003_store_instance_id.sql +1 -0
- package/docs/examples/host-chatgpt-sites/drizzle/meta/_journal.json +1 -1
- package/docs/examples/host-chatgpt-sites/public/site.css +1 -1
- package/docs/examples/host-chatgpt-sites/scripts/build.mjs +2 -1
- package/docs/examples/host-chatgpt-sites/scripts/check.mjs +2 -0
- package/docs/examples/host-chatgpt-sites/src/index.ts +1 -1
- package/docs/examples/host-chatgpt-sites/src/web.ts +1 -1
- package/docs/examples/host-minimal-worker/README.md +5 -5
- package/docs/handbook/{sites → chatgpt-sites}/equipment-checkout.md +1 -1
- package/docs/handbook/{sites → chatgpt-sites}/index.md +15 -3
- package/docs/handbook/cloudflare/chatgpt-sites.md +6 -6
- package/docs/handbook/cloudflare/deploy-and-operate.md +3 -2
- package/docs/handbook/cloudflare/media-r2.md +2 -2
- package/docs/handbook/concepts/four-atoms.md +1 -1
- package/docs/handbook/concepts/lifecycle-and-locales.md +1 -1
- package/docs/handbook/concepts/mcp-and-agents.md +24 -4
- package/docs/handbook/concepts/procedures-and-triggers.md +1 -1
- package/docs/handbook/concepts/runtime-and-adapters.md +1 -1
- package/docs/handbook/concepts/views.md +1 -1
- package/docs/handbook/guides/agent-setup.md +6 -5
- package/docs/handbook/navigation.json +4 -4
- package/docs/handbook/releases/index.md +26 -1
- package/docs/handbook/start/overview.md +1 -1
- package/docs/handbook/start/project-and-cli.md +5 -5
- package/docs/handbook/start/quickstart-worker.md +0 -3
- package/docs/release-process.md +3 -2
- package/docs/sealed-pipeline-ownership.md +1 -1
- package/docs/skills/develop/SKILL.md +250 -0
- package/docs/skills/media-gc/SKILL.md +85 -0
- package/docs/skills/plugin/SKILL.md +132 -0
- package/docs/skills/provision/SKILL.md +194 -0
- package/docs/skills/theme/SKILL.md +77 -0
- package/docs/skills/update/SKILL.md +51 -0
- package/docs/spec-only-host-adoption.md +1 -1
- package/package.json +18 -18
- package/skills/README.md +26 -21
- package/skills/develop/SKILL.md +2 -2
- package/skills/install/SKILL.md +19 -7
- package/skills/media-gc/SKILL.md +2 -2
- package/skills/plugin/SKILL.md +2 -2
- package/skills/provision/SKILL.md +3 -3
- package/skills/theme/SKILL.md +2 -2
- package/skills/update/SKILL.md +2 -2
- package/skills/.keep +0 -0
- /package/docs/handbook/{sites → chatgpt-sites}/host-reference.md +0 -0
|
@@ -68,6 +68,25 @@ Only `status: published` entries appear anywhere in that set. Details are in [Pu
|
|
|
68
68
|
|
|
69
69
|
## WebMCP in the browser
|
|
70
70
|
|
|
71
|
+
### Admin: tools for the signed-in staff member
|
|
72
|
+
|
|
73
|
+
Admin UI registers staff tools in browsers supporting `document.modelContext`.
|
|
74
|
+
The catalog comes from `GET /admin/api/webmcp`; calls use
|
|
75
|
+
`POST /admin/api/mcp` with the current staff session. Server-side role checks,
|
|
76
|
+
Procedure authorization, and optimistic concurrency remain in force.
|
|
77
|
+
`admin_get_context` and `admin_navigate` add page context and navigation.
|
|
78
|
+
The WebMCP control appears after registration succeeds; unsupported browsers
|
|
79
|
+
can continue using the regular Admin UI.
|
|
80
|
+
|
|
81
|
+
Owners can explore application API documentation in Developer UI:
|
|
82
|
+
`/admin/dev/docs/api` for HTTP, `/admin/dev/docs/mcp` for remote MCP, and
|
|
83
|
+
`/admin/dev/docs/webmcp` for the Admin catalog and public-page capabilities.
|
|
84
|
+
These pages show projected definitions. Remote clients connect to the host's
|
|
85
|
+
advertised MCP endpoints using the authentication described above.
|
|
86
|
+
See the [Admin API guide](../../../packages/mantle-admin/README.md#admin-webmcp).
|
|
87
|
+
|
|
88
|
+
### Public pages: opt-in registration
|
|
89
|
+
|
|
71
90
|
`@aotter/mantle-web/webmcp` exposes public capabilities as tools inside a page, for browsers implementing the draft imperative WebMCP API. Importing the subpath has no side effect; registration starts only when `bindWebMcp()` is called.
|
|
72
91
|
|
|
73
92
|
```ts
|
|
@@ -78,7 +97,7 @@ const binding = await bindWebMcp();
|
|
|
78
97
|
binding.dispose();
|
|
79
98
|
```
|
|
80
99
|
|
|
81
|
-
It feature-detects `document.modelContext` and returns `{ supported: false }` on browsers without it.
|
|
100
|
+
It feature-detects `document.modelContext` and returns `{ supported: false }` on browsers without it. This public-page binding registers only public capabilities. Staff tools use the separate authenticated Admin integration above. Existing host tool names are inspected and skipped, never replaced. A server-backed page discovers the safe descriptors published at `GET /api/views` and calls the same-origin `GET /api/views/<name>` routes; a browser-local SPA passes `projectCallableCapabilities(plan, { surface: "public" })` and its own invoker. Procedure tools must still originate from an explicit public MCP Trigger, and invocation enters the runtime through that Trigger, so browser tools cannot bypass validation or authorization. See [Runtime pipeline and adapters](./runtime-and-adapters.md).
|
|
82
101
|
|
|
83
102
|
## Skills for your coding agent
|
|
84
103
|
|
|
@@ -91,11 +110,12 @@ pnpm exec mantle skills --check
|
|
|
91
110
|
|
|
92
111
|
This copies every skill the installed package marks `projection: project` — the develop skill among them — into matching `.agents/skills/mantle-*` and `.claude/skills/mantle-*` paths. Both layouts receive identical bytes; `--check` detects drift without writing. Skills that act destructively or target one platform stay out of that set and are opt-in. Manifest generation never rewrites agent instructions.
|
|
93
112
|
|
|
94
|
-
The
|
|
113
|
+
The bootstrap `mantle` skill is also available from the plugin marketplace.
|
|
114
|
+
The ongoing workflows come from the installed SDK through `mantle skills`:
|
|
95
115
|
|
|
96
116
|
```sh
|
|
97
117
|
# Canonical
|
|
98
|
-
npx skills add aotter/mantle
|
|
118
|
+
npx skills add aotter/mantle
|
|
99
119
|
|
|
100
120
|
# Claude Code — two separate prompts
|
|
101
121
|
/plugin marketplace add aotter/mantle
|
|
@@ -111,4 +131,4 @@ Never point a versioned project at a mutable branch. See [Project layout and the
|
|
|
111
131
|
- [`packages/mantle-web/README.md`](../../../packages/mantle-web/README.md)
|
|
112
132
|
- [`packages/mantle/README.md`](../../../packages/mantle/README.md)
|
|
113
133
|
- [`packages/adapters/cloudflare/README.md`](../../../packages/adapters/cloudflare/README.md)
|
|
114
|
-
- [`skills/develop/SKILL.md`](
|
|
134
|
+
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
@@ -218,4 +218,4 @@ Register the two `ref` keys in the project's handlers map, then run the check lo
|
|
|
218
218
|
- [`packages/mantle-spec/src/domain/model/ManifestGrammar.ts`](../../../packages/mantle-spec/src/domain/model/ManifestGrammar.ts)
|
|
219
219
|
- [`packages/mantle-runtime/src/domain/service/BuiltinProjector.ts`](../../../packages/mantle-runtime/src/domain/service/BuiltinProjector.ts)
|
|
220
220
|
- [`packages/mantle-runtime/src/infrastructure/http/createMantleRequestHandler.ts`](../../../packages/mantle-runtime/src/infrastructure/http/createMantleRequestHandler.ts)
|
|
221
|
-
- [`skills/develop/SKILL.md`](
|
|
221
|
+
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
@@ -174,4 +174,4 @@ If a normal feature cannot be expressed through a purpose-shaped surface, treat
|
|
|
174
174
|
- [`packages/adapters/bun/README.md`](../../../packages/adapters/bun/README.md)
|
|
175
175
|
- [`packages/adapters/vercel/README.md`](../../../packages/adapters/vercel/README.md)
|
|
176
176
|
- [`packages/adapters/indexeddb/README.md`](../../../packages/adapters/indexeddb/README.md)
|
|
177
|
-
- [`skills/develop/SKILL.md`](
|
|
177
|
+
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
@@ -189,4 +189,4 @@ spec:
|
|
|
189
189
|
- [`packages/mantle-runtime/src/infrastructure/storage/SqliteViewCompiler.ts`](../../../packages/mantle-runtime/src/infrastructure/storage/SqliteViewCompiler.ts)
|
|
190
190
|
- [`packages/mantle-runtime/src/infrastructure/http/createMantleRequestHandler.ts`](../../../packages/mantle-runtime/src/infrastructure/http/createMantleRequestHandler.ts)
|
|
191
191
|
- [`packages/adapters/cloudflare/src/mount/mountRuntimeEndpoints.ts`](../../../packages/adapters/cloudflare/src/mount/mountRuntimeEndpoints.ts)
|
|
192
|
-
- [`skills/develop/SKILL.md`](
|
|
192
|
+
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
@@ -9,12 +9,12 @@ application's SDK. Installing one does not install the other.
|
|
|
9
9
|
## 1. Install the bootstrap skill
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npx skills add aotter/mantle
|
|
12
|
+
npx skills add aotter/mantle
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
The installer selects the repository's `
|
|
15
|
+
The installer selects the repository's `mantle` skill. Read its printed
|
|
16
16
|
installation path. In a project-local Codex installation that is
|
|
17
|
-
`.agents/skills/
|
|
17
|
+
`.agents/skills/mantle/SKILL.md`, not `skills/install/SKILL.md` (the latter is
|
|
18
18
|
its source-repository path). Other agent selections and global installation
|
|
19
19
|
can use different locations.
|
|
20
20
|
|
|
@@ -32,6 +32,7 @@ version. `latest` and `alpha` can describe different capabilities. Resolve only
|
|
|
32
32
|
requirements the user has not provided: host, storage, public API/HTML, and
|
|
33
33
|
whether staff need Admin. Follow the bootstrap skill to install the selected
|
|
34
34
|
packages locally.
|
|
35
|
+
No matching `mantle-starters` tag or bundle is needed to create a project.
|
|
35
36
|
|
|
36
37
|
Then read:
|
|
37
38
|
|
|
@@ -44,7 +45,7 @@ node_modules/@aotter/mantle/docs/handbook/reference/features.md
|
|
|
44
45
|
These files are in the npm tarball. They are the version-matched authority,
|
|
45
46
|
including when the bootstrap skill came from a different Git ref. Every
|
|
46
47
|
`docs/...` path in the skill resolves under the installed package, not under
|
|
47
|
-
`.agents/skills/
|
|
48
|
+
`.agents/skills/mantle/`. Keep using that SDK's docs for host examples and CLI
|
|
48
49
|
behavior. No local `mantle` binary is available before package installation.
|
|
49
50
|
|
|
50
51
|
## 3. Project the ongoing workflows
|
|
@@ -61,7 +62,7 @@ pnpm exec mantle skills --check
|
|
|
61
62
|
|---|---|
|
|
62
63
|
| `.agents/skills/mantle-{develop,plugin,theme,update}/SKILL.md` | The installed package's four project-scoped workflows. |
|
|
63
64
|
| `.claude/skills/mantle-{develop,plugin,theme,update}/SKILL.md` | Identical bytes for Claude compatibility. |
|
|
64
|
-
| `node_modules/@aotter/mantle/skills/` | All seven shipped skills, including opt-in `
|
|
65
|
+
| `node_modules/@aotter/mantle/skills/` | All seven shipped skills, including opt-in `mantle`, `provision` and `media-gc`. |
|
|
65
66
|
| `node_modules/@aotter/mantle/docs/` | Handbook and examples matched to the package. |
|
|
66
67
|
|
|
67
68
|
`mantle skills` overwrites these four generated projections. Keep project-specific
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{ "text": "Project layout and the CLI loop", "link": "/start/project-and-cli" },
|
|
9
9
|
{ "text": "Quickstart: a minimal Worker", "link": "/start/quickstart-worker" },
|
|
10
10
|
{ "text": "Quickstart: local Admin (opt-in)", "link": "/start/quickstart-admin" },
|
|
11
|
-
{ "text": "When the host is ChatGPT Sites", "link": "/sites/index" }
|
|
11
|
+
{ "text": "When the host is ChatGPT Sites", "link": "/chatgpt-sites/index" }
|
|
12
12
|
]
|
|
13
13
|
},
|
|
14
14
|
{
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
{
|
|
50
50
|
"text": "ChatGPT Sites",
|
|
51
51
|
"items": [
|
|
52
|
-
{ "text": "Get started", "link": "/sites/index" },
|
|
53
|
-
{ "text": "Host reference", "link": "/sites/host-reference" },
|
|
54
|
-
{ "text": "Equipment checkout and external APIs", "link": "/sites/equipment-checkout" },
|
|
52
|
+
{ "text": "Get started", "link": "/chatgpt-sites/index" },
|
|
53
|
+
{ "text": "Host reference", "link": "/chatgpt-sites/host-reference" },
|
|
54
|
+
{ "text": "Equipment checkout and external APIs", "link": "/chatgpt-sites/equipment-checkout" },
|
|
55
55
|
{ "text": "Earlier guide URL", "link": "/cloudflare/chatgpt-sites" }
|
|
56
56
|
]
|
|
57
57
|
},
|
|
@@ -21,6 +21,31 @@ All eleven packages share a single version and are published together, so mixed
|
|
|
21
21
|
versions across `@aotter/mantle*` are never a supported combination. Pin the
|
|
22
22
|
version you install and upgrade the whole set at once.
|
|
23
23
|
|
|
24
|
+
## 0.1.4 — 2026-09-24
|
|
25
|
+
|
|
26
|
+
0.1.4 repairs the published consumer path without changing the Manifest
|
|
27
|
+
grammar. Pin every selected `@aotter/mantle*` package to `0.1.4`, refresh the
|
|
28
|
+
lockfile, then rerun `mantle generate` and `mantle skills` with their `--check`
|
|
29
|
+
commands. Read the handbook and skills from that installed version.
|
|
30
|
+
|
|
31
|
+
**ChatGPT Sites reference.** The 0.1.3 reference omitted the
|
|
32
|
+
`_mantle_boot_state.store_instance_id` column required by the runtime, which
|
|
33
|
+
could make deployed runtime routes return 500. The reference now adds the
|
|
34
|
+
append-only `drizzle/0003_store_instance_id.sql` migration. If your project
|
|
35
|
+
was copied from that reference, carry the new migration forward and apply
|
|
36
|
+
pending D1 migrations **before** deploying updated code; do not edit a
|
|
37
|
+
migration already applied. Repeated builds now clear `dist` so removed SQL
|
|
38
|
+
files cannot remain in the deployment artifact. The Sites guide also shows
|
|
39
|
+
how to mount an HTTP Trigger, identifies the browser and MCP owner workflows,
|
|
40
|
+
and names its integration chapter `docs/handbook/chatgpt-sites/`.
|
|
41
|
+
|
|
42
|
+
**Agent installation.** `npx skills add aotter/mantle` installs the small
|
|
43
|
+
`mantle` bootstrap skill; the installed npm package supplies version-matched
|
|
44
|
+
instructions and docs. The skill now checks the application's installed
|
|
45
|
+
version before reading them. Superseded Starter decisions are marked as
|
|
46
|
+
history: no `mantle-starters/v0.1.4` tag or `mantle create` command is needed
|
|
47
|
+
to author a new application.
|
|
48
|
+
|
|
24
49
|
## 0.1.3 — 2026-09-23
|
|
25
50
|
|
|
26
51
|
0.1.3 tightens the contract between Manifests, generated TypeScript, agent
|
|
@@ -98,7 +123,7 @@ See [HTTP, MCP, CLI and packages](../reference/surface.md) for the full list.
|
|
|
98
123
|
D1 and assets bindings, Better Auth 1.7 (social providers, email OTP, magic
|
|
99
124
|
link, passkey), Admin, MCP, Web and R2 media uploads. The Bun and Vercel
|
|
100
125
|
adapters are experimental, cover public Views and HTTP Triggers only, and leave
|
|
101
|
-
authentication and CSRF to the host. [ChatGPT Sites](../sites/index.md) is a
|
|
126
|
+
authentication and CSRF to the host. [ChatGPT Sites](../chatgpt-sites/index.md) is a
|
|
102
127
|
first-class integration with a runnable reference.
|
|
103
128
|
|
|
104
129
|
**Agents.** `mantle skills` projects the installed package's skills into
|
|
@@ -24,7 +24,7 @@ current npm `latest` contains it.
|
|
|
24
24
|
| Embed Runtime in an existing host | [Runtime and adapters](../concepts/runtime-and-adapters.md), then [typed queries](../guides/typed-queries.md) | Bind your storage and call the generated API. |
|
|
25
25
|
| Build a local Cloudflare API | [Minimal Worker tutorial](./quickstart-worker.md) | A running public View and a verified HTTP response. |
|
|
26
26
|
| Add a staff console | [Local Admin tutorial](./quickstart-admin.md) | Email OTP, Admin assets and a local human workflow. |
|
|
27
|
-
| Build on ChatGPT Sites | [Sites integration](../sites/index.md) | Host-owned sign-in and deployment with Mantle content. |
|
|
27
|
+
| Build on ChatGPT Sites | [Sites integration](../chatgpt-sites/index.md) | Host-owned sign-in and deployment with Mantle content. |
|
|
28
28
|
| Work through a coding agent | [Skill installation and handoff](../guides/agent-setup.md) | Bootstrap skill, pinned package, then project-local instructions. |
|
|
29
29
|
|
|
30
30
|
Human authors can follow these pages directly; installing an agent skill is
|
|
@@ -8,7 +8,7 @@ This page describes a directly authored Mantle project: which files are yours, w
|
|
|
8
8
|
Agents can bootstrap with the install skill; human authors can follow this guide directly. For installation paths and the pinned-package handoff, see [Agent setup](../guides/agent-setup.md):
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
-
npx skills add aotter/mantle
|
|
11
|
+
npx skills add aotter/mantle
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
## You own the project
|
|
@@ -96,14 +96,14 @@ Run the harness after any change to a Schema index, View filter or ordering, or
|
|
|
96
96
|
|
|
97
97
|
## Connecting an agent
|
|
98
98
|
|
|
99
|
-
`mantle skills` projects the skills the installed package marks `projection: project`. At this version those are `develop`, `plugin`, `theme` and `update`; `
|
|
99
|
+
`mantle skills` projects the skills the installed package marks `projection: project`. At this version those are `develop`, `plugin`, `theme` and `update`; `mantle`, `media-gc` and `provision` stay opt-in because they create projects, delete remote objects or handle production secrets. Both tool layouts receive identical bytes. Generation never rewrites these files.
|
|
100
100
|
|
|
101
|
-
Install the
|
|
101
|
+
Install the bootstrap skill in the agent host. Cold start uses
|
|
102
102
|
the install skill; an already-installed project pins packages from `package.json`:
|
|
103
103
|
|
|
104
104
|
```sh
|
|
105
105
|
# Canonical
|
|
106
|
-
npx skills add aotter/mantle
|
|
106
|
+
npx skills add aotter/mantle
|
|
107
107
|
|
|
108
108
|
# Claude Code — two separate prompts
|
|
109
109
|
/plugin marketplace add aotter/mantle
|
|
@@ -137,4 +137,4 @@ The projected `develop` skill tells the agent to read `package.json` for the ins
|
|
|
137
137
|
- [`packages/mantle-spec/src/infrastructure/cli/ValidateCommand.ts`](../../../packages/mantle-spec/src/infrastructure/cli/ValidateCommand.ts)
|
|
138
138
|
- [`packages/mantle-spec/src/infrastructure/cli/EmitOpenapiCommand.ts`](../../../packages/mantle-spec/src/infrastructure/cli/EmitOpenapiCommand.ts)
|
|
139
139
|
- [`packages/mantle-spec/src/infrastructure/cli/MantleCli.ts`](../../../packages/mantle-spec/src/infrastructure/cli/MantleCli.ts)
|
|
140
|
-
- [`skills/develop/SKILL.md`](
|
|
140
|
+
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
@@ -174,9 +174,6 @@ curl -i http://127.0.0.1:8787/mcp/staff
|
|
|
174
174
|
|
|
175
175
|
`generate` fails on missing or invalid manifests and never creates a project, a default Schema or a home route. `mantle generate --check` reports stale output without writing. The reference keeps `.mantle/`, `.agents/` and `.claude/` out of git and regenerates them in `check`; see [Project layout and the CLI loop](./project-and-cli.md).
|
|
176
176
|
|
|
177
|
-
> **npm and optional peers**
|
|
178
|
-
> A cold npm install can fail with `ERESOLVE` when an Auth peer selects a different optional `@libsql/client` than this snapshot declares. If that happens, pin `@libsql/client` in `overrides` to the range in this checkout's `package.json` and rerun `npm install`. Do not use `--force`. Commit the lockfile and use `npm ci` afterwards.
|
|
179
|
-
|
|
180
177
|
## Next steps
|
|
181
178
|
|
|
182
179
|
- [Quickstart: local Admin](./quickstart-admin.md) — opt-in Dev UI: ASSETS, prebuilt Admin, email OTP.
|
package/docs/release-process.md
CHANGED
|
@@ -110,10 +110,11 @@ dist-tag DELETE only added failure and re-run state, and Actions
|
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
Leave the consumer cold-start entry **untagged**: `npx skills add
|
|
113
|
-
aotter/mantle
|
|
113
|
+
aotter/mantle`, `/plugin marketplace add aotter/mantle`,
|
|
114
114
|
`codex plugin marketplace add aotter/mantle` and the plugin-manifest
|
|
115
115
|
descriptions carry no `@v…` / `--ref`. Untagged resolves to `main`, which
|
|
116
|
-
|
|
116
|
+
normally moves at a release but may contain a source-only hotfix; the
|
|
117
|
+
installed npm package remains the version authority
|
|
117
118
|
(#995, #998). Only "installed version" statements such as
|
|
118
119
|
`(currently \`X.Y.Z\`)` are bumped.
|
|
119
120
|
|
|
@@ -65,7 +65,7 @@ release use `docs/examples/host-minimal-worker` from the same reviewed commit.
|
|
|
65
65
|
Private consumers can still run the exact-tarball checker in their own repos;
|
|
66
66
|
public Core PRs receive no cross-repository credentials:
|
|
67
67
|
|
|
68
|
-
|
|
|
68
|
+
| Historical consumer | Revision | Gate at the time | Manifest paths |
|
|
69
69
|
|---|---|---|---|
|
|
70
70
|
| `aotter/mantle-starters` | `157e8f49e1e25ae1c52c0115f0dd9e8b6017ef0e` | Core CI + release | `blank/manifests/site.yaml`; `overlays/{community,intake,presence,publication,reservation,transaction}/manifests/site.yaml`; `recipes/typed-web/manifests/site.yaml` |
|
|
71
71
|
| `aotter/mantle-landing` | `4381354dd25d5d94f4096cf3e55a4cb9eecbf3ad` | Landing CI + Core release | `manifests/site.yaml` |
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: develop
|
|
3
|
+
description: Work on any Mantle project using the Core SDK contract. Use for manifest, runtime, content model, handler, adapter, validation, and MCP work after a project already exists.
|
|
4
|
+
metadata:
|
|
5
|
+
source: "@aotter/mantle"
|
|
6
|
+
sourcePath: docs/skills/develop/SKILL.md
|
|
7
|
+
applies_to: mantle grammar v0.1
|
|
8
|
+
projection: project
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Mantle Develop
|
|
12
|
+
|
|
13
|
+
This is the Core workflow skill for an existing Mantle project. Repo-local
|
|
14
|
+
copies are byte-for-byte projections from the installed package; its embedded
|
|
15
|
+
docs govern runtime/API behavior.
|
|
16
|
+
|
|
17
|
+
## First Read
|
|
18
|
+
|
|
19
|
+
1. `package.json` for the installed `@aotter/mantle*` versions.
|
|
20
|
+
2. The manifest directory selected by the project scripts, the actual host
|
|
21
|
+
entry and adapter config (for example `wrangler.jsonc` on Cloudflare).
|
|
22
|
+
Read custom Auth construction there when present.
|
|
23
|
+
3. Optional local context: `.mantle/plugins.json`, `.mantle/plugins.lock.json`,
|
|
24
|
+
and `.mantle/recipes/`. Legacy launch/handoff files are context only.
|
|
25
|
+
4. Installed Core docs in `node_modules/@aotter/mantle/docs/`.
|
|
26
|
+
|
|
27
|
+
If `node_modules/` is missing, run `pnpm install --frozen-lockfile` before
|
|
28
|
+
falling back to remote docs. Remote docs must use a tag matching the installed
|
|
29
|
+
version; never use `develop` branch docs for a versioned consumer project.
|
|
30
|
+
|
|
31
|
+
## Existing Examples
|
|
32
|
+
|
|
33
|
+
Read installed `docs/handbook/start/project-and-cli.md` and
|
|
34
|
+
`docs/examples/README.md`. Use `docs/examples/host-minimal-worker/` for Spec +
|
|
35
|
+
adapter without Admin. Read `docs/examples/host-local-admin-otp/` only when the
|
|
36
|
+
project already has Admin or the human asked for Dev UI — that path is opt-in.
|
|
37
|
+
Ingest only `docs/examples/builtin-*.md` Manifests as grammar for new domains.
|
|
38
|
+
Read `docs/examples/cf-primitives-*.md` before inventing Durable Object, Queue,
|
|
39
|
+
cron, or `ref` handler patterns.
|
|
40
|
+
References are test/documentation, not a Starter or a fixed application shape.
|
|
41
|
+
|
|
42
|
+
Public rendering is opt-in consumer wiring: `mountPublicRoutes`, a
|
|
43
|
+
`TemplateRegistry`, and a matching `publicPathResolver` must agree on the
|
|
44
|
+
exposed collections. Do not auto-publish every Schema. Applications document their mounted URL surface in their own README.
|
|
45
|
+
Import the registry and resolver from `@aotter/mantle/web`; Core runtime does
|
|
46
|
+
not install public rendering by itself.
|
|
47
|
+
|
|
48
|
+
## Authoring CLI
|
|
49
|
+
|
|
50
|
+
Use the project's scripts first; applications use the shipping
|
|
51
|
+
`mantle` authoring CLI from `@aotter/mantle`. Ask the installed CLI for its
|
|
52
|
+
command list instead of trusting one copied into prose — the surface is
|
|
53
|
+
version-matched and changes between releases:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pnpm exec mantle --help
|
|
57
|
+
pnpm validate
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This CLI validates and derives artifacts from application-authored manifests.
|
|
61
|
+
It does not create projects, business schemas or a visitor homepage. There is
|
|
62
|
+
no `mantle create` / `mantle update` happy path.
|
|
63
|
+
|
|
64
|
+
## Core Model
|
|
65
|
+
|
|
66
|
+
Mantle exposes exactly four declarative atoms:
|
|
67
|
+
|
|
68
|
+
| Atom | Purpose |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `Schema` | Stored entity/table shape. |
|
|
71
|
+
| `View` | Read/query surface. |
|
|
72
|
+
| `Procedure` | Typed mutation or operation. |
|
|
73
|
+
| `Trigger` | HTTP/lifecycle/MCP invocation binding. |
|
|
74
|
+
|
|
75
|
+
Do not invent manifest kinds such as `Form`, `Feature`, `Workflow`, or
|
|
76
|
+
`Membership`. Compose those from the four atoms plus TypeScript only where
|
|
77
|
+
the atoms cannot express the behavior.
|
|
78
|
+
|
|
79
|
+
## Choose the manifest feature first
|
|
80
|
+
|
|
81
|
+
Read installed `docs/handbook/reference/features.md` to map the requested
|
|
82
|
+
behavior to fields before adding handlers or a custom UI. For host-only reads,
|
|
83
|
+
`surface: internal` keeps a View out of REST/MCP/Admin while preserving its
|
|
84
|
+
`requires` checks. Read `docs/handbook/guides/typed-queries.md` for generated
|
|
85
|
+
View params/results, indexed entry reads, and their authorization boundary.
|
|
86
|
+
Use `from` for portable typed projections; SQL is for queries needing native
|
|
87
|
+
SQLite and produces `unknown` row types.
|
|
88
|
+
|
|
89
|
+
For Admin labels, inputs, collection columns/tabs, reports or action buttons,
|
|
90
|
+
read `docs/handbook/guides/admin-ui.md`. Prefer supported Schema/Procedure/View
|
|
91
|
+
metadata and `uiSchema` before custom frontend code. These control the Admin
|
|
92
|
+
console, not the visitor frontend. Regenerate and verify the actual console;
|
|
93
|
+
never edit generated `public/_mantle/admin/` assets.
|
|
94
|
+
|
|
95
|
+
## Content Edits
|
|
96
|
+
|
|
97
|
+
- Follow the actual frontend content source. Use Admin or Staff MCP for
|
|
98
|
+
runtime-backed content. Do not invent an overlay/seed homepage.
|
|
99
|
+
- For a new submitted field, update the stored `Schema` and the public
|
|
100
|
+
`Procedure.spec.input` before any form UI. Keep public mutation inputs
|
|
101
|
+
`additionalProperties: false`; otherwise JSON Schema's default may strip an
|
|
102
|
+
undeclared field while returning success.
|
|
103
|
+
- Use `lifecycle: operational` for submissions, inquiries, orders, and other
|
|
104
|
+
Procedure-created operational records that staff inspect or correct. Reserve
|
|
105
|
+
`publishing` for content a person stages and publishes.
|
|
106
|
+
- Lifecycle `before_update` / `after_update` hooks also fire for unpublish,
|
|
107
|
+
archive, and every other status transition whose target is not `published`;
|
|
108
|
+
do not use them for edit-only work.
|
|
109
|
+
- When a form's fixed option values change, update the stored Schema and public
|
|
110
|
+
Procedure input `enum` together. Keep translated labels in the frontend content source;
|
|
111
|
+
Admin and Staff MCP derive their typed controls from the manifest values.
|
|
112
|
+
- If the application has a `page` Schema with sections, update its declared
|
|
113
|
+
section properties when adding display fields; an undeclared property has no
|
|
114
|
+
runtime-backed Admin or Staff MCP path.
|
|
115
|
+
- Update notification handlers when they need the new field. Test the stored
|
|
116
|
+
entry, not only the HTTP `{ "ok": true }` response.
|
|
117
|
+
|
|
118
|
+
## Locales
|
|
119
|
+
|
|
120
|
+
- `data.locale` is reserved for `localized: true` Schemas. A non-localized
|
|
121
|
+
Schema must use a domain field such as `replyLocale`.
|
|
122
|
+
- Use a standalone localized Schema only for independent locale rows. For
|
|
123
|
+
versions of one entity, use a non-localized parent plus a localized child
|
|
124
|
+
with `translates: { parent, on }`. The child must own at least one field
|
|
125
|
+
besides `locale` and the join field.
|
|
126
|
+
- Parallel locale blocks must keep field names, option values, step IDs, and
|
|
127
|
+
result keys identical; translate display strings only.
|
|
128
|
+
- `siteDefaults.origin`, `siteDefaults.locales`, and `siteDefaults.icons` are
|
|
129
|
+
code-owned and boot-synced. The icon list is shared by browser favicons,
|
|
130
|
+
Admin chrome, and MCP `serverInfo.icons`; keep its static files under
|
|
131
|
+
`public/`. Brand, title, and description seed once, then change through site
|
|
132
|
+
settings.
|
|
133
|
+
- When changing an existing collection from `[slug]` to `[slug, locale]`,
|
|
134
|
+
boot with a Mantle version that reconciles obsolete unique indexes and test
|
|
135
|
+
the same slug in two locales. Do not patch D1 manually.
|
|
136
|
+
|
|
137
|
+
## Adapter Boundary
|
|
138
|
+
|
|
139
|
+
The runtime is adapter-neutral. A `MantleStorageAdapter` prepares the compiled
|
|
140
|
+
plan into semantic storage ports; `createMantleRuntime` binds that prepared
|
|
141
|
+
storage and selected capabilities. Database drivers and asset serving belong
|
|
142
|
+
to the host/optional composition. Follow the installed adapter guide.
|
|
143
|
+
|
|
144
|
+
Do not assume Cloudflare unless the project imports `@aotter/mantle/cloudflare`
|
|
145
|
+
or its adapter config is visible. A future Netlify adapter should satisfy the
|
|
146
|
+
same Core workflow through its own ports and provider setup.
|
|
147
|
+
|
|
148
|
+
Site code is a consumer of this abstraction. Use Manifests, runtime use cases,
|
|
149
|
+
`runtime.entries`, and optional `runtime.siteConfig`; do not query Mantle-owned `entries` or
|
|
150
|
+
`site_config`, reach through deprecated `runtime.db`, copy generated-column
|
|
151
|
+
names, or construct SDK KV keys. Cloudflare bindings belong only at the
|
|
152
|
+
composition root. If a normal feature cannot be expressed through a
|
|
153
|
+
purpose-shaped surface, treat that as a Core abstraction gap instead of
|
|
154
|
+
teaching the project Mantle internals.
|
|
155
|
+
|
|
156
|
+
## Auth Composition
|
|
157
|
+
|
|
158
|
+
Admin is opt-in. A project without `@aotter/mantle-admin-ui` is complete.
|
|
159
|
+
When Admin is installed, `createMantleWorker({ auth })` with `email-otp`
|
|
160
|
+
and `ConsoleEmailSender` is the local human path (OTP in wrangler logs).
|
|
161
|
+
That override owns Auth construction; Core still owns `/admin` and
|
|
162
|
+
`/api/auth/*`. Admin also requires wrangler `assets.directory=./public`
|
|
163
|
+
and an `ASSETS` binding. A white screen at `/admin` with HTML 200 and
|
|
164
|
+
`/_mantle/admin/assets/*` 404 is a missing assets binding, not a missing
|
|
165
|
+
frontend build.
|
|
166
|
+
|
|
167
|
+
Conventional Cloudflare projects that do not replace Auth declare
|
|
168
|
+
`MANTLE_AUTH_MODE=hosted` or `self-managed`; Core owns that standard
|
|
169
|
+
composition and rejects partial or mixed bindings. Preserve the explicit
|
|
170
|
+
mode recorded in Worker config, keep provider secrets out of source, and
|
|
171
|
+
do not infer a mode from whichever credentials happen to be present.
|
|
172
|
+
|
|
173
|
+
## Performance Loop
|
|
174
|
+
|
|
175
|
+
After changing a Schema index, View filter/order, public API, or rendered page,
|
|
176
|
+
run the project's index check when present. Otherwise run the installed
|
|
177
|
+
harness directly:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
pnpm exec mantle-harness indexes --require-public --format text
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The check uses crowded real SQLite and the shipped compiler. It complements
|
|
184
|
+
`pnpm validate`; it does not replace correctness validation. Declare the
|
|
185
|
+
smallest ordered index justified by the measured path and respect SQLite's
|
|
186
|
+
leftmost-prefix rule; which columns an index may name and how a public View's
|
|
187
|
+
status predicate shapes it is in the handbook (`reference/schema.md#indexes`).
|
|
188
|
+
Do not change user-visible filter or ordering semantics
|
|
189
|
+
just to make the gate pass. Do not add every permutation or cache every read.
|
|
190
|
+
|
|
191
|
+
For relevant Cloudflare serving changes, start the project and sample the
|
|
192
|
+
actual routes:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
pnpm exec mantle-harness http \
|
|
196
|
+
--base-url http://127.0.0.1:8787 \
|
|
197
|
+
--route page=/en/example \
|
|
198
|
+
--rounds 20 --warmup 2 --format text
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Prefer query plan, query count, `rows_read` scaling, and cache MISS/HIT
|
|
202
|
+
evidence. Do not create CI gates from absolute local milliseconds.
|
|
203
|
+
|
|
204
|
+
## Loop
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pnpm install --frozen-lockfile
|
|
208
|
+
pnpm validate
|
|
209
|
+
pnpm check:indexes # when the project provides it
|
|
210
|
+
pnpm typecheck
|
|
211
|
+
pnpm check
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Use `pnpm dev` for local preview when the project provides it.
|
|
215
|
+
|
|
216
|
+
## Connect a Local MCP Client
|
|
217
|
+
|
|
218
|
+
Start the project with `pnpm dev`, then use the exact local origin it prints.
|
|
219
|
+
The conventional Cloudflare adapter exposes:
|
|
220
|
+
|
|
221
|
+
- `http://localhost:8787/mcp` for public tools;
|
|
222
|
+
- `http://localhost:8787/mcp/staff` for authenticated authoring tools.
|
|
223
|
+
|
|
224
|
+
Prefer the client's native remote HTTP + OAuth support. Use a standard
|
|
225
|
+
HTTP-to-stdio bridge such as `npx -y mcp-remote <url>` only when the client
|
|
226
|
+
accepts stdio MCP servers but cannot connect to remote HTTP directly. Mantle
|
|
227
|
+
does not own a separate local proxy or an auth-bypass mode.
|
|
228
|
+
|
|
229
|
+
Before changing client config, confirm the Worker is reachable:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
curl -i http://localhost:8787/mcp
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
An OAuth-protected endpoint should respond with `401` and a
|
|
236
|
+
`WWW-Authenticate` resource-metadata challenge before sign-in. After
|
|
237
|
+
connecting, inspect `tools/list`; make one read-only `query_view_*` call when
|
|
238
|
+
available before invoking any mutation. Use project-scoped client config when
|
|
239
|
+
the client offers it, and never commit OAuth tokens or the bridge's token
|
|
240
|
+
cache.
|
|
241
|
+
|
|
242
|
+
## Rules
|
|
243
|
+
|
|
244
|
+
- Keep content models in the configured manifest directory; its immediate
|
|
245
|
+
`.yaml` and `.yml` files are loaded together.
|
|
246
|
+
- Add TypeScript only for handlers, rendering, adapter wiring, or real behavior.
|
|
247
|
+
- Do not write directly to D1, KV, Postgres, or object storage for content
|
|
248
|
+
authoring. Use runtime use cases, admin APIs, or Staff MCP.
|
|
249
|
+
- Do not commit provider secrets.
|
|
250
|
+
- If the work is an installable capability, switch to `mantle:plugin`.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: media-gc
|
|
3
|
+
description: Audit and safely remove stale, uncommitted public media uploads from a Mantle Cloudflare R2 bucket. Use when a Mantle operator asks to inspect or clean orphan media objects left after create_media_upload without commit_media_upload.
|
|
4
|
+
metadata:
|
|
5
|
+
source: "@aotter/mantle"
|
|
6
|
+
sourcePath: docs/skills/media-gc/SKILL.md
|
|
7
|
+
applies_to: mantle grammar v0.1
|
|
8
|
+
projection: package
|
|
9
|
+
projectionReason: Destructive remote object deletion and Cloudflare-specific; opt-in only.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Mantle Media GC
|
|
13
|
+
|
|
14
|
+
Use the connected Cloudflare API. Audit by default; delete only the exact
|
|
15
|
+
objects approved by the user.
|
|
16
|
+
|
|
17
|
+
## Preflight
|
|
18
|
+
|
|
19
|
+
1. Read the project's Wrangler config and Mantle config. Resolve the R2 bucket
|
|
20
|
+
binding, bucket name, and declared public media purpose names.
|
|
21
|
+
2. Confirm the exact Cloudflare account and bucket. If either is ambiguous,
|
|
22
|
+
ask; never choose by name similarity.
|
|
23
|
+
3. Use the Cloudflare OpenAPI search before execution to resolve the current
|
|
24
|
+
R2 List Objects and Delete Objects endpoints. If the connected account lacks
|
|
25
|
+
access, stop. Do not create, request, or store credentials.
|
|
26
|
+
4. Stop when the project has no public R2 media binding or no declared purpose.
|
|
27
|
+
|
|
28
|
+
## Audit
|
|
29
|
+
|
|
30
|
+
For each declared purpose, list up to 1,000 objects per page under the exact
|
|
31
|
+
`<purpose>/` prefix. Use the API cursor until `is_truncated` is false.
|
|
32
|
+
|
|
33
|
+
An object is a deletion candidate only when all conditions hold:
|
|
34
|
+
|
|
35
|
+
- `last_modified` is more than 24 hours old;
|
|
36
|
+
- `custom_metadata.committedAt` is absent or empty;
|
|
37
|
+
- the key matches the exact Mantle layout
|
|
38
|
+
`<purpose>/<group>/(primary|alternate|fallback).(png|jpg|webp|avif|gif|svg)`,
|
|
39
|
+
where `<purpose>` is declared by this project and `<group>` contains only
|
|
40
|
+
letters, digits, `_`, or `-`.
|
|
41
|
+
|
|
42
|
+
Skip committed, unknown-prefix, unprefixed, malformed, or ambiguous objects.
|
|
43
|
+
Delete only an uncommitted variant, never its whole group.
|
|
44
|
+
|
|
45
|
+
Report the account, bucket, purpose prefixes, UTC cutoff, candidate object and
|
|
46
|
+
group counts, total bytes, skipped count, and a SHA-256 digest of the sorted
|
|
47
|
+
`key + etag` candidate set. Do not print object keys, upload group IDs,
|
|
48
|
+
filenames, public URLs, signed URLs, or secrets.
|
|
49
|
+
|
|
50
|
+
## Apply
|
|
51
|
+
|
|
52
|
+
1. Show the audit summary and get explicit confirmation for that exact account,
|
|
53
|
+
bucket, cutoff, count, byte total, and candidate-set digest.
|
|
54
|
+
2. Re-run the complete audit with the same UTC cutoff. If the candidate count,
|
|
55
|
+
bytes, or digest changed, stop and present the new audit for confirmation.
|
|
56
|
+
3. Call Delete Objects with JSON arrays of exact keys, at most 1,000 keys per
|
|
57
|
+
request. Never send the `prefix` query parameter: an empty prefix can empty
|
|
58
|
+
the bucket.
|
|
59
|
+
4. Do not automatically retry failed keys. Report safe API error codes and
|
|
60
|
+
counts; a later invocation can audit and retry what remains.
|
|
61
|
+
5. Re-list every inspected purpose prefix and report the remaining candidate
|
|
62
|
+
count and bytes.
|
|
63
|
+
|
|
64
|
+
## Don't
|
|
65
|
+
|
|
66
|
+
- Don't create a Worker, Cron Trigger, lifecycle rule, D1 table, or local script.
|
|
67
|
+
- Don't use prefix deletion or empty-bucket operations.
|
|
68
|
+
- Don't delete private-media buckets or objects outside declared purpose
|
|
69
|
+
prefixes.
|
|
70
|
+
- Don't treat missing pagination pages, metadata, or permissions as an empty
|
|
71
|
+
result.
|
|
72
|
+
|
|
73
|
+
## Diagnostics
|
|
74
|
+
|
|
75
|
+
| Symptom | Action |
|
|
76
|
+
|---|---|
|
|
77
|
+
| Multiple matching accounts or buckets | Stop and ask the user to select the exact target. |
|
|
78
|
+
| A page is truncated without a cursor | Stop; do not delete from a partial audit. |
|
|
79
|
+
| A candidate has an unexpected key or metadata shape | Skip it and include it only in the aggregate skipped count. |
|
|
80
|
+
| A delete request partially fails | Report safe error codes and leave the remaining objects for a later audit. |
|
|
81
|
+
|
|
82
|
+
## When You're Done
|
|
83
|
+
|
|
84
|
+
Return whether the run was audit-only or applied, the aggregate before/after
|
|
85
|
+
counts and bytes, and any safely redacted failures.
|