@aotter/mantle 0.0.11-alpha.73 → 0.1.0-alpha.10
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 +107 -28
- package/dist/admin.d.ts +2 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +2 -0
- package/dist/admin.js.map +1 -0
- package/dist/bun.d.ts +2 -0
- package/dist/bun.d.ts.map +1 -0
- package/dist/bun.js +2 -0
- package/dist/bun.js.map +1 -0
- package/dist/cli/create.d.ts +2 -0
- package/dist/cli/create.d.ts.map +1 -0
- package/dist/cli/create.js +243 -0
- package/dist/cli/create.js.map +1 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +101 -0
- package/dist/cli/generate.js.map +1 -0
- package/dist/cli/harness.d.ts +3 -0
- package/dist/cli/harness.d.ts.map +1 -0
- package/dist/{harness-cli.js → cli/harness.js} +13 -8
- package/dist/cli/harness.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/{cli.js → cli/main.js} +6 -8
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/skills.d.ts +3 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/{skills.js → cli/skills.js} +51 -6
- package/dist/cli/skills.js.map +1 -0
- package/dist/cli/update.d.ts.map +1 -0
- package/dist/{update.js → cli/update.js} +72 -46
- package/dist/cli/update.js.map +1 -0
- package/dist/codegen/emitMantleModule.d.ts +16 -0
- package/dist/codegen/emitMantleModule.d.ts.map +1 -0
- package/dist/codegen/emitMantleModule.js +217 -0
- package/dist/codegen/emitMantleModule.js.map +1 -0
- package/dist/codegen.d.ts +2 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +2 -0
- package/dist/codegen.js.map +1 -0
- package/dist/provision/renderProvisionBundle.d.ts +70 -0
- package/dist/provision/renderProvisionBundle.d.ts.map +1 -0
- package/dist/provision/renderProvisionBundle.js +367 -0
- package/dist/provision/renderProvisionBundle.js.map +1 -0
- package/dist/provision.d.ts +2 -0
- package/dist/provision.d.ts.map +1 -0
- package/dist/provision.js +2 -0
- package/dist/provision.js.map +1 -0
- package/dist/vercel-libsql.d.ts +2 -0
- package/dist/vercel-libsql.d.ts.map +1 -0
- package/dist/vercel-libsql.js +2 -0
- package/dist/vercel-libsql.js.map +1 -0
- package/dist/vercel.d.ts +2 -0
- package/dist/vercel.d.ts.map +1 -0
- package/dist/vercel.js +2 -0
- package/dist/vercel.js.map +1 -0
- package/dist/web.d.ts +2 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +2 -0
- package/dist/web.js.map +1 -0
- package/docs/adapter-guide.md +95 -51
- package/docs/adr/0001-four-atom-manifest-model.md +48 -307
- package/docs/adr/0002-closed-enums-for-bindings.md +6 -15
- package/docs/adr/0007-ai-as-primary-author.md +6 -4
- package/docs/adr/0008-structured-diagnostic-shape.md +2 -2
- package/docs/adr/0009-consumer-supplied-manifests.md +15 -9
- package/docs/adr/0010-locale-and-translates.md +13 -8
- package/docs/adr/0011-adapter-port-spec.md +39 -43
- package/docs/adr/0012-views-as-public-rest.md +6 -10
- package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +124 -43
- package/docs/adr/0018-core-starters-repository-boundary.md +22 -1
- package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +204 -0
- package/docs/adr/README.md +16 -14
- package/docs/api-mcp-authorization.md +78 -44
- package/docs/assets/mantle-admin-operations.png +0 -0
- package/docs/assets/mantle-hero.jpg +0 -0
- package/docs/auth-hosting-model.md +15 -11
- package/docs/cloudflare-low-level-composition.md +30 -18
- package/docs/deferred-lifecycle-queues.md +20 -41
- package/docs/design-atoms.md +159 -400
- package/docs/labels.md +5 -3
- package/docs/media-uploads.md +9 -2
- package/docs/migration-0.1.2.md +45 -0
- package/docs/performance-harness.md +23 -23
- package/docs/release-process.md +91 -28
- package/docs/schema-indexes.md +1 -1
- package/docs/sealed-pipeline-ownership.md +100 -0
- package/package.json +85 -15
- package/skills/README.md +39 -7
- package/skills/develop/SKILL.md +33 -19
- package/skills/install/SKILL.md +26 -25
- package/skills/media-gc/SKILL.md +85 -0
- package/skills/plugin/SKILL.md +2 -1
- package/skills/provision/SKILL.md +24 -2
- package/skills/theme/SKILL.md +11 -1
- package/skills/update/SKILL.md +1 -0
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/generate.d.ts.map +0 -1
- package/dist/generate.js +0 -181
- package/dist/generate.js.map +0 -1
- package/dist/harness-cli.d.ts +0 -3
- package/dist/harness-cli.d.ts.map +0 -1
- package/dist/harness-cli.js.map +0 -1
- package/dist/skills.d.ts +0 -2
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js.map +0 -1
- package/dist/update.d.ts.map +0 -1
- package/dist/update.js.map +0 -1
- /package/dist/{generate.d.ts → cli/generate.d.ts} +0 -0
- /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.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0-alpha.10",
|
|
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
|
|
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-
|
|
59
|
-
"@aotter/mantle-
|
|
60
|
-
"@aotter/mantle-runtime": "0.0.11-alpha.73",
|
|
61
|
-
"@aotter/mantle-spec": "0.0.11-alpha.73"
|
|
86
|
+
"@aotter/mantle-runtime": "0.1.0-alpha.10",
|
|
87
|
+
"@aotter/mantle-spec": "0.1.0-alpha.10"
|
|
62
88
|
},
|
|
63
89
|
"peerDependencies": {
|
|
64
|
-
"@cloudflare/workers-oauth-provider": "^0.8.0",
|
|
65
90
|
"aws4fetch": "^1.0.20",
|
|
66
|
-
"better-auth": "^1.
|
|
91
|
+
"better-auth": "^1.7.1",
|
|
67
92
|
"hono": "^4.12.0",
|
|
68
|
-
"
|
|
93
|
+
"@libsql/client": "^0.17.4",
|
|
94
|
+
"zod": "^4.0.0",
|
|
95
|
+
"@aotter/mantle-admin": "0.1.0-alpha.10",
|
|
96
|
+
"@aotter/mantle-bun": "0.1.0-alpha.10",
|
|
97
|
+
"@aotter/mantle-admin-ui": "0.1.0-alpha.10",
|
|
98
|
+
"@aotter/mantle-cloudflare": "0.1.0-alpha.10",
|
|
99
|
+
"@aotter/mantle-vercel": "0.1.0-alpha.10",
|
|
100
|
+
"@aotter/mantle-web": "0.1.0-alpha.10"
|
|
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.0",
|
|
72
135
|
"@types/node": "^26",
|
|
73
136
|
"aws4fetch": "^1.0.20",
|
|
74
|
-
"better-auth": "^1.
|
|
75
|
-
"hono": "^4.12.
|
|
137
|
+
"better-auth": "^1.7.1",
|
|
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.
|
|
142
|
+
"zod": "^4.4.3",
|
|
143
|
+
"@aotter/mantle-admin": "0.1.0-alpha.10",
|
|
144
|
+
"@aotter/mantle-admin-ui": "0.1.0-alpha.10",
|
|
145
|
+
"@aotter/mantle-bun": "0.1.0-alpha.10",
|
|
146
|
+
"@aotter/mantle-cloudflare": "0.1.0-alpha.10",
|
|
147
|
+
"@aotter/mantle-web": "0.1.0-alpha.10",
|
|
148
|
+
"@aotter/mantle-vercel": "0.1.0-alpha.10"
|
|
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`.
|
|
20
|
-
|
|
21
|
-
skills
|
|
22
|
-
|
|
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
|
|
41
|
-
repo-root `
|
|
42
|
-
|
|
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
|
|
package/skills/develop/SKILL.md
CHANGED
|
@@ -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
|
|
@@ -16,7 +17,7 @@ docs govern runtime/API behavior.
|
|
|
16
17
|
## First Read
|
|
17
18
|
|
|
18
19
|
1. `package.json` for the installed `@aotter/mantle*` versions.
|
|
19
|
-
2. `manifests
|
|
20
|
+
2. `manifests/site.yaml`, the active adapter config, and `src/auth.ts` when present. If the project is older, check `src/mantleConfig.ts`.
|
|
20
21
|
3. The active `.mantle/overlays/<type>/seed.json`, when present; generated
|
|
21
22
|
homepages commonly import visible copy and form structure from it.
|
|
22
23
|
4. Optional local context: `.mantle/launch-state.json`, `.mantle/handoff.md`,
|
|
@@ -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
|
|
48
|
-
`mantle` authoring CLI from `@aotter/mantle
|
|
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
|
|
@@ -82,9 +84,12 @@ the atoms cannot express the behavior.
|
|
|
82
84
|
`Procedure.spec.input` before the seed/form. Keep public mutation inputs
|
|
83
85
|
`additionalProperties: false`; otherwise JSON Schema's default may strip an
|
|
84
86
|
undeclared field while returning success.
|
|
85
|
-
- Use `lifecycle:
|
|
87
|
+
- Use `lifecycle: operational` for submissions, inquiries, orders, and other
|
|
86
88
|
Procedure-created operational records that staff inspect or correct. Reserve
|
|
87
|
-
`
|
|
89
|
+
`publishing` for content a person stages and publishes.
|
|
90
|
+
- Lifecycle `before_update` / `after_update` hooks also fire for unpublish,
|
|
91
|
+
archive, and every other status transition whose target is not `published`;
|
|
92
|
+
do not use them for edit-only work.
|
|
88
93
|
- When a form's fixed option values change, update the stored Schema and public
|
|
89
94
|
Procedure input `enum` together. Keep translated labels in the page seed;
|
|
90
95
|
Admin and Staff MCP derive their typed controls from the manifest values.
|
|
@@ -98,18 +103,25 @@ the atoms cannot express the behavior.
|
|
|
98
103
|
|
|
99
104
|
- `data.locale` is reserved for `localized: true` Schemas. A non-localized
|
|
100
105
|
Schema must use a domain field such as `replyLocale`.
|
|
106
|
+
- Use a standalone localized Schema only for independent locale rows. For
|
|
107
|
+
versions of one entity, use a non-localized parent plus a localized child
|
|
108
|
+
with `translates: { parent, on }`. The child must own at least one field
|
|
109
|
+
besides `locale` and the join field.
|
|
101
110
|
- Parallel locale blocks must keep field names, option values, step IDs, and
|
|
102
111
|
result keys identical; translate display strings only.
|
|
103
|
-
- `siteDefaults.locales
|
|
104
|
-
|
|
112
|
+
- `siteDefaults.origin`, `siteDefaults.locales`, and `siteDefaults.icons` are
|
|
113
|
+
code-owned and boot-synced. The icon list is shared by browser favicons,
|
|
114
|
+
Admin chrome, and MCP `serverInfo.icons`; keep its static files under
|
|
115
|
+
`public/`. Brand, title, and description seed once, then change through site
|
|
116
|
+
settings.
|
|
105
117
|
- When changing an existing collection from `[slug]` to `[slug, locale]`,
|
|
106
118
|
boot with a Mantle version that reconciles obsolete unique indexes and test
|
|
107
119
|
the same slug in two locales. Do not patch D1 manually.
|
|
108
120
|
|
|
109
121
|
## Adapter Boundary
|
|
110
122
|
|
|
111
|
-
The runtime is adapter-neutral. Required runtime ports are `DatabaseDriver
|
|
112
|
-
|
|
123
|
+
The runtime is adapter-neutral. Required runtime ports are `DatabaseDriver`
|
|
124
|
+
and `AssetServer`. Optional feature ports, such as `MediaStorage`
|
|
113
125
|
or `DeferredHookDispatcher`, are enabled only when the current adapter wires
|
|
114
126
|
them.
|
|
115
127
|
|
|
@@ -127,12 +139,13 @@ teaching the project Mantle internals.
|
|
|
127
139
|
|
|
128
140
|
## Auth Composition
|
|
129
141
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
142
|
+
Conventional Cloudflare projects declare `MANTLE_AUTH_MODE=hosted` or
|
|
143
|
+
`self-managed`; Core owns that standard Auth composition and rejects partial
|
|
144
|
+
or mixed bindings. Preserve the explicit mode recorded in launch state and
|
|
145
|
+
Worker config, keep provider secrets out of source, and do not infer a mode
|
|
146
|
+
from whichever credentials happen to be present. A repo with an explicit
|
|
147
|
+
`createMantleWorker({ auth })` override owns that custom composition; follow
|
|
148
|
+
its handoff instead of replacing it with the conventional factory.
|
|
136
149
|
|
|
137
150
|
## Performance Loop
|
|
138
151
|
|
|
@@ -203,7 +216,8 @@ cache.
|
|
|
203
216
|
|
|
204
217
|
## Rules
|
|
205
218
|
|
|
206
|
-
-
|
|
219
|
+
- Put all content model changes in `manifests/site.yaml`; other manifest
|
|
220
|
+
filenames are rejected.
|
|
207
221
|
- Use a generated overlay `seed.json` for the auth-free local first page when
|
|
208
222
|
it is already imported by `src/web/content/*`.
|
|
209
223
|
- Add TypeScript only for handlers, rendering, adapter wiring, or real behavior.
|
package/skills/install/SKILL.md
CHANGED
|
@@ -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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 `.
|
|
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;
|
|
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.
|
package/skills/plugin/SKILL.md
CHANGED
|
@@ -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
|
|
@@ -49,7 +50,7 @@ stop and ask for the recipe instead of guessing.
|
|
|
49
50
|
## First Read
|
|
50
51
|
|
|
51
52
|
1. `package.json` for Mantle version and adapter package.
|
|
52
|
-
2. `manifests
|
|
53
|
+
2. `manifests/site.yaml` for current atom names and route/tool collisions.
|
|
53
54
|
3. `src/mantle/config.ts` and `src/mantle/handlers/` for registered handlers, templates, and optional ports. Older projects may use `src/mantleConfig.ts`.
|
|
54
55
|
4. `.mantle/plugins.json` and `.mantle/plugins.lock.json` if present.
|
|
55
56
|
5. `.mantle/launch-state.json` only as context, not as plugin authority.
|
|
@@ -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
|
|
@@ -50,6 +52,10 @@ Capture the live URL in `PUBLIC_ORIGIN` and `Public site:` in `AGENTS.md`, then
|
|
|
50
52
|
commit and push non-secret changes. Reuse any repo or Worker already created
|
|
51
53
|
by landing. Workers Builds is optional after a direct deploy.
|
|
52
54
|
|
|
55
|
+
When the owner later adopts a custom domain, update `PUBLIC_ORIGIN` and the
|
|
56
|
+
provider's OAuth callback together, then redeploy. Do not patch `site_config`
|
|
57
|
+
directly; boot syncs its canonical origin from `PUBLIC_ORIGIN`.
|
|
58
|
+
|
|
53
59
|
## Choose Auth
|
|
54
60
|
|
|
55
61
|
- **Self-hosted — free:** configure the owner's per-site GitHub OAuth App and
|
|
@@ -58,6 +64,9 @@ by landing. Workers Builds is optional after a direct deploy.
|
|
|
58
64
|
hosted allocation and client configuration. Mantle Platform operates the
|
|
59
65
|
identity provider; do not ask the user for a per-site GitHub OAuth App.
|
|
60
66
|
|
|
67
|
+
Configure only the selected mode. Core deliberately rejects partial or mixed
|
|
68
|
+
hosted/self-managed bindings with `503 setup_incomplete`.
|
|
69
|
+
|
|
61
70
|
Do not claim that hosted auth can attach to an arbitrary local repo unless the
|
|
62
71
|
current Mantle landing flow explicitly supplies that handoff.
|
|
63
72
|
|
|
@@ -74,11 +83,15 @@ For the exact boundary, read
|
|
|
74
83
|
|
|
75
84
|
2. Put non-secret values in `wrangler.toml`:
|
|
76
85
|
|
|
86
|
+
- `MANTLE_AUTH_MODE = "self-managed"`
|
|
77
87
|
- `PUBLIC_ORIGIN`
|
|
78
88
|
- `GITHUB_CLIENT_ID`
|
|
79
89
|
- `ADMIN_GITHUB_LOGIN`
|
|
80
90
|
- correct Worker `name`
|
|
81
91
|
|
|
92
|
+
Remove `MANTLE_HOSTED_AUTH_ISSUER` and `MANTLE_HOSTED_AUTH_CLIENT_ID` if they
|
|
93
|
+
were present for a hosted allocation.
|
|
94
|
+
|
|
82
95
|
3. Keep the Client Secret out of chat. Prefer a Cloudflare connector for
|
|
83
96
|
secrets; otherwise use hidden shell input:
|
|
84
97
|
|
|
@@ -104,8 +117,17 @@ pnpm deploy
|
|
|
104
117
|
## Hosted Auth
|
|
105
118
|
|
|
106
119
|
Follow the landing handoff and generated client configuration. Hosted
|
|
107
|
-
configuration remains in landing-managed Cloudflare Worker bindings
|
|
108
|
-
|
|
120
|
+
configuration remains in landing-managed Cloudflare Worker bindings. Verify:
|
|
121
|
+
|
|
122
|
+
- `MANTLE_AUTH_MODE = "hosted"`;
|
|
123
|
+
- `MANTLE_HOSTED_AUTH_ISSUER` is the HTTPS root issuer;
|
|
124
|
+
- `MANTLE_HOSTED_AUTH_CLIENT_ID` is the same-origin `/clients/<id>` URL;
|
|
125
|
+
- `PUBLIC_ORIGIN` and `ADMIN_GITHUB_LOGIN` are set;
|
|
126
|
+
- `BETTER_AUTH_SECRET` exists as a Worker secret;
|
|
127
|
+
- `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` are absent.
|
|
128
|
+
|
|
129
|
+
Hosted clients use PKCE and have no client secret. Do not write secrets into
|
|
130
|
+
`wrangler.toml`.
|
|
109
131
|
|
|
110
132
|
Verify that admin sign-in redirects to Mantle Hosted Auth and Staff MCP
|
|
111
133
|
authenticates, then skip the self-hosted flow.
|
package/skills/theme/SKILL.md
CHANGED
|
@@ -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
|
|
@@ -18,7 +19,7 @@ tokens, or recipes, but the skill contract is Core-owned.
|
|
|
18
19
|
2. `styles/`, `components/`, `src/web/`, `src/theme*`, and UI-library config
|
|
19
20
|
if present.
|
|
20
21
|
3. A vendored UI palette's manifest and license, if present.
|
|
21
|
-
4. `manifests
|
|
22
|
+
4. `manifests/site.yaml` to understand which content shape drives the public UI.
|
|
22
23
|
|
|
23
24
|
## Ownership
|
|
24
25
|
|
|
@@ -26,6 +27,11 @@ tokens, or recipes, but the skill contract is Core-owned.
|
|
|
26
27
|
its `:root` and `.dark` values; runtime components inherit those variables.
|
|
27
28
|
- `components/` is the runtime-facing component surface when present.
|
|
28
29
|
`src/web/` is project-owned composition; put new sections there.
|
|
30
|
+
- `public/site-icon.svg` and `public/site-icon.png` are one site identity.
|
|
31
|
+
Keep both listed in `src/mantle/config.ts > siteDefaults.icons`: PNG first as
|
|
32
|
+
the 64x64 compatibility rendition, then SVG as the editable `any` size source.
|
|
33
|
+
The same list drives browser favicons, Admin chrome, and MCP
|
|
34
|
+
`serverInfo.icons`; do not edit generated files under `public/_mantle/`.
|
|
29
35
|
- If the project includes a vendored UI reference palette, treat it as
|
|
30
36
|
offline source material and provenance, not runtime source. Copy only a
|
|
31
37
|
needed primitive or block into the project's runtime directories, or
|
|
@@ -35,6 +41,10 @@ tokens, or recipes, but the skill contract is Core-owned.
|
|
|
35
41
|
## Work
|
|
36
42
|
|
|
37
43
|
- Use existing tokens, CSS, components, and installed dependencies first.
|
|
44
|
+
- When replacing the site mark, regenerate PNG from the same SVG artwork so
|
|
45
|
+
every surface presents the same identity. Check it at the Admin's 28px slot
|
|
46
|
+
in both light and dark themes; a single high-contrast rendition is preferred
|
|
47
|
+
over theme-specific variants unless the artwork genuinely needs both.
|
|
38
48
|
- For a standard hero image, set the section's `image: { src, alt }`; use
|
|
39
49
|
`showImage: false` for text-only hero/content blocks. Put non-image media in
|
|
40
50
|
a project-owned section.
|
package/skills/update/SKILL.md
CHANGED
package/dist/cli.d.ts
DELETED
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"}
|