@aotter/mantle 0.1.3 → 0.1.5-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 +20 -20
- package/dist/cli/generate-cloudflare.d.ts +7 -0
- package/dist/cli/generate-cloudflare.d.ts.map +1 -0
- package/dist/cli/generate-cloudflare.js +123 -0
- package/dist/cli/generate-cloudflare.js.map +1 -0
- package/dist/cli/generate-project.d.ts +25 -0
- package/dist/cli/generate-project.d.ts.map +1 -0
- package/dist/cli/generate-project.js +282 -0
- package/dist/cli/generate-project.js.map +1 -0
- package/dist/cli/generate-sites.d.ts +8 -0
- package/dist/cli/generate-sites.d.ts.map +1 -0
- package/dist/cli/generate-sites.js +273 -0
- package/dist/cli/generate-sites.js.map +1 -0
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +121 -10
- package/dist/cli/generate.js.map +1 -1
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +11 -11
- package/dist/cli/skills.js +1 -1
- package/dist/cli/skills.js.map +1 -1
- package/docs/adr/0001-four-atom-manifest-model.md +3 -2
- package/docs/adr/0013-agent-provisioned-consumer-projects.md +4 -4
- package/docs/adr/0016-site-semantic-layer.md +5 -4
- package/docs/adr/0018-core-starters-repository-boundary.md +1 -1
- package/docs/adr/0021-retire-starter-scaffolding.md +1 -1
- package/docs/adr/0026-progressive-generate.md +36 -0
- package/docs/adr/0027-scheduled-procedure-triggers.md +31 -0
- package/docs/adr/0028-schema-ttl-expiry.md +33 -0
- package/docs/adr/README.md +7 -4
- package/docs/agent-prompts.md +41 -78
- package/docs/assets/mantle-admin-developer.png +0 -0
- package/docs/examples/README.md +1 -1
- package/docs/examples/host-chatgpt-sites/README.md +29 -12
- package/docs/examples/host-chatgpt-sites/drizzle/0003_store_instance_id.sql +1 -0
- package/docs/examples/host-chatgpt-sites/drizzle/0004_mantle.sql +10 -0
- package/docs/examples/host-chatgpt-sites/drizzle/0005_mantle.sql +24 -0
- package/docs/examples/host-chatgpt-sites/drizzle/meta/_journal.json +1 -1
- package/docs/examples/host-chatgpt-sites/drizzle/meta/mantle-state.json +60 -0
- package/docs/examples/host-chatgpt-sites/package.json +1 -1
- package/docs/examples/host-chatgpt-sites/public/site.css +1 -1
- package/docs/examples/host-chatgpt-sites/scripts/build.mjs +2 -1
- package/docs/examples/host-chatgpt-sites/scripts/check.mjs +2 -0
- package/docs/examples/host-chatgpt-sites/scripts/migration.mjs +42 -8
- package/docs/examples/host-chatgpt-sites/src/chatgpt-auth.ts +9 -6
- package/docs/examples/host-chatgpt-sites/src/index.ts +1 -1
- package/docs/examples/host-chatgpt-sites/src/web.ts +1 -1
- package/docs/examples/host-local-admin-otp/package.json +2 -2
- package/docs/examples/host-minimal-worker/README.md +5 -5
- package/docs/examples/host-minimal-worker/package.json +2 -2
- package/docs/handbook/{sites → chatgpt-sites}/equipment-checkout.md +1 -1
- package/docs/handbook/chatgpt-sites/generated-app.md +84 -0
- package/docs/handbook/{sites → chatgpt-sites}/index.md +35 -13
- package/docs/handbook/cloudflare/authentication.md +19 -2
- package/docs/handbook/cloudflare/bindings.md +4 -11
- package/docs/handbook/cloudflare/chatgpt-sites.md +6 -6
- package/docs/handbook/cloudflare/conventional-worker.md +7 -3
- package/docs/handbook/cloudflare/deploy-and-operate.md +4 -3
- package/docs/handbook/cloudflare/media-r2.md +2 -2
- package/docs/handbook/concepts/four-atoms.md +1 -1
- package/docs/handbook/concepts/lifecycle-and-locales.md +1 -1
- package/docs/handbook/concepts/mcp-and-agents.md +24 -4
- package/docs/handbook/concepts/procedures-and-triggers.md +1 -1
- package/docs/handbook/concepts/runtime-and-adapters.md +8 -1
- package/docs/handbook/concepts/views.md +1 -1
- package/docs/handbook/guides/agent-setup.md +8 -7
- package/docs/handbook/navigation.json +7 -6
- package/docs/handbook/reference/diagnostics.md +5 -0
- package/docs/handbook/reference/procedure.md +52 -1
- package/docs/handbook/reference/schema.md +27 -1
- package/docs/handbook/reference/surface.md +3 -3
- package/docs/handbook/reference/trigger.md +21 -1
- package/docs/handbook/releases/index.md +81 -1
- package/docs/handbook/start/overview.md +6 -3
- package/docs/handbook/start/project-and-cli.md +103 -119
- package/docs/handbook/start/quickstart-admin.md +6 -4
- package/docs/handbook/start/quickstart-worker.md +17 -11
- package/docs/release-process.md +3 -2
- package/docs/sealed-pipeline-ownership.md +1 -1
- package/docs/skills/develop/SKILL.md +258 -0
- package/docs/skills/integrate/SKILL.md +60 -0
- package/docs/skills/media-gc/SKILL.md +85 -0
- package/docs/skills/plugin/SKILL.md +132 -0
- package/docs/skills/provision/SKILL.md +194 -0
- package/docs/skills/theme/SKILL.md +77 -0
- package/docs/skills/update/SKILL.md +51 -0
- package/docs/spec-only-host-adoption.md +1 -1
- package/package.json +19 -18
- package/skills/README.md +28 -21
- package/skills/develop/SKILL.md +16 -8
- package/skills/install/SKILL.md +103 -128
- package/skills/integrate/SKILL.md +60 -0
- package/skills/media-gc/SKILL.md +2 -2
- package/skills/plugin/SKILL.md +2 -2
- package/skills/provision/SKILL.md +3 -3
- package/skills/theme/SKILL.md +2 -2
- package/skills/update/SKILL.md +2 -2
- package/templates/chatgpt-sites/auth.ts +66 -0
- package/templates/chatgpt-sites/build.mjs +14 -0
- package/templates/chatgpt-sites/env.ts +1 -0
- package/templates/chatgpt-sites/mcp.ts +48 -0
- package/templates/chatgpt-sites/public-mcp.ts +29 -0
- package/templates/chatgpt-sites/smoke-local.mjs +20 -0
- package/skills/.keep +0 -0
- /package/docs/handbook/{sites → chatgpt-sites}/host-reference.md +0 -0
|
@@ -1,140 +1,124 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: Generate a full Mantle app or select smaller modules, then safely rerun the CLI as your manifests evolve.
|
|
3
3
|
---
|
|
4
|
-
# Project layout and
|
|
4
|
+
# Project layout and CLI
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
`mantle generate` can assemble a new application or compile manifests in an
|
|
7
|
+
existing one. A new hosted app defaults to Spec, Runtime, API, MCP, Admin and
|
|
8
|
+
an editable blank home. You can select a smaller set explicitly. It never
|
|
9
|
+
invents a business Schema or publishes a deployment.
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
## Start a new app
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## You own the project
|
|
15
|
-
|
|
16
|
-
Core is a manifest compiler and a runtime, not a project generator. You write `package.json`, the manifests, the Worker entry, handlers, TypeScript and provider configuration. `mantle generate` compiles what exists; it never initializes a missing project or invents a default Schema, frontend or home route.
|
|
17
|
-
|
|
18
|
-
```txt
|
|
19
|
-
my-service/
|
|
20
|
-
├── package.json exact-pinned @aotter/mantle* + peers, scripts
|
|
21
|
-
├── tsconfig.json includes src/ and .mantle/generated/
|
|
22
|
-
├── wrangler.jsonc Worker name, flags, vars, bindings
|
|
23
|
-
├── .dev.vars local secrets for wrangler dev; never committed
|
|
24
|
-
├── manifests/
|
|
25
|
-
│ └── site.yaml immediate .yaml/.yml files; multi-document with ---
|
|
26
|
-
├── src/
|
|
27
|
-
│ ├── index.ts createMantleWorker({ plan, extend })
|
|
28
|
-
│ └── mantle/handlers/ handler refs (a convention; any path under src/)
|
|
29
|
-
├── public/ required ASSETS root when Admin is installed; generate writes public/_mantle/admin/
|
|
30
|
-
├── .mantle/generated/
|
|
31
|
-
│ └── mantle.ts written by mantle generate
|
|
32
|
-
├── .agents/skills/mantle-*/ written by mantle skills
|
|
33
|
-
└── .claude/skills/mantle-*/ same bytes, for Claude compatibility
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
The minimal Worker reference keeps `.mantle/`, `.agents/`, `.claude/`, `.wrangler/`, `.dev.vars*` and `.env*` out of git and regenerates the first three in its `check` script. Committing the generated files is also workable, because `generate --check` and `skills --check` detect drift either way. Commit the lockfile in a real application and install with `--frozen-lockfile` afterwards.
|
|
37
|
-
|
|
38
|
-
`mantle validate` greps `./src` for the names of `handler.kind: ref` Procedures; a handler that is not found anywhere under `src/` produces a `HANDLER_NOT_REGISTERED` warning, so keep handlers under that root or pass `--source`.
|
|
39
|
-
|
|
40
|
-
## The CLI
|
|
41
|
-
|
|
42
|
-
The umbrella package installs two binaries, `mantle` and `mantle-harness`. Run them through the package manager, for example `pnpm exec mantle generate`. Defaults shown are the pinned ones. Bare `mantle` / `mantle --help` prints a layered overview of optional surfaces (Minimal Spec + generate, Runtime / adapter, opt-in Admin). `generate --help` and `validate --help` stay on the compile path. After a successful `generate`, the CLI says Admin is opt-in: next steps when `@aotter/mantle-admin-ui` is installed, otherwise an API-only tip.
|
|
43
|
-
|
|
44
|
-
| Command | Flags | Does |
|
|
45
|
-
|---|---|---|
|
|
46
|
-
| `mantle generate` | `--manifests <dir>` (default `./manifests`), `-o, --output <dir>` (default `.mantle/generated`), `--namespace <name>` (default `Mantle`), `--check` | Validate, link and compile manifests; write `mantle.ts`; sync Admin assets when installed. `--check` exits 1 without writing when output is stale. |
|
|
47
|
-
| `mantle validate` | `--manifests <dir>`, `--source <dir>` (default `./src`), `--no-source`, `--phase preview\|deploy` (default `preview`), `--format json\|text`, `--json` | Static manifest and handler-source validation. Exit 0 with warnings allowed, 1 on any error, 2 on a CLI invocation problem. |
|
|
48
|
-
| `mantle skills` | `--check` | Copy every skill marked `projection: project` into `.agents/skills/mantle-<name>/` and `.claude/skills/mantle-<name>/`. `--check` exits 1 when a projection is stale. |
|
|
49
|
-
| `mantle emit-openapi` | `--manifests <dir>`, `--title <str>` (default `mantle`), `--version <str>` (default `0.1.0`), `--session-cookie-name <str>`, `-o, --output <file>` | Emit OpenAPI 3.1 for HTTP Triggers and `GET /api/views/<name>` routes to stdout or a file. MCP is out of scope. |
|
|
50
|
-
| `mantle-harness indexes` | `--manifests <dir>`, `--rows <n>` (default 2000), `--require <view>` (repeatable), `--require-public`, `--format text\|json` | Execute compiled Views in crowded SQLite and inspect query plans; exit 1 when a required View lacks its access path. |
|
|
51
|
-
| `mantle-harness http` | `--base-url <url>`, `--route <name=path-or-url>` (repeatable, required), `--rounds <n>` (default 20), `--warmup <n>` (default 2), `--format text\|json` | Sample a running Worker and report p50/p95 timings plus query-count and `rows_read` metric headers. |
|
|
52
|
-
|
|
53
|
-
Advanced manifest primitives live in the `@aotter/mantle-spec` package's own `mantle-spec` binary: `mantle-spec introspect [--manifests <dir>]` dumps the parsed manifest tree as JSON, and `mantle-spec emit-types [--manifests <dir>] [--namespace <name>] [-o <file>]` emits standalone `.d.ts` declarations. Add `@aotter/mantle-spec` as a direct dependency to run them. The full flag reference is in [HTTP, MCP, CLI and packages](../reference/surface.md).
|
|
54
|
-
|
|
55
|
-
### What `generate` does and does not do
|
|
56
|
-
|
|
57
|
-
`generate` reads the manifest directory, runs the same validation as `validate` (without the handler-source grep), links the set, and emits one `.mantle/generated/mantle.ts`. When `@aotter/mantle-admin-ui` is installed it also syncs the **prebuilt** Admin SPA into `public/_mantle/admin/`, excluding the package's `server.*` exports; Core-only installs skip that copy. Any error diagnostic stops the run with exit 1.
|
|
58
|
-
|
|
59
|
-
Do not Vite-build Admin unless you are developing `@aotter/mantle-admin-ui` itself. A Cloudflare project that serves Admin must declare Static Assets:
|
|
13
|
+
Choose a host before running the command. The integrated hosts are `cf` and
|
|
14
|
+
`chatgpt-sites`; `--features spec` works without a host. Install one exact
|
|
15
|
+
published SDK version, then let the CLI declare its matching optional packages:
|
|
60
16
|
|
|
61
|
-
```
|
|
62
|
-
|
|
17
|
+
```sh
|
|
18
|
+
mkdir my-app && cd my-app
|
|
19
|
+
npm init -y
|
|
20
|
+
npm pkg set type=module
|
|
21
|
+
MANTLE_VERSION=$(npm view @aotter/mantle@latest version)
|
|
22
|
+
npm install --save-exact "@aotter/mantle@$MANTLE_VERSION"
|
|
23
|
+
npx mantle generate --host cf
|
|
24
|
+
npm install
|
|
25
|
+
npx mantle generate
|
|
26
|
+
npm run build
|
|
63
27
|
```
|
|
64
28
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
29
|
+
Confirm `MANTLE_VERSION` is a stable release, without a prerelease suffix.
|
|
30
|
+
Use `--host chatgpt-sites` for a Site; [its guide](../chatgpt-sites/generated-app.md)
|
|
31
|
+
continues with D1 migration, owner identity and local smoke. If you already
|
|
32
|
+
use pnpm, keep that one package manager and run `pnpm install` /
|
|
33
|
+
`pnpm exec mantle`. The first `generate` may exit asking you to install newly
|
|
34
|
+
declared packages; the second completes generation. A README or lockfile from
|
|
35
|
+
bootstrapping still counts as a new app. Once choices are saved, omit flags on
|
|
36
|
+
rerun.
|
|
72
37
|
|
|
73
|
-
|
|
74
|
-
|---|---|
|
|
75
|
-
| `plan` | The sealed RuntimePlan with its fingerprint. The conventional Worker imports only this. |
|
|
76
|
-
| `MantleHandlers<Env>` | The handler map type: one typed function per `handler.kind: ref` Procedure, receiving `(input, ctx)`. |
|
|
77
|
-
| `createMantle({ storage, handlers, ports })` | Prepares storage eagerly once and returns the typed binding. No caching or retry. |
|
|
78
|
-
| `bindMantle(runtime)` | The same typed binding over a runtime whose lifecycle the host already owns. |
|
|
79
|
-
|
|
80
|
-
The binding exposes `mantle.views.<lowerCamelName>()`, `mantle.procedures.<name>(input, ctx)`, `mantle.entries.<collection>.createDraft({ data, authorId })`, typed indexed field reads such as `mantle.entries.<collection>.findManyByDataField({ field, value, limit })`, and the underlying `mantle.runtime`. Generated property names are deterministic lower-camel identifiers; calls keep the authored wire names internally. See [Typed queries](../guides/typed-queries.md) for internal Views and entry-reader examples. Details are in [HTTP, MCP, CLI and packages](../reference/surface.md).
|
|
81
|
-
|
|
82
|
-
## The daily loop
|
|
38
|
+
For a smaller composition, list wanted modules positively:
|
|
83
39
|
|
|
84
40
|
```sh
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
pnpm exec mantle generate
|
|
88
|
-
pnpm exec mantle generate --check
|
|
89
|
-
pnpm exec tsc --noEmit
|
|
90
|
-
pnpm test # only when the project declares a test script
|
|
91
|
-
pnpm exec mantle-harness indexes --require-public --format text
|
|
92
|
-
pnpm exec wrangler dev --local
|
|
41
|
+
npx mantle generate --host cf --features spec,api
|
|
42
|
+
npx mantle generate --features spec
|
|
93
43
|
```
|
|
94
44
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
45
|
+
Dependencies are expanded in the saved selection: `api` includes Runtime and
|
|
46
|
+
Spec; `admin` includes Runtime, API and MCP. Supported features are `spec`,
|
|
47
|
+
`runtime`, `api`, `mcp`, `admin`, `web`. No host is needed for Spec-only. Use an
|
|
48
|
+
explicit host in automation so a terminal prompt cannot stall. The selection
|
|
49
|
+
lives in `mantle.config.json`; changing it later requires a deliberate migration,
|
|
50
|
+
not an accidental CLI flag.
|
|
98
51
|
|
|
99
|
-
|
|
52
|
+
## Files and ownership
|
|
100
53
|
|
|
101
|
-
|
|
102
|
-
|
|
54
|
+
| File | Owner | What happens on rerun |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `manifests/*.yaml`, `src/handlers.ts`, `src/home.ts` | You | Preserved. Add domain behavior and edit the blank home here. |
|
|
57
|
+
| `package.json`, `mantle.config.json`, `wrangler.jsonc` | Shared | Required versions and scripts are added; existing user values are preserved or conflicts reported. |
|
|
58
|
+
| `.mantle/generated/*`, `src/storage-fingerprint.json` | CLI | Rebuilt from the saved selection and manifests. |
|
|
59
|
+
| `drizzle/*.sql` on Sites | Review and apply | New migrations append; applied migrations are never rewritten. |
|
|
60
|
+
| `public/_mantle/admin/*` | CLI | Prebuilt Admin assets copied from the selected exact package. |
|
|
61
|
+
| `.openai/hosting.json` on Sites | Sites | Binding metadata is created locally; existing project metadata is preserved. |
|
|
62
|
+
|
|
63
|
+
A generated Worker imports the sealed `plan`, your handler map and the selected
|
|
64
|
+
modules. Generated files carry a marker so the CLI can distinguish them from
|
|
65
|
+
user-owned code. A rerun refuses to replace an unmarked file. Existing
|
|
66
|
+
applications without a saved selection keep their direct-authoring compile
|
|
67
|
+
behavior. For integration into an independently authored application, use the
|
|
68
|
+
installed `docs/skills/integrate/SKILL.md` to choose an embedding, incremental
|
|
69
|
+
replacement or rebuild strategy. Generation does not verify arbitrary host
|
|
70
|
+
entry points or deployment wiring.
|
|
71
|
+
|
|
72
|
+
`generate` accepts `--manifests <dir>` (default `./manifests`), `--output <dir>`
|
|
73
|
+
(default `.mantle/generated`), `--namespace <name>`, `--host cf|chatgpt-sites`,
|
|
74
|
+
`--features <comma-list>` and `--check`. Check mode exits nonzero
|
|
75
|
+
on drift and does not write. Sites also accepts `--review-unique-indexes` for
|
|
76
|
+
an explicit, source-bound unique tuple migration and duplicate preflight;
|
|
77
|
+
[review the D1 procedure](../chatgpt-sites/generated-app.md) before applying
|
|
78
|
+
it. `mantle validate` checks grammar and linked
|
|
79
|
+
capabilities; `--phase deploy` adds deployment checks. `mantle skills` projects
|
|
80
|
+
the installed SDK's project skills into `.agents/skills/` and `.claude/skills/`;
|
|
81
|
+
`mantle skills --check` detects drift. `mantle emit-openapi` describes HTTP
|
|
82
|
+
Triggers and View REST routes; `mantle-harness indexes` and `http` inspect
|
|
83
|
+
queries and running routes. [Command reference](../reference/surface.md).
|
|
84
|
+
|
|
85
|
+
## Verify the assembled app
|
|
103
86
|
|
|
104
87
|
```sh
|
|
105
|
-
|
|
106
|
-
npx
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
# Codex
|
|
113
|
-
codex plugin marketplace add aotter/mantle
|
|
114
|
-
codex plugin add mantle@mantle
|
|
88
|
+
npx mantle generate --check
|
|
89
|
+
npx mantle skills
|
|
90
|
+
npx mantle skills --check
|
|
91
|
+
npm run typecheck
|
|
92
|
+
npm run build
|
|
93
|
+
npm run dev
|
|
115
94
|
```
|
|
116
95
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
96
|
+
Run scripts that exist in the selected project; Spec-only has no server to
|
|
97
|
+
start. Run `npx mantle validate` after adding the first Manifest: the validator
|
|
98
|
+
reports `MANIFEST_ROOT_NOT_FOUND` on an intentionally empty app. A full
|
|
99
|
+
Cloudflare app should serve the blank home and Admin assets.
|
|
100
|
+
For local CF Admin, copy `.dev.vars.example` to `.dev.vars`, replace
|
|
101
|
+
`ADMIN_EMAIL` with the intended owner's address and `BETTER_AUTH_SECRET` with
|
|
102
|
+
a random 32-byte secret, and keep `PUBLIC_ORIGIN` equal to the loopback URL
|
|
103
|
+
wrangler prints. Open `/admin/sign-in` with that email and read the OTP in
|
|
104
|
+
wrangler logs. Check that `/_mantle/admin/assets/*` loads, an anonymous
|
|
105
|
+
`/admin/api/site-settings` request is denied, and the signed-in owner can read
|
|
106
|
+
it. Verify anonymous staff MCP access fails before claiming it works. A full
|
|
107
|
+
Site must also apply its reviewed
|
|
108
|
+
D1 migration before the Worker boots. The public MCP endpoint is discoverable
|
|
109
|
+
without a staff session; the staff endpoint requires the host's verified
|
|
110
|
+
identity and a Mantle role. See [MCP and agents](../concepts/mcp-and-agents.md).
|
|
111
|
+
|
|
112
|
+
For an already installed app, confirm `node_modules/@aotter/mantle/package.json`
|
|
113
|
+
and the lockfile agree. Use that package's CLI and `docs/` tree; the latest
|
|
114
|
+
GitHub handbook may describe a newer release. Keep all selected
|
|
115
|
+
`@aotter/mantle*` packages on one exact version. The prior direct-authoring
|
|
116
|
+
contract remains valid for older installed SDKs; upgrade deliberately using
|
|
117
|
+
[release notes](../releases/index.md).
|
|
125
118
|
|
|
126
119
|
## Source
|
|
127
|
-
|
|
128
|
-
- [
|
|
129
|
-
- [
|
|
130
|
-
- [
|
|
131
|
-
- [
|
|
132
|
-
- [`packages/mantle/src/cli/main.ts`](../../../packages/mantle/src/cli/main.ts)
|
|
133
|
-
- [`packages/mantle/src/cli/generate.ts`](../../../packages/mantle/src/cli/generate.ts)
|
|
134
|
-
- [`packages/mantle/src/cli/skills.ts`](../../../packages/mantle/src/cli/skills.ts)
|
|
135
|
-
- [`packages/mantle/src/cli/harness.ts`](../../../packages/mantle/src/cli/harness.ts)
|
|
136
|
-
- [`packages/mantle/src/codegen/emitMantleModule.ts`](../../../packages/mantle/src/codegen/emitMantleModule.ts)
|
|
137
|
-
- [`packages/mantle-spec/src/infrastructure/cli/ValidateCommand.ts`](../../../packages/mantle-spec/src/infrastructure/cli/ValidateCommand.ts)
|
|
138
|
-
- [`packages/mantle-spec/src/infrastructure/cli/EmitOpenapiCommand.ts`](../../../packages/mantle-spec/src/infrastructure/cli/EmitOpenapiCommand.ts)
|
|
139
|
-
- [`packages/mantle-spec/src/infrastructure/cli/MantleCli.ts`](../../../packages/mantle-spec/src/infrastructure/cli/MantleCli.ts)
|
|
140
|
-
- [`skills/develop/SKILL.md`](../../../skills/develop/SKILL.md)
|
|
120
|
+
|
|
121
|
+
- [Generate CLI](../../../packages/mantle/src/cli/generate.ts)
|
|
122
|
+
- [Project selection and package pins](../../../packages/mantle/src/cli/generate-project.ts)
|
|
123
|
+
- [Cloudflare assembly](../../../packages/mantle/src/cli/generate-cloudflare.ts)
|
|
124
|
+
- [ChatGPT Sites assembly](../../../packages/mantle/src/cli/generate-sites.ts)
|
|
@@ -3,9 +3,11 @@ description: "Open local Admin in one shot: follow the official OTP example, bin
|
|
|
3
3
|
---
|
|
4
4
|
# Quickstart: local Admin
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
New generated CF and Sites apps include Admin by default. To leave it out,
|
|
7
|
+
select smaller features explicitly. This tutorial shows the existing
|
|
8
|
+
direct-authored Worker integration with local email OTP; use it when you own
|
|
9
|
+
the Worker entry. [Project layout and CLI](./project-and-cli.md) describes the
|
|
10
|
+
new generated path.
|
|
9
11
|
|
|
10
12
|
The procedural source of truth is the official example:
|
|
11
13
|
|
|
@@ -29,7 +31,7 @@ Traps (documented on the example):
|
|
|
29
31
|
- `pnpm check` / smoke rewrites `.dev.vars` to a smoke-only port — restore it
|
|
30
32
|
from `.dev.vars.example` before `pnpm dev`.
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Pin every selected `@aotter/mantle*` package to the same exact version; see
|
|
33
35
|
[Versions](../reference/surface.md#versions). Admin needs both
|
|
34
36
|
`@aotter/mantle-admin` and `@aotter/mantle-admin-ui`, wrangler `ASSETS` on
|
|
35
37
|
`./public`, and `createAuth` email-otp + `ConsoleEmailSender`.
|
|
@@ -3,7 +3,13 @@ description: "Author a minimal Cloudflare Worker from scratch: one Schema, one p
|
|
|
3
3
|
---
|
|
4
4
|
# Quickstart: a minimal Worker
|
|
5
5
|
|
|
6
|
-
This page reproduces
|
|
6
|
+
This page reproduces the API-only Worker reference as a direct-authoring
|
|
7
|
+
walkthrough: View REST without Admin, Auth or a visitor frontend. For a new
|
|
8
|
+
project, `mantle generate --host cf --features spec,api` assembles that smaller
|
|
9
|
+
composition. Omit `--features` to include Admin, MCP and a blank home. The
|
|
10
|
+
[local Admin tutorial](./quickstart-admin.md) covers an authored Worker entry.
|
|
11
|
+
Pin every selected `@aotter/mantle*` package to one exact version; see
|
|
12
|
+
[Versions](../reference/surface.md#versions).
|
|
7
13
|
|
|
8
14
|
## Prerequisites
|
|
9
15
|
|
|
@@ -13,10 +19,9 @@ This page reproduces Core's API-only Worker reference as a from-scratch walkthro
|
|
|
13
19
|
|
|
14
20
|
## 1. `package.json`
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
entries are the peers and tools used by this reference.
|
|
22
|
+
Step 5 adds the two Mantle packages at one exact version. For a prerelease
|
|
23
|
+
evaluation, select its exact version explicitly rather than mixing channels.
|
|
24
|
+
The entries below are the peers and tools used by this direct-authored reference.
|
|
20
25
|
|
|
21
26
|
```json
|
|
22
27
|
{
|
|
@@ -31,8 +36,6 @@ entries are the peers and tools used by this reference.
|
|
|
31
36
|
"check": "mantle generate && mantle generate --check && mantle validate && mantle skills && mantle skills --check && tsc --noEmit"
|
|
32
37
|
},
|
|
33
38
|
"dependencies": {
|
|
34
|
-
"@aotter/mantle": "latest",
|
|
35
|
-
"@aotter/mantle-cloudflare": "latest",
|
|
36
39
|
"better-auth": "1.7.2",
|
|
37
40
|
"hono": "^4.13.3",
|
|
38
41
|
"zod": "^4.5.4",
|
|
@@ -172,10 +175,13 @@ curl -i http://127.0.0.1:8787/mcp/staff
|
|
|
172
175
|
- `.mantle/generated/mantle.ts` — one module with the sealed `plan`, generated types (`MantleHandlers<Env>`), `createMantle` and `bindMantle`. The Worker entry above imports only `plan`.
|
|
173
176
|
- `public/_mantle/admin/` — the Admin SPA, synced only when `@aotter/mantle-admin-ui` is installed. This project did not install it, so nothing is written there and `/admin` has no assets.
|
|
174
177
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
This walkthrough uses the existing direct-authored Worker entry; in that legacy
|
|
179
|
+
compile mode, `generate` expects the supplied manifests and does not add a
|
|
180
|
+
home route. New applications can instead use `mantle generate --host cf`
|
|
181
|
+
with `--features spec,api` for a smaller assembled Worker. The CLI never
|
|
182
|
+
invents a Schema. `mantle generate --check` reports stale output without
|
|
183
|
+
writing. The reference keeps `.mantle/`, `.agents/` and `.claude/` out of git
|
|
184
|
+
and regenerates them in `check`; see [Project layout and CLI](./project-and-cli.md).
|
|
179
185
|
|
|
180
186
|
## Next steps
|
|
181
187
|
|
package/docs/release-process.md
CHANGED
|
@@ -110,10 +110,11 @@ dist-tag DELETE only added failure and re-run state, and Actions
|
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
Leave the consumer cold-start entry **untagged**: `npx skills add
|
|
113
|
-
aotter/mantle
|
|
113
|
+
aotter/mantle`, `/plugin marketplace add aotter/mantle`,
|
|
114
114
|
`codex plugin marketplace add aotter/mantle` and the plugin-manifest
|
|
115
115
|
descriptions carry no `@v…` / `--ref`. Untagged resolves to `main`, which
|
|
116
|
-
|
|
116
|
+
normally moves at a release but may contain a source-only hotfix; the
|
|
117
|
+
installed npm package remains the version authority
|
|
117
118
|
(#995, #998). Only "installed version" statements such as
|
|
118
119
|
`(currently \`X.Y.Z\`)` are bumped.
|
|
119
120
|
|
|
@@ -65,7 +65,7 @@ release use `docs/examples/host-minimal-worker` from the same reviewed commit.
|
|
|
65
65
|
Private consumers can still run the exact-tarball checker in their own repos;
|
|
66
66
|
public Core PRs receive no cross-repository credentials:
|
|
67
67
|
|
|
68
|
-
|
|
|
68
|
+
| Historical consumer | Revision | Gate at the time | Manifest paths |
|
|
69
69
|
|---|---|---|---|
|
|
70
70
|
| `aotter/mantle-starters` | `157e8f49e1e25ae1c52c0115f0dd9e8b6017ef0e` | Core CI + release | `blank/manifests/site.yaml`; `overlays/{community,intake,presence,publication,reservation,transaction}/manifests/site.yaml`; `recipes/typed-web/manifests/site.yaml` |
|
|
71
71
|
| `aotter/mantle-landing` | `4381354dd25d5d94f4096cf3e55a4cb9eecbf3ad` | Landing CI + Core release | `manifests/site.yaml` |
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: develop
|
|
3
|
+
description: Work on any Mantle project using the Core SDK contract. Use for manifest, runtime, content model, handler, adapter, validation, and MCP work after a project already exists.
|
|
4
|
+
metadata:
|
|
5
|
+
source: "@aotter/mantle"
|
|
6
|
+
sourcePath: docs/skills/develop/SKILL.md
|
|
7
|
+
applies_to: mantle grammar v0.1
|
|
8
|
+
projection: project
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Mantle Develop
|
|
12
|
+
|
|
13
|
+
This is the Core workflow skill for an existing Mantle project. Repo-local
|
|
14
|
+
copies are byte-for-byte projections from the installed package; its embedded
|
|
15
|
+
docs govern runtime/API behavior.
|
|
16
|
+
|
|
17
|
+
## First Read
|
|
18
|
+
|
|
19
|
+
1. `package.json` for the installed `@aotter/mantle*` versions.
|
|
20
|
+
2. The manifest directory selected by the project scripts, the actual host
|
|
21
|
+
entry and adapter config (for example `wrangler.jsonc` on Cloudflare).
|
|
22
|
+
Read custom Auth construction there when present.
|
|
23
|
+
3. Optional local context: `.mantle/plugins.json`, `.mantle/plugins.lock.json`,
|
|
24
|
+
and `.mantle/recipes/`. Legacy launch/handoff files are context only.
|
|
25
|
+
4. Installed Core docs in `node_modules/@aotter/mantle/docs/`.
|
|
26
|
+
|
|
27
|
+
If `node_modules/` is missing, run `pnpm install --frozen-lockfile` before
|
|
28
|
+
falling back to remote docs. Remote docs must use a tag matching the installed
|
|
29
|
+
version; never use `develop` branch docs for a versioned consumer project.
|
|
30
|
+
|
|
31
|
+
## Existing Examples
|
|
32
|
+
|
|
33
|
+
Read installed `docs/handbook/start/project-and-cli.md` and
|
|
34
|
+
`docs/examples/README.md`. Use `docs/examples/host-minimal-worker/` for Spec +
|
|
35
|
+
adapter without Admin. Read `docs/examples/host-local-admin-otp/` only when the
|
|
36
|
+
project already has Admin or the human asked for Dev UI — that path is opt-in.
|
|
37
|
+
Ingest only `docs/examples/builtin-*.md` Manifests as grammar for new domains.
|
|
38
|
+
Read `docs/examples/cf-primitives-*.md` before inventing Durable Object, Queue,
|
|
39
|
+
cron, or `ref` handler patterns.
|
|
40
|
+
References are test/documentation, not a Starter or a fixed application shape.
|
|
41
|
+
|
|
42
|
+
Public rendering is opt-in consumer wiring: `mountPublicRoutes`, a
|
|
43
|
+
`TemplateRegistry`, and a matching `publicPathResolver` must agree on the
|
|
44
|
+
exposed collections. Do not auto-publish every Schema. Applications document their mounted URL surface in their own README.
|
|
45
|
+
Import the registry and resolver from `@aotter/mantle/web`; Core runtime does
|
|
46
|
+
not install public rendering by itself.
|
|
47
|
+
|
|
48
|
+
## Authoring CLI
|
|
49
|
+
|
|
50
|
+
Use the project's scripts first; applications use the shipping
|
|
51
|
+
`mantle` authoring CLI from `@aotter/mantle`. Ask the installed CLI for its
|
|
52
|
+
command list instead of trusting one copied into prose — the surface is
|
|
53
|
+
version-matched and changes between releases:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pnpm exec mantle --help
|
|
57
|
+
pnpm validate
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
On 0.1.5 and newer, `generate --host cf|chatgpt-sites` assembles a new blank
|
|
61
|
+
app; no `--features` selects Spec, Runtime, API, MCP, Admin and Web. Explicit
|
|
62
|
+
`--features` selects a smaller composition. It never invents a business
|
|
63
|
+
Schema. Existing authored apps keep compile mode, and older installed CLIs
|
|
64
|
+
may not support project generation. Check this project's CLI help first.
|
|
65
|
+
|
|
66
|
+
## Core Model
|
|
67
|
+
|
|
68
|
+
Mantle exposes exactly four declarative atoms:
|
|
69
|
+
|
|
70
|
+
| Atom | Purpose |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `Schema` | Stored entity/table shape. |
|
|
73
|
+
| `View` | Read/query surface. |
|
|
74
|
+
| `Procedure` | Typed mutation or operation. |
|
|
75
|
+
| `Trigger` | HTTP/lifecycle/MCP invocation binding. |
|
|
76
|
+
|
|
77
|
+
Do not invent manifest kinds such as `Form`, `Feature`, `Workflow`, or
|
|
78
|
+
`Membership`. Compose those from the four atoms plus TypeScript only where
|
|
79
|
+
the atoms cannot express the behavior.
|
|
80
|
+
|
|
81
|
+
## Choose the manifest feature first
|
|
82
|
+
|
|
83
|
+
Read installed `docs/handbook/reference/features.md` to map the requested
|
|
84
|
+
behavior to fields before adding handlers or a custom UI. For host-only reads,
|
|
85
|
+
`surface: internal` keeps a View out of REST/MCP/Admin while preserving its
|
|
86
|
+
`requires` checks. Read `docs/handbook/guides/typed-queries.md` for generated
|
|
87
|
+
View params/results, indexed entry reads, and their authorization boundary.
|
|
88
|
+
Use `from` for portable typed projections; SQL is for queries needing native
|
|
89
|
+
SQLite and produces `unknown` row types.
|
|
90
|
+
|
|
91
|
+
For Admin labels, inputs, collection columns/tabs, reports or action buttons,
|
|
92
|
+
read `docs/handbook/guides/admin-ui.md`. Prefer supported Schema/Procedure/View
|
|
93
|
+
metadata and `uiSchema` before custom frontend code. These control the Admin
|
|
94
|
+
console, not the visitor frontend. Regenerate and verify the actual console;
|
|
95
|
+
never edit generated `public/_mantle/admin/` assets.
|
|
96
|
+
|
|
97
|
+
## Content Edits
|
|
98
|
+
|
|
99
|
+
- Follow the actual frontend content source. Use Admin or Staff MCP for
|
|
100
|
+
runtime-backed content. Do not invent an overlay/seed homepage.
|
|
101
|
+
- For a new submitted field, update the stored `Schema` and the public
|
|
102
|
+
`Procedure.spec.input` before any form UI. Keep public mutation inputs
|
|
103
|
+
`additionalProperties: false`; otherwise JSON Schema's default may strip an
|
|
104
|
+
undeclared field while returning success.
|
|
105
|
+
- Use `lifecycle: operational` for submissions, inquiries, orders, and other
|
|
106
|
+
Procedure-created operational records that staff inspect or correct. Reserve
|
|
107
|
+
`publishing` for content a person stages and publishes.
|
|
108
|
+
- Lifecycle `before_update` / `after_update` hooks also fire for unpublish,
|
|
109
|
+
archive, and every other status transition whose target is not `published`;
|
|
110
|
+
do not use them for edit-only work.
|
|
111
|
+
- When a form's fixed option values change, update the stored Schema and public
|
|
112
|
+
Procedure input `enum` together. Keep translated labels in the frontend content source;
|
|
113
|
+
Admin and Staff MCP derive their typed controls from the manifest values.
|
|
114
|
+
- If the application has a `page` Schema with sections, update its declared
|
|
115
|
+
section properties when adding display fields; an undeclared property has no
|
|
116
|
+
runtime-backed Admin or Staff MCP path.
|
|
117
|
+
- Update notification handlers when they need the new field. Test the stored
|
|
118
|
+
entry, not only the HTTP `{ "ok": true }` response.
|
|
119
|
+
|
|
120
|
+
## Locales
|
|
121
|
+
|
|
122
|
+
- `data.locale` is reserved for `localized: true` Schemas. A non-localized
|
|
123
|
+
Schema must use a domain field such as `replyLocale`.
|
|
124
|
+
- Use a standalone localized Schema only for independent locale rows. For
|
|
125
|
+
versions of one entity, use a non-localized parent plus a localized child
|
|
126
|
+
with `translates: { parent, on }`. The child must own at least one field
|
|
127
|
+
besides `locale` and the join field.
|
|
128
|
+
- Parallel locale blocks must keep field names, option values, step IDs, and
|
|
129
|
+
result keys identical; translate display strings only.
|
|
130
|
+
- `siteDefaults.origin`, `siteDefaults.locales`, and `siteDefaults.icons` are
|
|
131
|
+
code-owned and boot-synced. The icon list is shared by browser favicons,
|
|
132
|
+
Admin chrome, and MCP `serverInfo.icons`; keep its static files under
|
|
133
|
+
`public/`. Brand, title, and description seed once, then change through site
|
|
134
|
+
settings.
|
|
135
|
+
- When changing an existing collection from `[slug]` to `[slug, locale]`,
|
|
136
|
+
boot with a Mantle version that reconciles obsolete unique indexes and test
|
|
137
|
+
the same slug in two locales. Do not patch D1 manually.
|
|
138
|
+
|
|
139
|
+
## Adapter Boundary
|
|
140
|
+
|
|
141
|
+
The runtime is adapter-neutral. A `MantleStorageAdapter` prepares the compiled
|
|
142
|
+
plan into semantic storage ports; `createMantleRuntime` binds that prepared
|
|
143
|
+
storage and selected capabilities. Database drivers and asset serving belong
|
|
144
|
+
to the host/optional composition. Follow the installed adapter guide.
|
|
145
|
+
|
|
146
|
+
Do not assume Cloudflare unless the project imports `@aotter/mantle/cloudflare`
|
|
147
|
+
or its adapter config is visible. A future Netlify adapter should satisfy the
|
|
148
|
+
same Core workflow through its own ports and provider setup.
|
|
149
|
+
|
|
150
|
+
Site code is a consumer of this abstraction. Use Manifests, runtime use cases,
|
|
151
|
+
`runtime.entries`, and optional `runtime.siteConfig`; do not query Mantle-owned `entries` or
|
|
152
|
+
`site_config`, reach through deprecated `runtime.db`, copy generated-column
|
|
153
|
+
names, or construct SDK KV keys. Cloudflare bindings belong only at the
|
|
154
|
+
composition root. If a normal feature cannot be expressed through a
|
|
155
|
+
purpose-shaped surface, treat that as a Core abstraction gap instead of
|
|
156
|
+
teaching the project Mantle internals.
|
|
157
|
+
|
|
158
|
+
## Auth Composition
|
|
159
|
+
|
|
160
|
+
Generated full apps select Admin by default; smaller selections can omit it.
|
|
161
|
+
A project without `@aotter/mantle-admin-ui` is complete when Admin was not
|
|
162
|
+
selected. If Admin was selected but its package is missing, install the
|
|
163
|
+
CLI-declared exact version and rerun generation.
|
|
164
|
+
When Admin is installed, `createMantleWorker({ auth })` with `email-otp`
|
|
165
|
+
and `ConsoleEmailSender` is the local human path (OTP in wrangler logs).
|
|
166
|
+
That override owns Auth construction; Core still owns `/admin` and
|
|
167
|
+
`/api/auth/*`. Admin also requires wrangler `assets.directory=./public`
|
|
168
|
+
and an `ASSETS` binding. A white screen at `/admin` with HTML 200 and
|
|
169
|
+
`/_mantle/admin/assets/*` 404 is a missing assets binding, not a missing
|
|
170
|
+
frontend build.
|
|
171
|
+
|
|
172
|
+
Generated Cloudflare apps use `MANTLE_AUTH_MODE=local-otp` on loopback after
|
|
173
|
+
copying `.dev.vars.example` to `.dev.vars` and setting a real owner email and
|
|
174
|
+
random secret. Production uses `hosted` or `self-managed` with provider
|
|
175
|
+
credentials and `ADMIN_GITHUB_LOGIN`. Conventional Cloudflare projects that
|
|
176
|
+
do not replace Auth use those two production modes; Core owns that standard
|
|
177
|
+
composition and rejects partial or mixed bindings. Preserve the explicit
|
|
178
|
+
mode recorded in Worker config, keep provider secrets out of source, and
|
|
179
|
+
do not infer a mode from whichever credentials happen to be present.
|
|
180
|
+
|
|
181
|
+
## Performance Loop
|
|
182
|
+
|
|
183
|
+
After changing a Schema index, View filter/order, public API, or rendered page,
|
|
184
|
+
run the project's index check when present. Otherwise run the installed
|
|
185
|
+
harness directly:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
pnpm exec mantle-harness indexes --require-public --format text
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The check uses crowded real SQLite and the shipped compiler. It complements
|
|
192
|
+
`pnpm validate`; it does not replace correctness validation. Declare the
|
|
193
|
+
smallest ordered index justified by the measured path and respect SQLite's
|
|
194
|
+
leftmost-prefix rule; which columns an index may name and how a public View's
|
|
195
|
+
status predicate shapes it is in the handbook (`reference/schema.md#indexes`).
|
|
196
|
+
Do not change user-visible filter or ordering semantics
|
|
197
|
+
just to make the gate pass. Do not add every permutation or cache every read.
|
|
198
|
+
|
|
199
|
+
For relevant Cloudflare serving changes, start the project and sample the
|
|
200
|
+
actual routes:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pnpm exec mantle-harness http \
|
|
204
|
+
--base-url http://127.0.0.1:8787 \
|
|
205
|
+
--route page=/en/example \
|
|
206
|
+
--rounds 20 --warmup 2 --format text
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Prefer query plan, query count, `rows_read` scaling, and cache MISS/HIT
|
|
210
|
+
evidence. Do not create CI gates from absolute local milliseconds.
|
|
211
|
+
|
|
212
|
+
## Loop
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
pnpm install --frozen-lockfile
|
|
216
|
+
pnpm validate
|
|
217
|
+
pnpm check:indexes # when the project provides it
|
|
218
|
+
pnpm typecheck
|
|
219
|
+
pnpm check
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Use `pnpm dev` for local preview when the project provides it.
|
|
223
|
+
|
|
224
|
+
## Connect a Local MCP Client
|
|
225
|
+
|
|
226
|
+
Start the project with `pnpm dev`, then use the exact local origin it prints.
|
|
227
|
+
The conventional Cloudflare adapter exposes:
|
|
228
|
+
|
|
229
|
+
- `http://localhost:8787/mcp` for public tools;
|
|
230
|
+
- `http://localhost:8787/mcp/staff` for authenticated authoring tools.
|
|
231
|
+
|
|
232
|
+
Prefer the client's native remote HTTP + OAuth support. Use a standard
|
|
233
|
+
HTTP-to-stdio bridge such as `npx -y mcp-remote <url>` only when the client
|
|
234
|
+
accepts stdio MCP servers but cannot connect to remote HTTP directly. Mantle
|
|
235
|
+
does not own a separate local proxy or an auth-bypass mode.
|
|
236
|
+
|
|
237
|
+
Before changing client config, confirm the Worker is reachable:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
curl -i http://localhost:8787/mcp
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
An OAuth-protected endpoint should respond with `401` and a
|
|
244
|
+
`WWW-Authenticate` resource-metadata challenge before sign-in. After
|
|
245
|
+
connecting, inspect `tools/list`; make one read-only `query_view_*` call when
|
|
246
|
+
available before invoking any mutation. Use project-scoped client config when
|
|
247
|
+
the client offers it, and never commit OAuth tokens or the bridge's token
|
|
248
|
+
cache.
|
|
249
|
+
|
|
250
|
+
## Rules
|
|
251
|
+
|
|
252
|
+
- Keep content models in the configured manifest directory; its immediate
|
|
253
|
+
`.yaml` and `.yml` files are loaded together.
|
|
254
|
+
- Add TypeScript only for handlers, rendering, adapter wiring, or real behavior.
|
|
255
|
+
- Do not write directly to D1, KV, Postgres, or object storage for content
|
|
256
|
+
authoring. Use runtime use cases, admin APIs, or Staff MCP.
|
|
257
|
+
- Do not commit provider secrets.
|
|
258
|
+
- If the work is an installable capability, switch to `mantle:plugin`.
|