@aotter/mantle 0.1.0-alpha.9 → 0.1.2-alpha.1
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 +38 -38
- package/dist/cli/generate.d.ts +10 -1
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +49 -4
- package/dist/cli/generate.js.map +1 -1
- package/dist/cli/main.js +0 -8
- package/dist/cli/main.js.map +1 -1
- package/docs/adapter-guide.md +20 -24
- package/docs/adr/0008-structured-diagnostic-shape.md +7 -2
- package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +100 -0
- package/docs/adr/0018-core-starters-repository-boundary.md +3 -0
- package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +37 -1
- package/docs/adr/0020-builtin-handler-contracts-and-matched-upsert.md +199 -0
- package/docs/adr/0021-retire-starter-scaffolding.md +30 -0
- package/docs/adr/0022-caller-observed-version-occ.md +212 -0
- package/docs/adr/0023-port-failure-contract.md +69 -0
- package/docs/adr/README.md +18 -3
- package/docs/adr/adr-lite-803-request-diagnostics.md +38 -0
- package/docs/adr/adr-lite-808-route-readiness.md +47 -0
- package/docs/adr/adr-lite-809-bounded-public-content.md +71 -0
- package/docs/adr/adr-lite-812-native-parity.md +149 -0
- package/docs/adr/adr-lite-823-home-statistics.md +63 -0
- package/docs/adr/adr-lite-842-mcp-authoring.md +30 -0
- package/docs/adr/adr-lite-861-admin-webmcp.md +42 -0
- package/docs/adr/adr-lite-909-admin-ui-kit.md +37 -0
- package/docs/api-mcp-authorization.md +3 -664
- package/docs/auth-hosting-model.md +4 -4
- package/docs/cloudflare-low-level-composition.md +3 -104
- package/docs/deferred-lifecycle-queues.md +2 -243
- package/docs/design-atoms.md +16 -796
- package/docs/direct-authoring.md +5 -0
- package/docs/examples/minimal-worker/README.md +37 -0
- package/docs/examples/minimal-worker/manifests/site.yaml +25 -0
- package/docs/examples/minimal-worker/package.json +26 -0
- package/docs/examples/minimal-worker/smoke.mjs +23 -0
- package/docs/examples/minimal-worker/src/index.ts +4 -0
- package/docs/examples/minimal-worker/tsconfig.json +17 -0
- package/docs/examples/minimal-worker/wrangler.jsonc +22 -0
- package/docs/handbook/cloudflare/authentication.md +167 -0
- package/docs/handbook/cloudflare/bindings.md +233 -0
- package/docs/handbook/cloudflare/conventional-worker.md +162 -0
- package/docs/handbook/cloudflare/deferred-hooks-queues.md +171 -0
- package/docs/handbook/cloudflare/deploy-and-operate.md +98 -0
- package/docs/handbook/cloudflare/low-level-composition.md +169 -0
- package/docs/handbook/cloudflare/media-r2.md +216 -0
- package/docs/handbook/cloudflare/public-web.md +144 -0
- package/docs/handbook/concepts/authorization.md +116 -0
- package/docs/handbook/concepts/four-atoms.md +173 -0
- package/docs/handbook/concepts/lifecycle-and-locales.md +142 -0
- package/docs/handbook/concepts/mcp-and-agents.md +109 -0
- package/docs/handbook/concepts/procedures-and-triggers.md +221 -0
- package/docs/handbook/concepts/runtime-and-adapters.md +177 -0
- package/docs/handbook/concepts/views.md +183 -0
- package/docs/handbook/examples/commerce-transaction.md +813 -0
- package/docs/handbook/examples/guarded-api.md +427 -0
- package/docs/handbook/examples/intake-form.md +319 -0
- package/docs/handbook/examples/legal-documents.md +218 -0
- package/docs/handbook/examples/procurement-approvals.md +240 -0
- package/docs/handbook/examples/publication.md +240 -0
- package/docs/handbook/examples/reservation.md +220 -0
- package/docs/handbook/navigation.json +63 -0
- package/docs/handbook/reference/authorization.md +295 -0
- package/docs/handbook/reference/diagnostics.md +183 -0
- package/docs/handbook/reference/manifest.md +132 -0
- package/docs/handbook/reference/procedure.md +263 -0
- package/docs/handbook/reference/schema.md +247 -0
- package/docs/handbook/reference/site-config.md +233 -0
- package/docs/handbook/reference/surface.md +207 -0
- package/docs/handbook/reference/trigger.md +193 -0
- package/docs/handbook/reference/view.md +256 -0
- package/docs/handbook/start/project-and-cli.md +122 -0
- package/docs/handbook/start/quickstart-worker.md +193 -0
- package/docs/labels.md +3 -1
- package/docs/media-uploads.md +3 -184
- package/docs/migration-0.1.2.md +34 -1
- package/docs/performance-harness.md +125 -8
- package/docs/release-process.md +85 -231
- package/docs/schema-indexes.md +3 -180
- package/docs/sealed-pipeline-ownership.md +5 -4
- package/docs/spec-only-host-adoption.md +158 -0
- package/docs/transaction-patterns.md +5 -0
- package/package.json +21 -25
- package/skills/README.md +4 -4
- package/skills/develop/SKILL.md +23 -28
- package/skills/install/SKILL.md +55 -147
- package/skills/provision/SKILL.md +4 -3
- package/skills/theme/SKILL.md +6 -6
- package/skills/update/SKILL.md +32 -68
- package/dist/cli/create.d.ts +0 -2
- package/dist/cli/create.d.ts.map +0 -1
- package/dist/cli/create.js +0 -243
- package/dist/cli/create.js.map +0 -1
- package/dist/cli/update.d.ts +0 -2
- package/dist/cli/update.d.ts.map +0 -1
- package/dist/cli/update.js +0 -413
- package/dist/cli/update.js.map +0 -1
- package/dist/provision/renderProvisionBundle.d.ts +0 -70
- package/dist/provision/renderProvisionBundle.d.ts.map +0 -1
- package/dist/provision/renderProvisionBundle.js +0 -367
- package/dist/provision/renderProvisionBundle.js.map +0 -1
- package/dist/provision.d.ts +0 -2
- package/dist/provision.d.ts.map +0 -1
- package/dist/provision.js +0 -2
- package/dist/provision.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ engine built around a 4-atom YAML model (Schema / View / Procedure / Trigger)
|
|
|
5
5
|
where agents write config and the runtime carries the complexity.
|
|
6
6
|
|
|
7
7
|
> Mantle is prerelease software. Use this package's `package.json` as the exact
|
|
8
|
-
> installed version; APIs may change between prereleases until
|
|
8
|
+
> installed version; APIs may change between prereleases until the first stable 0.1.2 release.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -49,18 +49,18 @@ by the application.
|
|
|
49
49
|
The package also installs `mantle` and `mantle-harness`:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
npx -y @aotter/mantle@alpha create <type> <directory>
|
|
53
52
|
pnpm exec mantle generate
|
|
54
53
|
pnpm exec mantle generate --check
|
|
55
54
|
pnpm exec mantle skills
|
|
56
55
|
pnpm exec mantle skills --check
|
|
57
|
-
pnpm exec mantle update --ref <immutable-starter-ref>
|
|
58
56
|
pnpm exec mantle-harness indexes --require-public
|
|
59
57
|
pnpm exec mantle-harness http --base-url http://127.0.0.1:8787 --route page=/en/example
|
|
60
58
|
```
|
|
61
59
|
|
|
62
60
|
`mantle generate` validates and compiles `./manifests/`, then writes one typed
|
|
63
|
-
`.mantle/generated/mantle.ts` module.
|
|
61
|
+
`.mantle/generated/mantle.ts` module. When `@aotter/mantle-admin-ui` is
|
|
62
|
+
installed, it also syncs the Admin SPA to `public/_mantle/admin/` (excluding
|
|
63
|
+
`server.*` package exports). Core-only installs skip that copy. It performs no
|
|
64
64
|
skill sync, package update, styling, provisioning, or deployment.
|
|
65
65
|
The same pure emitter is available from `@aotter/mantle/codegen` when a host
|
|
66
66
|
wants to own parsing and filesystem IO.
|
|
@@ -86,10 +86,9 @@ does not cache or retry. Dynamic and platform hosts can keep their own lifecycle
|
|
|
86
86
|
use generated `bindMantle(runtime)`, or skip code generation and call
|
|
87
87
|
`runtime.executeView({ view: "published-notes" })` directly.
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
tag for the CLI's own version, and refuses to write into an existing path.
|
|
89
|
+
Author the application directly using [the installed guide](docs/handbook/start/project-and-cli.md).
|
|
90
|
+
The CLI has no scaffold/type picker; missing manifests fail without creating
|
|
91
|
+
an application or a visitor home page.
|
|
93
92
|
|
|
94
93
|
`mantle skills` copies every skill the installed package marks
|
|
95
94
|
`projection: project` in its front matter into matching
|
|
@@ -100,15 +99,10 @@ receive identical bytes; `--check` detects drift without writing. An older
|
|
|
100
99
|
project may also carry `.agent/skills/`, which is left untouched. Manifest
|
|
101
100
|
generation never rewrites agent instructions.
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
report carries the only supported metadata migration; review and apply it
|
|
108
|
-
after porting selected upstream changes. Format-versioned bundles use the same
|
|
109
|
-
strict renderer as `mantle create`; an invalid current launch state fails
|
|
110
|
-
instead of producing a guessed diff. Older bundles without `formatVersion`
|
|
111
|
-
retain a read-only compatibility renderer.
|
|
102
|
+
SDK upgrades use the package manager and the version-matched update skill.
|
|
103
|
+
For npm peer-resolution troubleshooting, see [the authoring guide](docs/handbook/start/project-and-cli.md).
|
|
104
|
+
See [0.1.2 migration](docs/migration-0.1.2.md) for removed bundle APIs and how to
|
|
105
|
+
preserve legacy application source and provider configuration.
|
|
112
106
|
|
|
113
107
|
## Conventional Cloudflare Worker
|
|
114
108
|
|
|
@@ -134,7 +128,8 @@ configuration keeps public routes available but returns `503 setup_incomplete`
|
|
|
134
128
|
from Auth-owned private routes. Pass `auth: (env) => Auth` only when the site
|
|
135
129
|
needs to replace this conventional factory; Core still owns the Auth routes.
|
|
136
130
|
The exact bindings and validation rules are in the
|
|
137
|
-
|
|
131
|
+
`node_modules/@aotter/mantle-cloudflare/README.md`, under “Conventional Auth”
|
|
132
|
+
(path relative to the application root).
|
|
138
133
|
|
|
139
134
|
Extensions may add routes but may not replace Core surfaces. These paths are
|
|
140
135
|
reserved:
|
|
@@ -181,22 +176,18 @@ identity reused by browser favicons, Admin chrome, and MCP `serverInfo.icons`;
|
|
|
181
176
|
PNG is the compatibility rendition and SVG remains the editable source.
|
|
182
177
|
|
|
183
178
|
For an uncommon deployment that must own the top-level assembly, use the
|
|
184
|
-
embedded [`docs/cloudflare
|
|
179
|
+
embedded [`docs/handbook/cloudflare/low-level-composition.md`](docs/handbook/cloudflare/low-level-composition.md)
|
|
185
180
|
fixture. It composes the same public primitives without importing package
|
|
186
181
|
internals or rebuilding Mantle's adapters.
|
|
187
182
|
|
|
188
183
|
## Getting started
|
|
189
184
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
[
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
[Mantle landing](https://mantle.tools) uses the same bundles and continues
|
|
197
|
-
through private GitHub repo creation, Cloudflare deployment, and optional paid
|
|
198
|
-
hosted auth. Generated repos project Core-owned `mantle:*` skills from their
|
|
199
|
-
installed package for repo-local use.
|
|
185
|
+
Use the installed install skill and [direct-authoring guide](docs/handbook/start/project-and-cli.md).
|
|
186
|
+
The owner or agent writes the application's manifests, entry and configuration;
|
|
187
|
+
`generate` compiles them and `skills` projects the version-matched instructions.
|
|
188
|
+
The [minimal Worker reference](docs/examples/minimal-worker/README.md) is an
|
|
189
|
+
executable example, not a scaffold command. Legacy Landing/Starters remain on
|
|
190
|
+
alpha.17 and are not required by new applications.
|
|
200
191
|
|
|
201
192
|
## Agent marketplace install
|
|
202
193
|
|
|
@@ -249,16 +240,20 @@ adapter is a port-implementation exercise, not a runtime refactor.
|
|
|
249
240
|
|
|
250
241
|
## Documentation
|
|
251
242
|
|
|
243
|
+
- The handbook is the user documentation and ships inside this npm package:
|
|
244
|
+
`node_modules/@aotter/mantle/docs/handbook/` (start, concepts, Cloudflare
|
|
245
|
+
guides, examples, reference; `navigation.json` lists every page in order).
|
|
246
|
+
The copy in `node_modules` describes the installed release.
|
|
252
247
|
- Embedded docs and agent skills ship inside this npm package for
|
|
253
248
|
generated-site agents:
|
|
254
|
-
- `node_modules/@aotter/mantle/docs/
|
|
255
|
-
- `node_modules/@aotter/mantle/docs/api
|
|
249
|
+
- `node_modules/@aotter/mantle/docs/handbook/reference/manifest.md`
|
|
250
|
+
- `node_modules/@aotter/mantle/docs/handbook/examples/guarded-api.md` (anonymous,
|
|
256
251
|
API-key, paid guard, personal-token, OAuth, REST, and MCP examples)
|
|
257
|
-
- `node_modules/@aotter/mantle/docs/media-
|
|
258
|
-
- `node_modules/@aotter/mantle/docs/deferred-
|
|
252
|
+
- `node_modules/@aotter/mantle/docs/handbook/cloudflare/media-r2.md` (Cloudflare R2 adapter recipe)
|
|
253
|
+
- `node_modules/@aotter/mantle/docs/handbook/cloudflare/deferred-hooks-queues.md` (versioned
|
|
259
254
|
Queue wiring, retry/DLQ, idempotency, and delivery guarantees)
|
|
260
|
-
- `node_modules/@aotter/mantle/docs/schema
|
|
261
|
-
JSON-field indexes
|
|
255
|
+
- `node_modules/@aotter/mantle/docs/handbook/reference/schema.md` (Schema grammar,
|
|
256
|
+
ordered composite JSON-field indexes and the safe Procedure SQL helper)
|
|
262
257
|
- `node_modules/@aotter/mantle/docs/performance-harness.md` (crowded SQLite,
|
|
263
258
|
Wrangler-local D1 origin paths and coding-agent guardrails)
|
|
264
259
|
- `node_modules/@aotter/mantle/docs/adr/`
|
|
@@ -269,9 +264,9 @@ adapter is a port-implementation exercise, not a runtime refactor.
|
|
|
269
264
|
- `node_modules/@aotter/mantle/skills/install/SKILL.md`
|
|
270
265
|
- `node_modules/@aotter/mantle/skills/provision/SKILL.md`
|
|
271
266
|
- [4-atom manifest model (ADR-0001)](docs/adr/0001-four-atom-manifest-model.md)
|
|
272
|
-
- [API and MCP authorization](docs/api
|
|
273
|
-
- [Deferred lifecycle Queues](docs/deferred-
|
|
274
|
-
- [Schema indexes on D1](docs/schema
|
|
267
|
+
- [API and MCP authorization](docs/handbook/examples/guarded-api.md)
|
|
268
|
+
- [Deferred lifecycle Queues](docs/handbook/cloudflare/deferred-hooks-queues.md)
|
|
269
|
+
- [Schema indexes on D1](docs/handbook/reference/schema.md)
|
|
275
270
|
- [Release process](docs/release-process.md)
|
|
276
271
|
- [Source repository](https://github.com/aotter/mantle)
|
|
277
272
|
- [Issues](https://github.com/aotter/mantle/issues)
|
|
@@ -279,3 +274,8 @@ adapter is a port-implementation exercise, not a runtime refactor.
|
|
|
279
274
|
## License
|
|
280
275
|
|
|
281
276
|
Apache-2.0
|
|
277
|
+
|
|
278
|
+
Pure extension routes do not await content preparation. Before an extension
|
|
279
|
+
uses Mantle data or database-backed Auth, await its supplied `getRuntime()`
|
|
280
|
+
(or `ref.get()`). Standard protected routes establish this readiness themselves;
|
|
281
|
+
queue/scheduled handlers continue to use `worker.getRuntime(env)`.
|
package/dist/cli/generate.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/** Test seam for Core-only vs Admin-present installs. */
|
|
2
|
+
export interface GenerateDeps {
|
|
3
|
+
readonly resolveAdminUiIndexHtml?: () => string | null;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Locate the optional Admin SPA. A Core-only install does not have
|
|
7
|
+
* `@aotter/mantle-admin-ui`, so resolution failure is not an error.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveAdminUiIndexHtml(): string | null;
|
|
10
|
+
export declare function runGenerate(rawArgs: readonly string[], deps?: GenerateDeps): Promise<number>;
|
|
2
11
|
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"AAiBA,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACxD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAOvD;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
|
package/dist/cli/generate.js
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
2
3
|
import { dirname, join, resolve } from "node:path";
|
|
3
4
|
import { cwd, stderr, stdout } from "node:process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
4
6
|
import { parseArgs } from "node:util";
|
|
5
7
|
import { ValidateManifestsUseCase } from "@aotter/mantle-spec";
|
|
6
8
|
import { loadManifestsFromRoot } from "@aotter/mantle-spec/cli";
|
|
7
9
|
import { assertMantleNamespace, emitMantleModule } from "../codegen/emitMantleModule.js";
|
|
8
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Locate the optional Admin SPA. A Core-only install does not have
|
|
12
|
+
* `@aotter/mantle-admin-ui`, so resolution failure is not an error.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveAdminUiIndexHtml() {
|
|
15
|
+
try {
|
|
16
|
+
const path = fileURLToPath(import.meta.resolve("@aotter/mantle-admin-ui/index.html"));
|
|
17
|
+
return existsSync(path) ? path : null;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function runGenerate(rawArgs, deps = {}) {
|
|
9
24
|
let options;
|
|
10
25
|
try {
|
|
11
26
|
const parsed = parseGenerateArgs(rawArgs);
|
|
@@ -38,7 +53,13 @@ export async function runGenerate(rawArgs) {
|
|
|
38
53
|
return 1;
|
|
39
54
|
}
|
|
40
55
|
const output = resolve(cwd(), options.output);
|
|
41
|
-
|
|
56
|
+
let stale = !(await syncText(join(output, "mantle.ts"), emitted.source, options.check));
|
|
57
|
+
const adminIndex = (deps.resolveAdminUiIndexHtml ?? resolveAdminUiIndexHtml)();
|
|
58
|
+
if (adminIndex !== null) {
|
|
59
|
+
const adminSource = dirname(adminIndex);
|
|
60
|
+
const adminTarget = resolve(cwd(), "public/_mantle/admin");
|
|
61
|
+
stale = !(await syncAdminAssets(adminSource, adminTarget, options.check)) || stale;
|
|
62
|
+
}
|
|
42
63
|
if (stale && options.check) {
|
|
43
64
|
stderr.write("Mantle generated files are stale; run `mantle generate`.\n");
|
|
44
65
|
return 1;
|
|
@@ -76,7 +97,7 @@ Options:
|
|
|
76
97
|
--manifests <dir> Manifest directory (default: ./manifests)
|
|
77
98
|
-o, --output <dir> Generated root (default: .mantle/generated)
|
|
78
99
|
--namespace <name> Generated type namespace (default: Mantle)
|
|
79
|
-
--check Fail without writing when generated code
|
|
100
|
+
--check Fail without writing when generated code or Admin assets are stale
|
|
80
101
|
-h, --help This help
|
|
81
102
|
`);
|
|
82
103
|
}
|
|
@@ -95,6 +116,30 @@ async function syncText(path, expected, check) {
|
|
|
95
116
|
await writeFile(path, expected, "utf8");
|
|
96
117
|
return true;
|
|
97
118
|
}
|
|
119
|
+
async function syncAdminAssets(source, target, check) {
|
|
120
|
+
const sourceFiles = (await listFiles(source)).filter((path) => !path.startsWith("server."));
|
|
121
|
+
const targetFiles = await listFiles(target).catch(() => []);
|
|
122
|
+
const current = sourceFiles.length === targetFiles.length
|
|
123
|
+
&& sourceFiles.every((path, index) => path === targetFiles[index])
|
|
124
|
+
&& (await Promise.all(sourceFiles.map(async (path) => (await readFile(join(source, path))).equals(await readFile(join(target, path)))))).every(Boolean);
|
|
125
|
+
if (current || check)
|
|
126
|
+
return current;
|
|
127
|
+
await rm(target, { recursive: true, force: true });
|
|
128
|
+
for (const path of sourceFiles) {
|
|
129
|
+
const destination = join(target, path);
|
|
130
|
+
await mkdir(dirname(destination), { recursive: true });
|
|
131
|
+
await writeFile(destination, await readFile(join(source, path)));
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
async function listFiles(root, prefix = "") {
|
|
136
|
+
const entries = await readdir(join(root, prefix), { withFileTypes: true });
|
|
137
|
+
const files = await Promise.all(entries.map((entry) => {
|
|
138
|
+
const path = join(prefix, entry.name);
|
|
139
|
+
return entry.isDirectory() ? listFiles(root, path) : [path];
|
|
140
|
+
}));
|
|
141
|
+
return files.flat().sort();
|
|
142
|
+
}
|
|
98
143
|
function message(error) {
|
|
99
144
|
return error instanceof Error ? error.message : String(error);
|
|
100
145
|
}
|
package/dist/cli/generate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/main.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { argv, stderr, stdout } from "node:process";
|
|
3
3
|
import { runEmitOpenapi, runValidate, } from "@aotter/mantle-spec/cli";
|
|
4
|
-
import { runCreate } from "./create.js";
|
|
5
4
|
import { runGenerate } from "./generate.js";
|
|
6
5
|
import { runSkills } from "./skills.js";
|
|
7
|
-
import { runUpdate } from "./update.js";
|
|
8
6
|
async function main() {
|
|
9
7
|
const command = argv[2];
|
|
10
8
|
if (!command || command === "--help" || command === "-h") {
|
|
@@ -13,10 +11,8 @@ async function main() {
|
|
|
13
11
|
Usage: mantle <subcommand> [options]
|
|
14
12
|
|
|
15
13
|
Subcommands:
|
|
16
|
-
create Materialize a version-matched starter into a new directory
|
|
17
14
|
generate Compile manifests and handler types
|
|
18
15
|
skills Project version-matched Core skills
|
|
19
|
-
update Compare local work with provision bundles
|
|
20
16
|
validate Static manifest + handler-source validation
|
|
21
17
|
emit-openapi Emit OpenAPI 3.1 from Triggers + Views
|
|
22
18
|
`);
|
|
@@ -24,14 +20,10 @@ Subcommands:
|
|
|
24
20
|
}
|
|
25
21
|
const rest = argv.slice(3);
|
|
26
22
|
switch (command) {
|
|
27
|
-
case "create":
|
|
28
|
-
return runCreate(rest);
|
|
29
23
|
case "generate":
|
|
30
24
|
return runGenerate(rest);
|
|
31
25
|
case "skills":
|
|
32
26
|
return runSkills(rest);
|
|
33
|
-
case "update":
|
|
34
|
-
return runUpdate(rest);
|
|
35
27
|
case "validate":
|
|
36
28
|
return runValidate(rest);
|
|
37
29
|
case "emit-openapi":
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,cAAc,EACd,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,cAAc,EACd,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,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;;;;;;;;;CAShB,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,UAAU;YACb,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,cAAc;YACjB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B;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"}
|
package/docs/adapter-guide.md
CHANGED
|
@@ -4,7 +4,7 @@ This guide is the fresh-developer entry point for implementing a new mantle plat
|
|
|
4
4
|
|
|
5
5
|
Read this with [ADR-0019](adr/0019-sealed-manifest-runtime-pipeline.md). The source of truth for TypeScript shapes is `packages/mantle-runtime/src/domain/port/`.
|
|
6
6
|
|
|
7
|
-
Adapter packages live under `packages/adapters/<platform>/` using a plural `adapters` bucket. The npm package names stay unchanged, for example `@aotter/mantle-cloudflare`. Keep adapters in this monorepo until the runtime/spec API is stable enough that coordinated releases across separate repositories would not create version skew for
|
|
7
|
+
Adapter packages live under `packages/adapters/<platform>/` using a plural `adapters` bucket. The npm package names stay unchanged, for example `@aotter/mantle-cloudflare`. Keep adapters in this monorepo until the runtime/spec API is stable enough that coordinated releases across separate repositories would not create version skew for consumers.
|
|
8
8
|
|
|
9
9
|
## Required storage boundary
|
|
10
10
|
|
|
@@ -106,6 +106,15 @@ optional `/libsql` subpath adapts a caller-owned remote Turso/libSQL client to
|
|
|
106
106
|
the canonical SQLite chain; the default entry has no database-vendor policy.
|
|
107
107
|
Vercel's read-only filesystem and writable `/tmp` are never durable state.
|
|
108
108
|
|
|
109
|
+
### Browser IndexedDB embedding
|
|
110
|
+
|
|
111
|
+
`@aotter/mantle-indexeddb` implements the same required semantic storage ports
|
|
112
|
+
over one application-owned IndexedDB database. It keeps browser globals out of
|
|
113
|
+
Runtime Core, supports declarative Views with a documented O(n) collection
|
|
114
|
+
scan, and exposes `deleteDatabase()` only on the concrete adapter. The host owns
|
|
115
|
+
database naming, `navigator.storage` persistence requests, active-runtime
|
|
116
|
+
selection, UI invalidation, and any remote synchronization.
|
|
117
|
+
|
|
109
118
|
## HTTP and MCP surfaces
|
|
110
119
|
|
|
111
120
|
The runtime is a library, not an HTTP server. A new adapter must mount equivalent framework routes:
|
|
@@ -126,7 +135,7 @@ adapter. A narrow adapter extension seam may let consumer code verify its own
|
|
|
126
135
|
API-key or personal-token formats, but credential storage/issuance must not
|
|
127
136
|
become a runtime port. The Cloudflare reference is
|
|
128
137
|
`mount/resolveCaller.ts`; consumer usage is documented in
|
|
129
|
-
[API and MCP authorization](api
|
|
138
|
+
[API and MCP authorization](handbook/examples/guarded-api.md).
|
|
130
139
|
|
|
131
140
|
Minimum HTTP behavior for a full adapter:
|
|
132
141
|
|
|
@@ -134,7 +143,7 @@ Minimum HTTP behavior for a full adapter:
|
|
|
134
143
|
- Route `GET /api/views/<name>` to `runtime.executeView`.
|
|
135
144
|
- Mount admin content APIs with session/role checks before calling runtime content use cases.
|
|
136
145
|
- Serve selected Admin SPA assets through `AdminAssetServer`, with an SPA catchall for client-side routes.
|
|
137
|
-
- Mount public render routes and markdown mirrors when the
|
|
146
|
+
- Mount public render routes and markdown mirrors when the application exposes public pages.
|
|
138
147
|
- Translate runtime diagnostics and validation failures into stable HTTP JSON responses instead of throwing raw errors.
|
|
139
148
|
- Evaluate target auth and dynamic guards through the runtime use cases; do
|
|
140
149
|
not duplicate guard logic in HTTP handlers.
|
|
@@ -152,27 +161,10 @@ its document operations into their own routing and cache conventions.
|
|
|
152
161
|
|
|
153
162
|
### HTTP cache contract
|
|
154
163
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
and
|
|
158
|
-
|
|
159
|
-
CDN cache overrides are removed.
|
|
160
|
-
|
|
161
|
-
`mountPublicRoutes(...)` renders canonical D1 state and opts only successful HTML, markdown,
|
|
162
|
-
`llms.txt`, and sitemap responses into the shared cache with
|
|
163
|
-
`Cache-Control: public, max-age=0, s-maxage=300` and the site-level
|
|
164
|
-
`Cache-Tag: mantle-public`. The top-level policy preserves
|
|
165
|
-
that opt-in only for anonymous `GET`/`HEAD` responses with status 200, explicit
|
|
166
|
-
shared freshness, no request `Cookie` or `Authorization`, and no response
|
|
167
|
-
`Set-Cookie`. It also varies public responses by `Cookie` and `Authorization`.
|
|
168
|
-
|
|
169
|
-
A starter-level Workers Cache may therefore store only responses that still
|
|
170
|
-
meet that exact public contract. It must bypass credentialed/cookie requests
|
|
171
|
-
and must never infer cacheability from a URL prefix. Cache entries remain
|
|
172
|
-
version-local; cross-version caching is outside this contract. Successful
|
|
173
|
-
publishing-content and site-setting mutations purge `mantle-public` through
|
|
174
|
-
Cloudflare's native cache API. Operational records and immutable assets do not
|
|
175
|
-
purge the public render cache.
|
|
164
|
+
Keep responses private by default. For Cloudflare, apply the final policy after
|
|
165
|
+
all routes and preserve only explicit anonymous public opt-in. Follow the
|
|
166
|
+
[public cache contract](handbook/cloudflare/public-web.md#cache-contract) and the
|
|
167
|
+
[performance harness](performance-harness.md#cache-contract) for verification.
|
|
176
168
|
|
|
177
169
|
Minimum auth/MCP behavior:
|
|
178
170
|
|
|
@@ -195,6 +187,10 @@ storage preparation and binding do not accept or require a static asset port.
|
|
|
195
187
|
|
|
196
188
|
## Implementation checklist
|
|
197
189
|
|
|
190
|
+
- [ ] Run `runStorageConformance` from `@aotter/mantle-runtime/testing/storage`
|
|
191
|
+
against a disposable prepared-storage factory. See the
|
|
192
|
+
[Runtime conformance guide](../packages/mantle-runtime/README.md#storage-adapter-conformance)
|
|
193
|
+
for coverage, cleanup, locale setup, and remaining adapter-specific tests.
|
|
198
194
|
- [ ] Implement `MantleStorageAdapter` returning existing semantic ports, or reuse `SqliteMantleStorageAdapter` with an already-owned handle.
|
|
199
195
|
- [ ] Call `bootMantleRuntime()` once per semantic revision, or explicitly prepare before binding.
|
|
200
196
|
- [ ] Mount HTTP Trigger and View REST surfaces.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
**Status:** Carried over from POC v0.0.x; amended for the shipped v0.1
|
|
4
4
|
diagnostic emitters and measured harnesses.
|
|
5
5
|
|
|
6
|
-
**Date:** 2026-04-30 (POC); last amended 2026-08-
|
|
6
|
+
**Date:** 2026-04-30 (POC); last amended 2026-08-31.
|
|
7
7
|
|
|
8
8
|
**Deciders**: phsu
|
|
9
9
|
|
|
@@ -215,8 +215,13 @@ admin SPA and CF Workers could share a CSP-safe path with no
|
|
|
215
215
|
`Function`-constructor codegen. The v0.1.0 rebuild inherits zod
|
|
216
216
|
from day 1 — manifest authoring stays JSON Schema, but the
|
|
217
217
|
runtime validator a manifest author's request body hits is a
|
|
218
|
-
zod schema, produced by
|
|
218
|
+
zod schema, produced by Zod's official `z.fromJSONSchema` importer behind the
|
|
219
|
+
compatibility boundary in
|
|
219
220
|
`@aotter/mantle-spec` (see [`docs/design-atoms.md`](../design-atoms.md) § "Manifest validation — JSON Schema in, zod at runtime").
|
|
221
|
+
Mantle validates its supported keyword/ref policy before import and emits
|
|
222
|
+
`JSON_SCHEMA_UNSUPPORTED`, `JSON_SCHEMA_REF_INVALID`, or
|
|
223
|
+
`JSON_SCHEMA_LIMIT_EXCEEDED`; Zod owns the accepted keywords' validation
|
|
224
|
+
semantics.
|
|
220
225
|
|
|
221
226
|
Concretely, runtime entry validation consumes `ZodError.issues`:
|
|
222
227
|
|
|
@@ -625,3 +625,103 @@ OAuth store and is not renamed by this decision.
|
|
|
625
625
|
This amendment adopts the 2026-07-28 CIMD authorization profile only. Updating
|
|
626
626
|
Mantle's JSON-RPC dispatcher to the complete MCP 2026-07-28 transport revision
|
|
627
627
|
is a separate decision.
|
|
628
|
+
|
|
629
|
+
## 2026-09-07 amendment — shared OAuth surfaces and revocation
|
|
630
|
+
|
|
631
|
+
OAuth product UI is not owned by a runtime adapter. `@aotter/mantle-admin`
|
|
632
|
+
owns `MantleOAuthAuth`, the consent/connected-app view models, and
|
|
633
|
+
`handleMantleOAuth(Request) -> Response | null`; `mountMantleOAuth` is a thin
|
|
634
|
+
Hono bridge. The Cloudflare adapter implements protocol actions using the
|
|
635
|
+
same Better Auth instance and D1. Future adapters reuse this contract, not
|
|
636
|
+
Cloudflare-specific UI glue. The old `mountAuthorize` export remains an alias.
|
|
637
|
+
|
|
638
|
+
`@aotter/mantle-admin-ui` owns the React/shadcn sign-in, consent and connected
|
|
639
|
+
apps surfaces, including i18n, theme and submit state. Auth pages initially
|
|
640
|
+
follow the system theme; the light/dark toggle persists an explicit override.
|
|
641
|
+
Connected apps has an Admin page, but managing one's own grants requires only
|
|
642
|
+
a session, never a staff role. The no-assets HTML fallback uses native forms
|
|
643
|
+
without JavaScript or a second implementation of the Admin design system.
|
|
644
|
+
Both mounts retain same-origin mutation checks and private/no-store responses.
|
|
645
|
+
The consent document's CSP permits only the provider-validated callback
|
|
646
|
+
origin for the browser's form redirect; it never trusts an unsigned query.
|
|
647
|
+
|
|
648
|
+
MCP authorization remains session-bound: the JWT's original Better Auth
|
|
649
|
+
session must still exist and be unexpired. Admin sign-out/session expiration
|
|
650
|
+
therefore also ends that session's MCP access. A refresh token is not an
|
|
651
|
+
independent authorization to bypass this check. Staff roles are still read
|
|
652
|
+
fresh on every protected request.
|
|
653
|
+
|
|
654
|
+
Disconnect is scoped to the authenticated user and the selected client. It
|
|
655
|
+
revokes refresh/opaque access tokens, removes pending authorization codes and
|
|
656
|
+
consent rows, and prevents existing JWTs from becoming valid when the client
|
|
657
|
+
is connected again. The verification-create hook captures the consent row ID
|
|
658
|
+
in Better Auth's existing authorization `referenceId`; Better Auth carries it
|
|
659
|
+
through the authorization code and every refresh rotation. MCP JWTs copy that
|
|
660
|
+
reference into `mantle_consent_id`, which must match the active consent row.
|
|
661
|
+
Never look up a new consent at token mint time: doing so could revive a refresh
|
|
662
|
+
lineage whose insertion raced the revoke batch. Same-second reconnect and a
|
|
663
|
+
delayed old refresh row are required regression cases, not clock delays.
|
|
664
|
+
|
|
665
|
+
MCP mode reserves authorization `referenceId` for this grant identity; future
|
|
666
|
+
curated configuration must not also expose Better Auth's `postLogin` reference
|
|
667
|
+
hooks. MCP access requires a persisted user consent, so `skipConsent` and
|
|
668
|
+
`cachedTrustedClients` must not bypass consent for MCP clients.
|
|
669
|
+
|
|
670
|
+
This alpha hotfix requires existing MCP clients to reconnect once: pre-hotfix
|
|
671
|
+
JWTs without the grant claim are rejected immediately. No account/session reset
|
|
672
|
+
is required. The unshipped watermark migration 0008 is removed; its unused
|
|
673
|
+
table in the phsu development database is harmless and is not queried or
|
|
674
|
+
deleted during deployment.
|
|
675
|
+
|
|
676
|
+
## 2026-09-08 amendment — request security boundaries
|
|
677
|
+
|
|
678
|
+
All Admin session mutations use the existing same-origin guard, including
|
|
679
|
+
same-site sibling origins. Admin HTML forbids framing and is private/no-store.
|
|
680
|
+
The SPA also refuses to render in frames, covering direct static-asset URLs
|
|
681
|
+
that bypass the server mount.
|
|
682
|
+
The Admin/auth mounts cap request bodies at 1 MiB using Hono's body limiter;
|
|
683
|
+
HTTP trigger and MCP dispatchers count streamed JSON bytes before parsing and
|
|
684
|
+
return 413 above the same limit. Media bytes continue through direct uploads.
|
|
685
|
+
This intentionally rejects previously accepted larger control-plane payloads.
|
|
686
|
+
|
|
687
|
+
Cloudflare `createAuth` explicitly enables Better Auth rate limits regardless
|
|
688
|
+
of `NODE_ENV`, including the OAuth provider's anonymous registration limit of
|
|
689
|
+
five requests per minute. Only `CF-Connecting-IP` supplies the client key.
|
|
690
|
+
The upstream memory store limits each isolate; deployments needing a shared
|
|
691
|
+
abuse quota must additionally enforce it at ingress. No D1 migration or new
|
|
692
|
+
runtime platform dependency is introduced.
|
|
693
|
+
|
|
694
|
+
Workers must retain initialization work through `ExecutionContext.waitUntil`
|
|
695
|
+
even when the initial challenge finishes or its client disconnects. Schema
|
|
696
|
+
boot precedes OAuth handling. The adapter's static AsyncLocalStorage seeding
|
|
697
|
+
is a version-pinned Better Auth 1.7.2 integration, with accessor-identity
|
|
698
|
+
regression coverage; it does not replace Better Auth's request context.
|
|
699
|
+
Failed Auth initialization evicts only the failed Worker assembly so a later
|
|
700
|
+
request can retry. Non-HTTP callers await Auth initialization with runtime boot;
|
|
701
|
+
HTTP requests anchor it without making public responses depend on Auth health.
|
|
702
|
+
|
|
703
|
+
The conventional `/favicon.ico` reflects the configured site icon, but is a
|
|
704
|
+
fallback after consumer routes, not a newly reserved namespace. Existing
|
|
705
|
+
consumer icon routes must continue to work after a package update.
|
|
706
|
+
|
|
707
|
+
## Amendment — 2026-09-14: Host-only control-plane cookies
|
|
708
|
+
|
|
709
|
+
`CreateAuthConfig.hostOnlyCookies` is an opt-in, curated auth field for a
|
|
710
|
+
control plane on a parent domain shared with tenants. It uses native `__Host-`
|
|
711
|
+
cookie names, `Secure`, `Path=/` and no `Domain`; HTTPS is required and enabling
|
|
712
|
+
cross-subdomain sharing at the same time is rejected. Existing defaults and
|
|
713
|
+
Apple's `SameSite=None` requirement remain unchanged. Consumers must treat
|
|
714
|
+
switching cookie names as an explicit sign-in migration, not rewrite request
|
|
715
|
+
or response cookies. This keeps cookie semantics in the auth adapter rather
|
|
716
|
+
than requiring each consumer to wrap Admin, member and OAuth routes.
|
|
717
|
+
|
|
718
|
+
## Amendment — 2026-09-16: deployment KV session reads
|
|
719
|
+
|
|
720
|
+
Cloudflare deployments may pass their deployment-owned KV namespace as
|
|
721
|
+
`CreateAuthConfig.sessionCacheKv`. Better Auth reads sessions from KV while
|
|
722
|
+
keeping the canonical session row in D1. OTP verification remains D1-backed
|
|
723
|
+
and rate limiting remains isolate-local because Workers KV does not provide
|
|
724
|
+
the atomic consume or increment operations those paths require. Auth keys use
|
|
725
|
+
the `better-auth:` prefix so the namespace can also hold Mantle projections.
|
|
726
|
+
Session revocation and user updates use Better Auth's cache invalidation and
|
|
727
|
+
therefore follow Workers KV's propagation model.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# ADR-0018: Keep Core and public starters in separate repositories
|
|
2
2
|
|
|
3
|
+
> Superseded for 0.1.2 by [ADR-0021](0021-retire-starter-scaffolding.md).
|
|
4
|
+
> The contract below is retained as alpha.17 history, not current launch/release guidance.
|
|
5
|
+
|
|
3
6
|
**Status:** Accepted for now; revisit only under the triggers below
|
|
4
7
|
|
|
5
8
|
**Date:** 2026-08-02
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
**Status:** Accepted
|
|
4
4
|
|
|
5
|
-
**Date:** 2026-08-16
|
|
5
|
+
**Date:** 2026-08-16; last amended 2026-09-01
|
|
6
6
|
|
|
7
7
|
**Related:** [#656](https://github.com/aotter/mantle/issues/656),
|
|
8
8
|
[#662](https://github.com/aotter/mantle/issues/662),
|
|
9
|
+
[#759](https://github.com/aotter/mantle/issues/759),
|
|
10
|
+
[#760](https://github.com/aotter/mantle/issues/760),
|
|
9
11
|
[#546](https://github.com/aotter/mantle/issues/546), ADR-0008, ADR-0009,
|
|
10
12
|
ADR-0011, ADR-0018
|
|
11
13
|
|
|
@@ -106,11 +108,45 @@ Concrete D1/SQLite drivers and SQL repositories remain implementation details.
|
|
|
106
108
|
An existing application may either pass its already-owned database/client to
|
|
107
109
|
an official adapter or implement the semantic ports over its own tables.
|
|
108
110
|
|
|
111
|
+
`@aotter/mantle-indexeddb` is the optional browser storage implementation of
|
|
112
|
+
the same semantic ports. One adapter exclusively owns one application-selected
|
|
113
|
+
database name, uses structured-clone persistence and IndexedDB transaction
|
|
114
|
+
completion as its write boundary, and exposes database deletion only on the
|
|
115
|
+
concrete adapter. Runtime Core gains no browser global, browser facade,
|
|
116
|
+
namespace, persistence request, reactive binding, or synchronization port.
|
|
117
|
+
Declarative browser Views use a documented O(n) scan until measured use proves
|
|
118
|
+
an IndexedDB query planner necessary.
|
|
119
|
+
|
|
109
120
|
Declarative Views compile to logical plans once. Storage preparation lowers
|
|
110
121
|
those plans to native queries. The v0.1 `View.spec.sql` form remains explicitly
|
|
111
122
|
SQLite-only and is rejected by unsupported storage during preparation; Mantle
|
|
112
123
|
does not guess a translation and does not add a universal query driver.
|
|
113
124
|
|
|
125
|
+
### Callable capability projection
|
|
126
|
+
|
|
127
|
+
Optional callable transports consume `projectCallableCapabilities(RuntimePlan)`.
|
|
128
|
+
Each Procedure capability retains the owning MCP Trigger name while its
|
|
129
|
+
input/output/title/description remain owned by the target Procedure; View
|
|
130
|
+
capabilities retain their read-only View contract. Discovery and invocation use
|
|
131
|
+
the same projected descriptor, and invocation routes through `invokeTrigger`
|
|
132
|
+
rather than bypassing Trigger identity with a direct Procedure call. Hosts may
|
|
133
|
+
select a surface and bind transport or browser lifecycle, but do not rescan raw
|
|
134
|
+
manifests or maintain a second registry.
|
|
135
|
+
|
|
136
|
+
`@aotter/mantle-web/webmcp` is an opt-in host binding over that projection. It
|
|
137
|
+
feature-detects `document.modelContext`, adds public capabilities without
|
|
138
|
+
replacing existing host tools, and uses the registration `AbortSignal` only for
|
|
139
|
+
teardown. A browser-local host supplies the projected capabilities and a
|
|
140
|
+
late-bound invoker; Procedure calls retain their explicit MCP Trigger identity.
|
|
141
|
+
For a server-backed host, the Cloudflare adapter publishes a minimal public View
|
|
142
|
+
catalog at `GET /api/views`; the binding validates that wire catalog and invokes
|
|
143
|
+
the existing same-origin `GET /api/views/<name>` route. The catalog contains no
|
|
144
|
+
raw manifest or staff capability.
|
|
145
|
+
Invocation hooks may drive host UI effects but cannot replace Runtime
|
|
146
|
+
validation, authorization, dispatch, or domain results. The binding does not
|
|
147
|
+
add browser globals to Runtime Core, expose staff capabilities, or introduce a
|
|
148
|
+
second manifest/runtime path.
|
|
149
|
+
|
|
114
150
|
### Naming and code generation
|
|
115
151
|
|
|
116
152
|
The Core execution unit is `MantleRuntime`, not a site. Optional TypeScript
|