@aotter/mantle 0.1.0-alpha.6 → 0.1.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +68 -30
  2. package/dist/admin.d.ts +2 -0
  3. package/dist/admin.d.ts.map +1 -0
  4. package/dist/admin.js +2 -0
  5. package/dist/admin.js.map +1 -0
  6. package/dist/bun.d.ts +2 -0
  7. package/dist/bun.d.ts.map +1 -0
  8. package/dist/bun.js +2 -0
  9. package/dist/bun.js.map +1 -0
  10. package/dist/cli/create.d.ts +2 -0
  11. package/dist/cli/create.d.ts.map +1 -0
  12. package/dist/cli/create.js +243 -0
  13. package/dist/cli/create.js.map +1 -0
  14. package/dist/cli/generate.d.ts.map +1 -0
  15. package/dist/cli/generate.js +101 -0
  16. package/dist/cli/generate.js.map +1 -0
  17. package/dist/cli/harness.d.ts +3 -0
  18. package/dist/cli/harness.d.ts.map +1 -0
  19. package/dist/{harness-cli.js → cli/harness.js} +13 -8
  20. package/dist/cli/harness.js.map +1 -0
  21. package/dist/cli/main.d.ts +3 -0
  22. package/dist/cli/main.d.ts.map +1 -0
  23. package/dist/{cli.js → cli/main.js} +6 -8
  24. package/dist/cli/main.js.map +1 -0
  25. package/dist/cli/skills.d.ts +3 -0
  26. package/dist/cli/skills.d.ts.map +1 -0
  27. package/dist/{skills.js → cli/skills.js} +51 -6
  28. package/dist/cli/skills.js.map +1 -0
  29. package/dist/cli/update.d.ts.map +1 -0
  30. package/dist/{update.js → cli/update.js} +72 -46
  31. package/dist/cli/update.js.map +1 -0
  32. package/dist/codegen/emitMantleModule.d.ts +16 -0
  33. package/dist/codegen/emitMantleModule.d.ts.map +1 -0
  34. package/dist/codegen/emitMantleModule.js +217 -0
  35. package/dist/codegen/emitMantleModule.js.map +1 -0
  36. package/dist/codegen.d.ts +2 -0
  37. package/dist/codegen.d.ts.map +1 -0
  38. package/dist/codegen.js +2 -0
  39. package/dist/codegen.js.map +1 -0
  40. package/dist/provision/renderProvisionBundle.d.ts +70 -0
  41. package/dist/provision/renderProvisionBundle.d.ts.map +1 -0
  42. package/dist/provision/renderProvisionBundle.js +367 -0
  43. package/dist/provision/renderProvisionBundle.js.map +1 -0
  44. package/dist/provision.d.ts +2 -0
  45. package/dist/provision.d.ts.map +1 -0
  46. package/dist/provision.js +2 -0
  47. package/dist/provision.js.map +1 -0
  48. package/dist/vercel-libsql.d.ts +2 -0
  49. package/dist/vercel-libsql.d.ts.map +1 -0
  50. package/dist/vercel-libsql.js +2 -0
  51. package/dist/vercel-libsql.js.map +1 -0
  52. package/dist/vercel.d.ts +2 -0
  53. package/dist/vercel.d.ts.map +1 -0
  54. package/dist/vercel.js +2 -0
  55. package/dist/vercel.js.map +1 -0
  56. package/dist/web.d.ts +2 -0
  57. package/dist/web.d.ts.map +1 -0
  58. package/dist/web.js +2 -0
  59. package/dist/web.js.map +1 -0
  60. package/docs/adapter-guide.md +88 -45
  61. package/docs/adr/0001-four-atom-manifest-model.md +11 -3
  62. package/docs/adr/0007-ai-as-primary-author.md +3 -3
  63. package/docs/adr/0009-consumer-supplied-manifests.md +9 -4
  64. package/docs/adr/0011-adapter-port-spec.md +18 -4
  65. package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +111 -6
  66. package/docs/adr/0018-core-starters-repository-boundary.md +22 -1
  67. package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +204 -0
  68. package/docs/adr/README.md +12 -10
  69. package/docs/api-mcp-authorization.md +21 -42
  70. package/docs/assets/mantle-admin-operations.png +0 -0
  71. package/docs/assets/mantle-hero.jpg +0 -0
  72. package/docs/auth-hosting-model.md +5 -5
  73. package/docs/cloudflare-low-level-composition.md +30 -18
  74. package/docs/deferred-lifecycle-queues.md +20 -38
  75. package/docs/design-atoms.md +31 -133
  76. package/docs/labels.md +1 -1
  77. package/docs/media-uploads.md +9 -2
  78. package/docs/migration-0.1.2.md +45 -0
  79. package/docs/performance-harness.md +4 -4
  80. package/docs/release-process.md +72 -22
  81. package/docs/sealed-pipeline-ownership.md +100 -0
  82. package/package.json +84 -14
  83. package/skills/README.md +39 -7
  84. package/skills/develop/SKILL.md +7 -5
  85. package/skills/install/SKILL.md +26 -25
  86. package/skills/media-gc/SKILL.md +85 -0
  87. package/skills/plugin/SKILL.md +1 -0
  88. package/skills/provision/SKILL.md +2 -0
  89. package/skills/theme/SKILL.md +1 -0
  90. package/skills/update/SKILL.md +1 -0
  91. package/dist/cli.d.ts +0 -3
  92. package/dist/cli.d.ts.map +0 -1
  93. package/dist/cli.js.map +0 -1
  94. package/dist/generate.d.ts.map +0 -1
  95. package/dist/generate.js +0 -226
  96. package/dist/generate.js.map +0 -1
  97. package/dist/harness-cli.d.ts +0 -3
  98. package/dist/harness-cli.d.ts.map +0 -1
  99. package/dist/harness-cli.js.map +0 -1
  100. package/dist/skills.d.ts +0 -2
  101. package/dist/skills.d.ts.map +0 -1
  102. package/dist/skills.js.map +0 -1
  103. package/dist/update.d.ts.map +0 -1
  104. package/dist/update.js.map +0 -1
  105. /package/dist/{generate.d.ts → cli/generate.d.ts} +0 -0
  106. /package/dist/{update.d.ts → cli/update.d.ts} +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aotter/mantle",
3
- "version": "0.1.0-alpha.6",
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 and adapter authors.",
3
+ "version": "0.1.0-alpha.8",
4
+ "description": "Embeddable Mantle Core umbrella with Spec and Runtime; Web, Admin, Bun, Vercel, Cloudflare, and Admin UI are optional peer packages.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://mantle.tools/",
7
7
  "repository": {
@@ -14,8 +14,8 @@
14
14
  "main": "./dist/spec.js",
15
15
  "types": "./dist/spec.d.ts",
16
16
  "bin": {
17
- "mantle": "./dist/cli.js",
18
- "mantle-harness": "./dist/harness-cli.js"
17
+ "mantle": "./dist/cli/main.js",
18
+ "mantle-harness": "./dist/cli/harness.js"
19
19
  },
20
20
  "publishConfig": {
21
21
  "access": "public",
@@ -27,6 +27,10 @@
27
27
  "types": "./dist/spec.d.ts",
28
28
  "import": "./dist/spec.js"
29
29
  },
30
+ "./provision": {
31
+ "types": "./dist/provision.d.ts",
32
+ "import": "./dist/provision.js"
33
+ },
30
34
  "./spec": {
31
35
  "types": "./dist/spec.d.ts",
32
36
  "import": "./dist/spec.js"
@@ -39,6 +43,30 @@
39
43
  "types": "./dist/runtime-testing.d.ts",
40
44
  "import": "./dist/runtime-testing.js"
41
45
  },
46
+ "./codegen": {
47
+ "types": "./dist/codegen.d.ts",
48
+ "import": "./dist/codegen.js"
49
+ },
50
+ "./web": {
51
+ "types": "./dist/web.d.ts",
52
+ "import": "./dist/web.js"
53
+ },
54
+ "./admin": {
55
+ "types": "./dist/admin.d.ts",
56
+ "import": "./dist/admin.js"
57
+ },
58
+ "./bun": {
59
+ "types": "./dist/bun.d.ts",
60
+ "import": "./dist/bun.js"
61
+ },
62
+ "./vercel": {
63
+ "types": "./dist/vercel.d.ts",
64
+ "import": "./dist/vercel.js"
65
+ },
66
+ "./vercel/libsql": {
67
+ "types": "./dist/vercel-libsql.d.ts",
68
+ "import": "./dist/vercel-libsql.js"
69
+ },
42
70
  "./cloudflare": {
43
71
  "types": "./dist/cloudflare.d.ts",
44
72
  "import": "./dist/cloudflare.js"
@@ -55,27 +83,69 @@
55
83
  "README.md"
56
84
  ],
57
85
  "dependencies": {
58
- "@aotter/mantle-admin-ui": "0.1.0-alpha.6",
59
- "@aotter/mantle-cloudflare": "0.1.0-alpha.6",
60
- "@aotter/mantle-spec": "0.1.0-alpha.6",
61
- "@aotter/mantle-runtime": "0.1.0-alpha.6"
86
+ "@aotter/mantle-runtime": "0.1.0-alpha.8",
87
+ "@aotter/mantle-spec": "0.1.0-alpha.8"
62
88
  },
63
89
  "peerDependencies": {
64
- "@cloudflare/workers-oauth-provider": "^0.8.2",
65
90
  "aws4fetch": "^1.0.20",
66
- "better-auth": "^1.6.27",
91
+ "better-auth": "^1.7.1",
67
92
  "hono": "^4.12.0",
68
- "zod": "^4.0.0"
93
+ "@libsql/client": "^0.17.4",
94
+ "zod": "^4.0.0",
95
+ "@aotter/mantle-admin": "0.1.0-alpha.8",
96
+ "@aotter/mantle-admin-ui": "0.1.0-alpha.8",
97
+ "@aotter/mantle-bun": "0.1.0-alpha.8",
98
+ "@aotter/mantle-cloudflare": "0.1.0-alpha.8",
99
+ "@aotter/mantle-vercel": "0.1.0-alpha.8",
100
+ "@aotter/mantle-web": "0.1.0-alpha.8"
101
+ },
102
+ "peerDependenciesMeta": {
103
+ "@aotter/mantle-admin": {
104
+ "optional": true
105
+ },
106
+ "@aotter/mantle-admin-ui": {
107
+ "optional": true
108
+ },
109
+ "@aotter/mantle-bun": {
110
+ "optional": true
111
+ },
112
+ "@aotter/mantle-cloudflare": {
113
+ "optional": true
114
+ },
115
+ "@aotter/mantle-vercel": {
116
+ "optional": true
117
+ },
118
+ "@aotter/mantle-web": {
119
+ "optional": true
120
+ },
121
+ "aws4fetch": {
122
+ "optional": true
123
+ },
124
+ "better-auth": {
125
+ "optional": true
126
+ },
127
+ "hono": {
128
+ "optional": true
129
+ },
130
+ "@libsql/client": {
131
+ "optional": true
132
+ }
69
133
  },
70
134
  "devDependencies": {
71
- "@cloudflare/workers-oauth-provider": "^0.8.2",
72
135
  "@types/node": "^26",
73
136
  "aws4fetch": "^1.0.20",
74
- "better-auth": "^1.6.27",
137
+ "better-auth": "^1.7.1",
75
138
  "hono": "^4.12.34",
139
+ "@libsql/client": "^0.17.4",
76
140
  "typescript": "^6.0.3",
77
141
  "vitest": "^4.1.10",
78
- "zod": "^4.4.2"
142
+ "zod": "^4.4.3",
143
+ "@aotter/mantle-admin": "0.1.0-alpha.8",
144
+ "@aotter/mantle-admin-ui": "0.1.0-alpha.8",
145
+ "@aotter/mantle-cloudflare": "0.1.0-alpha.8",
146
+ "@aotter/mantle-bun": "0.1.0-alpha.8",
147
+ "@aotter/mantle-vercel": "0.1.0-alpha.8",
148
+ "@aotter/mantle-web": "0.1.0-alpha.8"
79
149
  },
80
150
  "engines": {
81
151
  "node": ">=22"
package/skills/README.md CHANGED
@@ -5,6 +5,7 @@ Agent-readable skill briefs for consumers of `@aotter/mantle-*`. Discoverable by
5
5
  | Skill | When to invoke |
6
6
  |---|---|
7
7
  | [`develop`](develop/SKILL.md) | `mantle:develop`: Core-owned workflow for manifest, runtime, handler, adapter, validation, and MCP work in any Mantle project. |
8
+ | [`media-gc`](media-gc/SKILL.md) | `mantle:media-gc`: audit or remove stale uncommitted public media objects with the connected Cloudflare API. |
8
9
  | [`plugin`](plugin/SKILL.md) | `mantle:plugin`: Core-owned marketplace workflow for plan-first capability installs across starters and adapters. |
9
10
  | [`theme`](theme/SKILL.md) | `mantle:theme`: Core-owned visual workflow. Reads project context but does not depend on starter-owned skill semantics. |
10
11
  | [`update`](update/SKILL.md) | `mantle:update`: Core-owned drift check workflow for SDK, starter snapshots, and plugin lockfiles. |
@@ -14,12 +15,43 @@ Agent-readable skill briefs for consumers of `@aotter/mantle-*`. Discoverable by
14
15
  The skills target Mantle's v0.1 grammar. The installed package version, not
15
16
  duplicated skill prose, selects the exact runtime and embedded docs.
16
17
 
18
+ ## Disclosure audit
19
+
20
+ Every skill ships as one `SKILL.md` with no reference files, scripts, or
21
+ assets, so nothing is deferred behind a second load. Progressive disclosure
22
+ here is section routing inside one file: the agent reads the entry constraints,
23
+ then only the section its selected path names. `scripts/check-skills.mjs`
24
+ enforces the columns below.
25
+
26
+ | Skill | Routes on | Entry-path constraints (read before acting) | Path-gated sections | Projection | Restricted because |
27
+ |---|---|---|---|---|---|
28
+ | `develop` | existing project; manifest, runtime, handler, adapter, or MCP work | four-atom model; adapter neutrality; no direct D1/KV/Postgres writes; no committed secrets | performance harness; local MCP client; locale rules | project, plugin | — |
29
+ | `plugin` | user wants an installable capability | plan before apply; lock entry is the removal manifest; delete only plugin-owned files and atoms | apply; remove | project, plugin | — |
30
+ | `theme` | brand or visual direction in a generated project | repo-owned theme and UI contracts | — | project, plugin | — |
31
+ | `update` | drift check against SDK, starter, or plugin locks | never blindly overwrite user-owned code | — | project, plugin | — |
32
+ | `install` | new site, or opening an existing generated one | do not use the SDK checkout as the application; no push/deploy/provider config during cold start | create local project; continue existing project | plugin | Creates a new project; nothing to project into an existing one. |
33
+ | `provision` | ship to Cloudflare and finish production auth | secrets never enter source or logs; explicit auth mode | hosted auth; self-managed auth | plugin | Platform-specific deploy that handles production secrets; opt-in only. |
34
+ | `media-gc` | audit or remove stale uncommitted media objects | audit by default; confirm exact account, bucket, cutoff, and candidate digest; re-audit before applying; never prefix-delete; never print keys | apply | plugin | Destructive remote object deletion and Cloudflare-specific; opt-in only. |
35
+
36
+ Deliberately monolithic:
37
+
38
+ - `develop` is the widest file, but its adapter, auth, and data-ownership rules
39
+ constrain every path through it. Splitting them behind routing would let an
40
+ agent reach a write path without them, which is the failure this audit
41
+ exists to prevent.
42
+ - `media-gc` keeps its full audit-confirm-reapply sequence inline for the same
43
+ reason: each safeguard is a precondition of the delete that follows it.
44
+
17
45
  ## Skill authority
18
46
 
19
- The `mantle:*` namespace is owned by `@aotter/mantle`. Run `mantle skills` to
20
- project the installed package's `develop`, `plugin`, `theme`, and `update`
21
- skills to identical `.agent` and `.claude` paths; use `mantle skills --check`
22
- to fail closed on drift. The installed package and
47
+ The `mantle:*` namespace is owned by `@aotter/mantle`. Every skill declares its
48
+ own distribution scope in front matter: `metadata.projection: project` marks a
49
+ skill `mantle skills` should place in a generated project, and a skill that
50
+ withholds `project` must say why. `scripts/check-skills.mjs` holds that
51
+ declaration and the audit table below to each other.
52
+
53
+ Run `mantle skills` to project the installed package's skills into a project;
54
+ use `mantle skills --check` to fail closed on drift. The installed package and
23
55
  `node_modules/@aotter/mantle/docs/` are the single version-matched authority.
24
56
  Starter launch files and plugin recipes are project context, not competing
25
57
  contracts.
@@ -37,9 +69,9 @@ duplicated into the npm package:
37
69
  ## Audience
38
70
 
39
71
  These are written for **AI agents acting on behalf of consumers of mantle**,
40
- not for agents maintaining the Mantle SDK itself. SDK maintainers use the
41
- repo-root `CLAUDE.md` from a source checkout; it is intentionally not shipped
42
- inside the npm package. Two audiences, two artifacts.
72
+ not for contributors maintaining the Mantle SDK itself. SDK contributors use
73
+ the repo-root `CONTRIBUTING.md`; it is intentionally not shipped inside the npm
74
+ package. Two audiences, two artifacts.
43
75
 
44
76
  ## Discoverability
45
77
 
@@ -5,6 +5,7 @@ metadata:
5
5
  source: "@aotter/mantle"
6
6
  sourcePath: skills/develop/SKILL.md
7
7
  applies_to: mantle grammar v0.1
8
+ projection: project, plugin
8
9
  ---
9
10
 
10
11
  # Mantle Develop
@@ -41,18 +42,19 @@ Public rendering is opt-in consumer wiring: `mountPublicRoutes`, a
41
42
  `TemplateRegistry`, and a matching `publicPathResolver` must agree on the
42
43
  exposed collections. Do not auto-publish every Schema. Generated projects list
43
44
  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.
44
47
 
45
48
  ## Authoring CLI
46
49
 
47
- Use the project's scripts first; generated starters expose the shipping
48
- `mantle` authoring CLI from `@aotter/mantle-spec`:
50
+ Use the project's scripts first; generated projects expose 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:
49
54
 
50
55
  ```bash
51
56
  pnpm exec mantle --help
52
57
  pnpm validate
53
- pnpm introspect
54
- pnpm emit-openapi
55
- pnpm emit-types
56
58
  ```
57
59
 
58
60
  This CLI validates and derives artifacts from an existing materialized
@@ -5,6 +5,8 @@ metadata:
5
5
  source: "@aotter/mantle"
6
6
  sourcePath: skills/install/SKILL.md
7
7
  applies_to: mantle grammar v0.1
8
+ projection: plugin
9
+ projectionReason: Creates a new project; nothing to project into an existing one.
8
10
  ---
9
11
 
10
12
  # Mantle Install
@@ -33,35 +35,34 @@ hosted provider flow.
33
35
  | Blog, docs, posts, or editorial site | `publication` |
34
36
  | Catalog or order intent | `transaction` |
35
37
  | Booking or request intent | `reservation` |
36
- | Member or participation intent | `community` |
37
38
 
38
- 2. Choose absolute paths for a temporary starters checkout and a target
39
- directory outside both Mantle repositories. Derive a short project slug,
40
- brand, one-sentence description, and locales from the user's prompt.
41
- Require Node 22+ and pnpm 9+; check `node --version` and `pnpm --version`
42
- before materializing.
39
+ Community and membership types are not released; `create` refuses them. Build
40
+ those on `blank` or the closest released type.
43
41
 
44
- 3. Clone [`aotter/mantle-starters`](https://github.com/aotter/mantle-starters)
45
- into a temporary directory and run its materializer. Use a starters ref
46
- supplied by the user for branch testing. Otherwise use a tag matching the
47
- requested Mantle version; use `develop` only for unreleased work. When the
48
- user supplies a Mantle branch URL for a cold test, use the same branch name
49
- in `mantle-starters` when that branch exists.
42
+ 2. Choose a target directory outside both Mantle repositories; its name
43
+ becomes the project slug. Derive a brand, one-sentence description, and
44
+ locales from the user's prompt. Require Node 22+ and pnpm 9+; check
45
+ `node --version` and `pnpm --version` before creating.
46
+
47
+ 3. Create the project with the Core CLI. It resolves the official immutable
48
+ starter tag for its own version, so no starters checkout is involved:
50
49
 
51
50
  ```bash
52
- git clone --depth 1 --branch <starters-ref> \
53
- https://github.com/aotter/mantle-starters.git <temporary-starters-dir>
54
- pnpm --dir <temporary-starters-dir> materialize <type> \
55
- --out <target-dir> \
56
- --project-name <slug> \
51
+ npx -y @aotter/mantle@alpha create <type> <target-dir> \
57
52
  --brand "<brand>" \
58
53
  --description "<one sentence>" \
59
54
  --locales <comma-separated-locales>
60
55
  ```
61
56
 
62
- The materializer writes the same precomposed `provision-bundles/<type>.json`
63
- used by Mantle landing. Do not manually copy `blank/`, merge overlays, or edit
64
- the generated bundle JSON.
57
+ Pin an exact version (`@aotter/mantle@<version>`) when the user asked for one.
58
+ `create` writes files and stops: it installs nothing, initializes no
59
+ repository, configures no auth, and deploys nothing. It refuses to write into
60
+ a path that already exists, and there is no force flag — choose a new
61
+ directory instead.
62
+
63
+ Do not clone the starters repository, copy `blank/`, merge overlays, or edit a
64
+ provision bundle by hand. The CLI renders the same immutable bundle Mantle
65
+ landing uses.
65
66
 
66
67
  4. For a typed launch, read `.mantle/handoff.md`, the selected overlay's
67
68
  `layout.md`, `seed-prompt.md`, and `seed.json`. Shape the first local page by
@@ -107,7 +108,9 @@ pnpm exec mantle skills --check
107
108
 
108
109
  Then read:
109
110
 
110
- 3. Repo-local Mantle skills under `.agent/skills/` or `.claude/skills/`.
111
+ 3. Repo-local Mantle skills under `.agents/skills/` or `.claude/skills/`. A
112
+ project created before this layout may also carry `.agent/skills/`; read it
113
+ if present, but never write there and never delete it.
111
114
  4. Matching embedded docs under `node_modules/@aotter/mantle/docs/`.
112
115
 
113
116
  Use remote docs only when embedded docs are unavailable, and use a tag matching
@@ -125,14 +128,12 @@ pnpm typecheck
125
128
  ```
126
129
 
127
130
  Inspect the already composed manifest, page, and seed files before changing
128
- them. Use the project's scripts first; generated projects expose:
131
+ them. Use the project's scripts first; ask the installed CLI for its command
132
+ list rather than trusting one copied into prose:
129
133
 
130
134
  ```bash
131
135
  pnpm exec mantle --help
132
136
  pnpm validate
133
- pnpm introspect
134
- pnpm emit-openapi
135
- pnpm emit-types
136
137
  ```
137
138
 
138
139
  ## Production
@@ -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: skills/media-gc/SKILL.md
7
+ applies_to: mantle grammar v0.1
8
+ projection: plugin
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.
@@ -5,6 +5,7 @@ metadata:
5
5
  source: "@aotter/mantle"
6
6
  sourcePath: skills/plugin/SKILL.md
7
7
  applies_to: mantle grammar v0.1
8
+ projection: project, plugin
8
9
  ---
9
10
 
10
11
  # Mantle Plugin
@@ -5,6 +5,8 @@ metadata:
5
5
  source: "@aotter/mantle"
6
6
  sourcePath: skills/provision/SKILL.md
7
7
  applies_to: mantle grammar v0.1
8
+ projection: plugin
9
+ projectionReason: Platform-specific deploy that handles production secrets; opt-in only.
8
10
  ---
9
11
 
10
12
  # Provision a Mantle Project
@@ -5,6 +5,7 @@ metadata:
5
5
  source: "@aotter/mantle"
6
6
  sourcePath: skills/theme/SKILL.md
7
7
  applies_to: mantle grammar v0.1
8
+ projection: project, plugin
8
9
  ---
9
10
 
10
11
  # Mantle Theme
@@ -5,6 +5,7 @@ metadata:
5
5
  source: "@aotter/mantle"
6
6
  sourcePath: skills/update/SKILL.md
7
7
  applies_to: mantle grammar v0.1
8
+ projection: project, plugin
8
9
  ---
9
10
 
10
11
  # Mantle Update
package/dist/cli.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;;;CAYhB,CAAC,CAAC;QACC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,UAAU;YACb,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,UAAU;YACb,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,YAAY;YACf,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,cAAc;YACjB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,KAAK,YAAY;YACf,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B;YACE,MAAM,CAAC,KAAK,CAAC,uBAAuB,OAAO,IAAI,CAAC,CAAC;YACjD,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,IAAI,CACT,CAAC,IAAI,EAAE,EAAE;IACP,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;IACR,MAAM,CAAC,KAAK,CAAC,mBAAmB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3G,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAqBA,wBAAsB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA6C7E"}