@aotter/mantle 0.1.3-alpha.6 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/main.d.ts +1 -1
  3. package/dist/cli/main.d.ts.map +1 -1
  4. package/dist/cli/main.js +3 -1
  5. package/dist/cli/main.js.map +1 -1
  6. package/dist/cli/skills.js +1 -1
  7. package/dist/cli/skills.js.map +1 -1
  8. package/docs/agent-prompts.md +6 -5
  9. package/docs/consumer-onboarding-audit.md +65 -0
  10. package/docs/handbook/cloudflare/authentication.md +16 -0
  11. package/docs/handbook/concepts/mcp-and-agents.md +1 -1
  12. package/docs/handbook/concepts/runtime-and-adapters.md +1 -1
  13. package/docs/handbook/concepts/views.md +8 -7
  14. package/docs/handbook/guides/admin-ui.md +135 -0
  15. package/docs/handbook/guides/agent-setup.md +96 -0
  16. package/docs/handbook/guides/typed-queries.md +161 -0
  17. package/docs/handbook/navigation.json +24 -14
  18. package/docs/handbook/reference/features.md +55 -0
  19. package/docs/handbook/reference/manifest.md +3 -1
  20. package/docs/handbook/reference/schema.md +1 -1
  21. package/docs/handbook/reference/surface.md +1 -1
  22. package/docs/handbook/reference/view.md +4 -2
  23. package/docs/handbook/releases/index.md +45 -1
  24. package/docs/handbook/start/overview.md +52 -0
  25. package/docs/handbook/start/project-and-cli.md +2 -2
  26. package/docs/handbook/start/quickstart-worker.md +8 -3
  27. package/docs/spec-only-host-adoption.md +1 -1
  28. package/package.json +17 -17
  29. package/skills/README.md +5 -1
  30. package/skills/develop/SKILL.md +19 -2
  31. package/skills/install/SKILL.md +23 -3
  32. package/skills/plugin/SKILL.md +17 -5
  33. package/skills/theme/SKILL.md +8 -1
  34. package/skills/update/SKILL.md +7 -2
@@ -0,0 +1,161 @@
1
+ ---
2
+ description: Generate and call typed Views, including internal-only queries, and choose indexed entry readers without confusing them with authorized public reads.
3
+ ---
4
+ # Query from TypeScript
5
+
6
+ Use a **View** when a read needs declared params, projection, pagination or
7
+ `requires` authorization. Use an **entry reader** for trusted host code that
8
+ needs stored entries by a data field. Both are exposed by generated bindings;
9
+ only the View executes the declared View authorization contract.
10
+
11
+ ## Declare an internal query
12
+
13
+ Save this complete source as `manifests/tickets.yaml`. The operational Schema
14
+ uses a business status field distinct from Mantle's native `status`.
15
+
16
+ ```yaml
17
+ apiVersion: cms.mantle.aotter.net/v1
18
+ kind: Schema
19
+ metadata:
20
+ name: tickets
21
+ spec:
22
+ title: Tickets
23
+ lifecycle: operational
24
+ schema:
25
+ type: object
26
+ additionalProperties: false
27
+ required: [subject, ticketState]
28
+ properties:
29
+ subject: { type: string }
30
+ ticketState: { type: string, enum: [open, closed] }
31
+ indexes: [[ticketState]]
32
+ ---
33
+ apiVersion: cms.mantle.aotter.net/v1
34
+ kind: View
35
+ metadata:
36
+ name: tickets-by-state
37
+ spec:
38
+ surface: internal
39
+ from: tickets
40
+ fields: [id, subject, ticketState]
41
+ filter:
42
+ eq: { field: ticketState, value: { $param: ticketState } }
43
+ params:
44
+ type: object
45
+ additionalProperties: false
46
+ required: [ticketState]
47
+ properties:
48
+ ticketState: { type: string, enum: [open, closed] }
49
+ limit: 50
50
+ ```
51
+
52
+ ```sh
53
+ pnpm exec mantle validate --no-source
54
+ pnpm exec mantle generate
55
+ pnpm exec mantle generate --check
56
+ ```
57
+
58
+ `internal` keeps this query out of REST routes, OpenAPI, MCP/WebMCP catalogs and
59
+ Admin reports. It remains in the plan and generated binding. It is not a
60
+ security bypass: adding `requires` evaluates the same authorization and guards
61
+ against the host-supplied `ctx` on every call. No `uiSchema` or shared HTTP
62
+ cache is allowed for an internal View.
63
+
64
+ ## Bind and call
65
+
66
+ When the host already owns a prepared Runtime, bind it once where you need the
67
+ typed API. This function can live in `src/queries.ts`:
68
+
69
+ ```ts
70
+ import type { MantleRuntime } from "@aotter/mantle/runtime";
71
+ import { bindMantle } from "../.mantle/generated/mantle.js";
72
+
73
+ export async function openTickets(runtime: MantleRuntime) {
74
+ const mantle = bindMantle(runtime);
75
+ const result = await mantle.views.ticketsByState({
76
+ params: { ticketState: "open" },
77
+ page: 1,
78
+ show: 20,
79
+ });
80
+ if (!result.ok) throw new Error(result.diagnostic.message);
81
+ return result.result.rows;
82
+ }
83
+ ```
84
+
85
+ The runtime response uses `result` on success (`result.result.rows` above);
86
+ REST wraps those rows under `data` instead.
87
+
88
+ The wire name `tickets-by-state` becomes `ticketsByState`. Required params
89
+ make the request and `params` mandatory; invalid enum values are TypeScript
90
+ errors, and Runtime also validates actual inputs. `show` remains capped by
91
+ `limit`. For an authorized View, pass the verified caller context as `ctx`;
92
+ do not fabricate staff/user identities from request input.
93
+
94
+ A host without a Runtime can use generated `createMantle({ storage, handlers,
95
+ ports })`, which delegates one eager boot attempt and returns the typed
96
+ binding. Host code still owns connection lifetime and retries. See
97
+ [Runtime and adapters](../concepts/runtime-and-adapters.md).
98
+
99
+ ## What is typed
100
+
101
+ | Query form | Generated shape | Limit |
102
+ |---|---|---|
103
+ | Declarative View | `Mantle.ViewParams_<name>` and `Mantle.ViewRow_<name>` | Projection follows `fields`; native columns have their native types. Data properties remain optional in the row type. |
104
+ | SQL View | Typed params; row type `unknown` | The generator does not infer SQL expressions or aliases. Narrow/validate rows in host code. |
105
+ | Entry field reader | `MantleEntry<Mantle.Entry_<schema>>` | The field must be a declared data property and the value a compatible string, number or boolean. Types do not prove an index exists. |
106
+ | Dynamic Runtime call | `runtime.executeView({ view, ctx, options })` | Useful without codegen; supplying a generic row type is the caller's assertion, not SQL validation. |
107
+
108
+ Without `fields`, a declarative View includes native entry columns and Schema
109
+ properties. Use explicit projections on exposed reads. Public declarative
110
+ Views over publishing Schemas inject `status = published`; internal/staff
111
+ Views and SQL statements do not. See [View reference](../reference/view.md).
112
+
113
+ ## Indexed entry reads
114
+
115
+ For the Schema above:
116
+
117
+ ```ts
118
+ const rows = await mantle.entries.tickets.findManyByDataField({
119
+ field: "ticketState",
120
+ value: "open",
121
+ limit: 20,
122
+ });
123
+ // rows[n].data is the generated tickets data shape.
124
+ ```
125
+
126
+ | Method | Returns | Options worth knowing |
127
+ |---|---|---|
128
+ | `readBySlug({ slug, locale?, status? })` | One entry or `null` | Use on a Schema with a slug field and an appropriate index. |
129
+ | `readByDataField({ field, value, locale?, status? })` | One entry or `null` | Equality on one data property. |
130
+ | `readByDataFieldIn({ field, values, latestPerValue?, locale?, status? })` | Entry array | Batch equality lookups; `latestPerValue` selects the newest match per value. |
131
+ | `findManyByDataField({ field, value, limit })` | Entry array | Bounded equality lookup across statuses; no `ctx`, `status` or `locale` option. |
132
+
133
+ These readers do not evaluate View `requires`, inject public visibility or
134
+ fire mutation hooks. In particular, `findManyByDataField` can return drafts.
135
+ Use a public View for untrusted callers; do not expose a raw reader as a public
136
+ route and assume the generated type authorizes it. Declare a measured index
137
+ whose leftmost field matches the lookup; do not scan an entire collection in
138
+ TypeScript to replace a field query.
139
+
140
+ ## Generate from an existing plan
141
+
142
+ A build tool that already compiled a sealed plan can use the pure emitter:
143
+
144
+ ```ts
145
+ import { emitMantleModule } from "@aotter/mantle/codegen";
146
+
147
+ const emitted = emitMantleModule({ plan });
148
+ if (!emitted.ok) throw new Error(emitted.diagnostics.map(d => d.message).join("\n"));
149
+ // Write emitted.source to your generated module in the build step.
150
+ ```
151
+
152
+ Pass either `{ plan }` or `{ linked }`, never both. The plan form avoids
153
+ reparsing YAML and preserves the same generated types and entry/View/Procedure
154
+ bindings. The emitter does no I/O, asset copying, storage preparation or caching.
155
+
156
+ ## Source
157
+
158
+ - [Binding generator](../../../packages/mantle/src/codegen/emitMantleModule.ts)
159
+ - [Type generator](../../../packages/mantle-spec/src/usecase/EmitTypesUseCase.ts)
160
+ - [Entry reader contract](../../../packages/mantle-runtime/src/domain/port/EntryReader.ts)
161
+ - [View execution](../../../packages/mantle-runtime/src/usecase/view/ExecuteViewUseCase.ts)
@@ -4,12 +4,21 @@
4
4
  {
5
5
  "text": "Start here",
6
6
  "items": [
7
+ { "text": "Handbook overview", "link": "/start/overview" },
7
8
  { "text": "Project layout and the CLI loop", "link": "/start/project-and-cli" },
8
9
  { "text": "Quickstart: a minimal Worker", "link": "/start/quickstart-worker" },
9
10
  { "text": "Quickstart: local Admin (opt-in)", "link": "/start/quickstart-admin" },
10
11
  { "text": "When the host is ChatGPT Sites", "link": "/sites/index" }
11
12
  ]
12
13
  },
14
+ {
15
+ "text": "Task guides",
16
+ "items": [
17
+ { "text": "Agent installation and handoff", "link": "/guides/agent-setup" },
18
+ { "text": "Typed queries and internal Views", "link": "/guides/typed-queries" },
19
+ { "text": "Customize Admin from manifests", "link": "/guides/admin-ui" }
20
+ ]
21
+ },
13
22
  {
14
23
  "text": "Concepts",
15
24
  "items": [
@@ -22,6 +31,21 @@
22
31
  { "text": "Runtime pipeline and adapters", "link": "/concepts/runtime-and-adapters" }
23
32
  ]
24
33
  },
34
+ {
35
+ "text": "Reference",
36
+ "items": [
37
+ { "text": "Manifest feature table", "link": "/reference/features" },
38
+ { "text": "Manifest envelope", "link": "/reference/manifest" },
39
+ { "text": "Schema", "link": "/reference/schema" },
40
+ { "text": "View", "link": "/reference/view" },
41
+ { "text": "Procedure", "link": "/reference/procedure" },
42
+ { "text": "Trigger", "link": "/reference/trigger" },
43
+ { "text": "Authorization requirements", "link": "/reference/authorization" },
44
+ { "text": "Site defaults and site_config", "link": "/reference/site-config" },
45
+ { "text": "Diagnostic codes", "link": "/reference/diagnostics" },
46
+ { "text": "HTTP, MCP, CLI and packages", "link": "/reference/surface" }
47
+ ]
48
+ },
25
49
  {
26
50
  "text": "ChatGPT Sites",
27
51
  "items": [
@@ -60,20 +84,6 @@
60
84
  { "text": "Guarded API access", "link": "/examples/guarded-api" }
61
85
  ]
62
86
  },
63
- {
64
- "text": "Reference",
65
- "items": [
66
- { "text": "Manifest envelope", "link": "/reference/manifest" },
67
- { "text": "Schema", "link": "/reference/schema" },
68
- { "text": "View", "link": "/reference/view" },
69
- { "text": "Procedure", "link": "/reference/procedure" },
70
- { "text": "Trigger", "link": "/reference/trigger" },
71
- { "text": "Authorization requirements", "link": "/reference/authorization" },
72
- { "text": "Site defaults and site_config", "link": "/reference/site-config" },
73
- { "text": "Diagnostic codes", "link": "/reference/diagnostics" },
74
- { "text": "HTTP, MCP, CLI and packages", "link": "/reference/surface" }
75
- ]
76
- },
77
87
  {
78
88
  "text": "Releases",
79
89
  "items": [
@@ -0,0 +1,55 @@
1
+ ---
2
+ description: Manifest capability table mapping authoring goals to Schema, View, Procedure and Trigger fields, generated APIs and Admin behavior.
3
+ ---
4
+ # Manifest feature reference
5
+
6
+ All paths below are relative to the atom's `spec`. The envelope is always
7
+ `apiVersion`, `kind`, `metadata.name`, `spec`. Features compose from these four
8
+ atoms; there is no separate Form, Workflow or UI manifest kind. See the
9
+ [envelope reference](./manifest.md) for naming and unknown-key rules.
10
+
11
+ ## Capability table
12
+
13
+ | Goal | Atom and fields | Runtime / surface effect | Contract |
14
+ |---|---|---|---|
15
+ | Define stored business data | Schema `schema` | Validated fields; storage adapter prepares the Schema. Generated entry types follow the JSON Schema subset. | [Schema](./schema.md) |
16
+ | Choose draft publishing or live records | Schema `lifecycle` | `publishing` has draft/publish transitions; `operational` creates live records. Admin workflow follows this choice. | [Lifecycle](../concepts/lifecycle-and-locales.md) |
17
+ | Label fields and collections | Schema `title`, `description`, property `title`, `description` | Localized Admin labels/help. Does not rename data keys. | [LocalizedText](./manifest.md#localizedtext) |
18
+ | Make Procedure-managed records | Schema `schema.readOnly` | Disables generic authoring writes; declared Procedures still work. | [Read-only collections](./schema.md#root-readonly-true) |
19
+ | Find and constrain records | Schema `indexes`, `uniqueIndexes`, `searchableFields` | Native access paths, uniqueness and declared substring-search fields. Search fields do not create indexes. | [Indexes](./schema.md#indexes) |
20
+ | Translate or relate records | Schema `localized`, `translates`; property `x-mantle-ref` | Locale rows, joined translations, relation controls and folded child collections. | [Schema](./schema.md), [Admin guide](../guides/admin-ui.md) |
21
+ | Stamp trusted values | Property `x-mantle-bind` | Runtime stamps identity/time; generic agent inputs exclude bound fields and Admin shows them read-only. | [Binding](./schema.md#x-mantle-bind) |
22
+ | Adjust collection inputs and list | Schema `uiSchema.fields`, `.list`, `.nav` | Textareas, operational columns/tabs, standalone child navigation. No CSS or component injection. | [Admin guide](../guides/admin-ui.md) |
23
+ | Query one Schema portably | View `from`, `fields`, `filter`, `orderBy`, `limit`, `params` | Named query with generated typed params and projected rows. | [View](./view.md), [typed queries](../guides/typed-queries.md) |
24
+ | Join or aggregate in SQLite | View `sql`, `params`, `limit` | One bound SELECT; requires a SQLite-capable adapter. Generated row type is `unknown`. | [SQL Views](./view.md#sql) |
25
+ | Choose read visibility | View `surface` | `public`: public REST/MCP; `staff`: Admin reports/staff MCP; `internal`: host binding only. Transports require host composition. | [Surfaces](./view.md#surfaces) |
26
+ | Authorize a query or action | View / Procedure `requires.auth`, `requires.guard` | Runtime checks verified caller context and optional guard. Visibility and UI metadata do not grant access. | [Authorization](./authorization.md) |
27
+ | Filter by caller identity | View `filter` with `$ctx.user: id` | Declarative equality filter; requires user auth and a left-prefix index. | [Identity filters](./view.md#value-forms) |
28
+ | Cache anonymous published reads | View `cache.sharedMaxAge` | Eligible public declarative publishing reads receive shared HTTP cache policy when the host configures cache scope. | [View cache](../concepts/views.md#shared-response-cache) |
29
+ | Configure a report | Staff View `title`, `uiSchema.list` | Ordered report/CSV columns, server-side search and exact filters. | [View list](./view.md#uischemalist) |
30
+ | Define an action | Procedure `input`, `output`, `handler` | Typed input/output; builtin mutation or registered host handler. A Procedure does not create an HTTP route by itself. | [Procedure](./procedure.md) |
31
+ | Put an action in Admin | Procedure `uiSchema.collectionAction`, `.fields`; input `x-mantle-ref`; qualifying Trigger | Collection/row actions and forms; eligible standalone operations appear under Operations. | [Admin guide](../guides/admin-ui.md) |
32
+ | Describe an agent action | Procedure `title`, `description`, `mcp` | Tool descriptions and behavior annotations; enforcement remains in runtime authorization/validation. | [Procedure](./procedure.md) |
33
+ | Expose an HTTP action | Trigger `source: { kind: http, method, path }`, `target.procedure` | Handler on the declared `/api/` path through supporting host adapters. | [HTTP Trigger](./trigger.md#http-source) |
34
+ | Expose an agent action | Trigger `source: { kind: mcp, surface }`, `target.procedure` | Public or staff MCP tool; Procedure authorization still applies. | [Trigger](./trigger.md) |
35
+ | React to content lifecycle | Trigger `source: { kind: lifecycle, schema, on, errorPolicy }`, `target.procedure` | Invokes the action on selected lifecycle events. Deferred execution needs host support. | [Hooks](../concepts/procedures-and-triggers.md) |
36
+
37
+ ## Where manifest control ends
38
+
39
+ Manifests describe data, callable behavior and supported presentation metadata.
40
+ They do not declare arbitrary React components, visitor routes, page layouts,
41
+ CSS, provider credentials or deployment resources. Those belong to application
42
+ source and optional host packages. For an Admin change, consult the
43
+ [rendering map](../guides/admin-ui.md) before deciding that custom UI is needed.
44
+
45
+ The pipeline is source → parse → link → compile → prepare storage → bind
46
+ runtime. `mantle generate` projects the plan and types; it does not start a
47
+ server. Programmatic `emitMantleModule({ plan })` also accepts an already
48
+ compiled plan; see [typed queries](../guides/typed-queries.md).
49
+
50
+ ## Source
51
+
52
+ - [Manifest grammar](../../../packages/mantle-spec/src/domain/model/ManifestGrammar.ts)
53
+ - [Admin UI validation](../../../packages/mantle-spec/src/domain/service/SchemaAdminUiChecker.ts)
54
+ - [Type generation](../../../packages/mantle-spec/src/usecase/EmitTypesUseCase.ts)
55
+ - [Runtime binding generation](../../../packages/mantle/src/codegen/emitMantleModule.ts)
@@ -5,6 +5,8 @@ description: Envelope fields, unknown-key policy, multi-document YAML, Localized
5
5
 
6
6
  This page covers the rules that apply to every Manifest document before kind-specific validation runs. Read it once; the four atom pages ([Schema](./schema.md), [View](./view.md), [Procedure](./procedure.md), [Trigger](./trigger.md)) assume it. Diagnostic codes named here are catalogued in [Diagnostics](./diagnostics.md).
7
7
 
8
+ For a task-to-field table covering all four atoms, see the [Manifest feature reference](./features.md). For the resulting console, see [Customize Admin](../guides/admin-ui.md).
9
+
8
10
  ## Envelope
9
11
 
10
12
  Every document is a YAML mapping with exactly four top-level keys.
@@ -37,7 +39,7 @@ The parser rejects keys outside the shipped grammar at every level it knows. The
37
39
  | `/` | `apiVersion`, `kind`, `metadata`, `spec` |
38
40
  | `/metadata` | `name` |
39
41
  | `/spec` (Schema) | `title`, `description`, `schema`, `uiSchema`, `uniqueIndexes`, `indexes`, `searchableFields`, `localized`, `translates`, `lifecycle` |
40
- | `/spec` (View) | `title`, `uiSchema`, `from`, `sql`, `surface`, `requires`, `filter`, `fields`, `orderBy`, `limit`, `params` |
42
+ | `/spec` (View) | `title`, `uiSchema`, `from`, `sql`, `surface`, `cache`, `requires`, `filter`, `fields`, `orderBy`, `limit`, `params` |
41
43
  | `/spec` (Procedure) | `title`, `description`, `requires`, `input`, `uiSchema`, `output`, `handler`, `mcp` |
42
44
  | `/spec` (Trigger) | `source`, `target` |
43
45
  | `/spec/translates` | `parent`, `on` |
@@ -164,7 +164,7 @@ Closed Admin-only roots: `fields`, `list`, `nav`. Nested keys are closed too. Un
164
164
  | `fields.<field>.widget` | Only `textarea`. The field must be a top-level property with a string type (`string` or `[string, null]`). |
165
165
  | `list.filterField` | Operational Schemas only. A declared property with a non-empty string `enum` that is the first field of some `indexes` or `uniqueIndexes` tuple. Admin renders the enum as sidebar links and list tabs. |
166
166
  | `list.primaryField` | Operational Schemas only. A non-empty top-level scalar property; rendered as the linked leading column. |
167
- | `list.columns` | Operational Schemas only. Top-level properties, no repeats and not repeating `primaryField`; structured values render as compact JSON. |
167
+ | `list.columns` | Operational Schemas only. Top-level properties or native entry columns, no repeats and not repeating `primaryField`; structured values render as compact JSON. |
168
168
  | `nav.standalone` | Boolean. `true` also emits a main Admin Nav list entry with a **parent autocomplete filter**. It does not unfold: required `x-mantle-ref` children still compose under the parent. Omit or `false` means fold-only (discover via the parent-entry workbench). Rejected on top-level Schemas, `translates` children, and Schemas with no eligible required-ref parent. |
169
169
  | `nav.parentField` | Allowed only with `standalone: true`. Names a required `x-mantle-ref` field used as the parent filter. One eligible required ref is inferred; more than one requires an explicit `parentField`. Do not rely on property-order heuristics when multiple refs exist. |
170
170
 
@@ -97,7 +97,7 @@ Tool names are the mangled `metadata.name`: lower-cased, with `-` replaced by `_
97
97
 
98
98
  | Tool | Surface | Registered when |
99
99
  |---|---|---|
100
- | `query_view_<segment>` | The View's own `surface` | One per declared View. `annotations.readOnlyHint` is `true`; the input schema is the View's `params.properties` plus `page` and `show`. |
100
+ | `query_view_<segment>` | The View's own `surface` | One per public or staff View; internal Views have no tool. `annotations.readOnlyHint` is `true`; the input schema is the View's `params.properties` plus `page` and `show`. |
101
101
  | `<procedure_segment>` | The MCP Trigger's `surface` | One per `mcp` Trigger. `annotations` carry what Core can prove (`readOnlyHint: false` for every builtin handler, `destructiveHint: true` for `op: delete`, `idempotentHint: true` when an input carries `x-mcp-hint: idempotency-key`) plus whatever the Procedure declares under `spec.mcp`; `ref` handlers get nothing inferred beyond the idempotency key. Generic authoring, lifecycle and media tools are `readOnlyHint: false`; `delete_entry` is also `destructiveHint: true`. |
102
102
  | `<procedure segment>` | The Trigger's `surface` | One per `Trigger.source.kind: mcp`. A Procedure with no MCP Trigger is not exposed. |
103
103
  | `request_publish` | staff | Always. Rejected at call time for an operational Schema. |
@@ -3,7 +3,7 @@ description: View field reference — declarative and SQL forms, filter AST, par
3
3
  ---
4
4
  # View
5
5
 
6
- A View is a named read-only query over Schemas. It is the only atom that needs no [Trigger](./trigger.md): declaring `surface` mounts it. This page is the field-level contract; the concepts are in [Views](../concepts/views.md) and [The four atoms](../concepts/four-atoms.md). Envelope rules are in [Manifest envelope and conventions](./manifest.md), and every diagnostic code named here is catalogued in [Diagnostics](./diagnostics.md).
6
+ A View is a named read-only query over Schemas. It is the only atom that needs no [Trigger](./trigger.md): `surface: public` or `staff` exposes it on supported transports; `internal` keeps it host-only. This page is the field-level contract; the concepts are in [Views](../concepts/views.md) and [The four atoms](../concepts/four-atoms.md). Envelope rules are in [Manifest envelope and conventions](./manifest.md), and every diagnostic code named here is catalogued in [Diagnostics](./diagnostics.md).
7
7
 
8
8
  ## Fields
9
9
 
@@ -13,7 +13,7 @@ A View is a named read-only query over Schemas. It is the only atom that needs n
13
13
  | `uiSchema` | object | no | — | Only on `surface: staff`; only the key `list`. Violations are `VIEW_UI_INVALID`. |
14
14
  | `from` | string | exactly one of `from` / `sql` | — | Name of a declared Schema (`VIEW_FROM_UNKNOWN_SCHEMA`). The declarative form. |
15
15
  | `sql` | string | exactly one of `from` / `sql` | — | One SQLite `SELECT`. See [`sql`](#sql). |
16
- | `surface` | `public` \| `staff` | yes | — | Decides where the View mounts. See [Surfaces](#surfaces). |
16
+ | `surface` | `public` \| `staff` \| `internal` | yes | — | Decides where the View mounts. See [Surfaces](#surfaces). |
17
17
  | `cache` | `{ sharedMaxAge }` | no | — | Anonymous REST shared-cache hint. `sharedMaxAge` is an integer from 1 to 86400. Only an unguarded, declarative public View over a publishing Schema may declare it. |
18
18
  | `requires` | AuthorizationRequirements | no | — | `auth.all` predicates plus one optional `guard.procedure`. See [Authorization](./authorization.md). |
19
19
  | `filter` | FilterAst | no | — | `from` form only. See [Filter AST](#filter-ast). |
@@ -207,6 +207,8 @@ Admin applies search and filters before pagination, rejecting a search term or f
207
207
  | `staff` | `GET /admin/api/views/<name>` and `/admin/api/views/<name>/export` — not mounted publicly | `query_view_<segment>` on `/mcp/staff` | Report sidebar |
208
208
  | `internal` | Not mounted | Not mounted | Not listed or mounted |
209
209
 
210
+ For a complete generated-binding example, see [Typed queries](../guides/typed-queries.md).
211
+
210
212
  An `internal` View remains in the compiled plan for host code to call through `MantleRuntime.executeView`. It is an exposure policy, not an authorization bypass: `requires` and guards still evaluate against the `ctx` supplied by the host. Shared HTTP caching is invalid because no adapter owns an HTTP response for the View.
211
213
 
212
214
  A `public` declarative View over a `publishing` Schema reads **published rows only**, on every transport. The runtime adds `status = published` to the compiled query whether or not the filter spells it out; writing it is allowed and redundant, and comparing `status` to any other value is rejected at validate time (`VIEW_PUBLIC_STATUS_INVALID`). Staff Views see every status. `operational` Schemas create rows as `published`, so nothing is added. SQL Views (`spec.sql`) are the author's own statement and receive no injected predicate. Decision record: ADR-0025.
@@ -17,10 +17,54 @@ stable candidate cut from `main`. Installing a prerelease means opting into an
17
17
  exact version, not a channel. [GitHub Releases](https://github.com/aotter/mantle/releases)
18
18
  is the canonical, immutable change history; this chapter is the narrative one.
19
19
 
20
- All ten packages share a single version and are published together, so mixed
20
+ All eleven packages share a single version and are published together, so mixed
21
21
  versions across `@aotter/mantle*` are never a supported combination. Pin the
22
22
  version you install and upgrade the whole set at once.
23
23
 
24
+ ## 0.1.3 — 2026-09-23
25
+
26
+ 0.1.3 tightens the contract between Manifests, generated TypeScript, agent
27
+ skills and the optional Admin surface. To upgrade from 0.1.2, pin every
28
+ selected `@aotter/mantle*` package to `0.1.3`, refresh the lockfile, then run
29
+ `mantle generate`, `mantle skills` and the matching `--check` commands.
30
+
31
+ **Private and typed reads.** Views may use `surface: internal` to stay out of
32
+ REST, MCP, WebMCP, OpenAPI and Admin while remaining callable from host code.
33
+ Generated bindings type declarative View params and rows, expose typed indexed
34
+ field reads for Schemas, and can be emitted from an already compiled plan. SQL
35
+ Views remain SQLite-native and deliberately return an `unknown` row type.
36
+
37
+ **Safer View storage and validation.** Public declarative Views over publishing
38
+ Schemas always enforce published status. Native entry columns (`id`, `status`,
39
+ `version`, `createdAt`, `updatedAt`, `authorId`) are reserved consistently and
40
+ may be used in the supported View/index positions. SQL validation is confined
41
+ to declared Schema tables, and the local index harness now uses production-
42
+ shaped planner and fixture state instead of reporting an artificial pass.
43
+
44
+ **MCP and authorization.** Tool schemas have agent-shaped inputs and standard
45
+ read-only, destructive, open-world and idempotency annotations. Calls carry
46
+ expected-version data through optimistic concurrency checks, enforce the
47
+ caller gate, and can emit audit records keyed by a declared idempotency input.
48
+ OAuth provider extensions, account linking and sign-in-link flows are owned by
49
+ the extracted optional `@aotter/mantle-auth` package. Session cache keys bind
50
+ to the prepared store identity so replacing D1 cannot revive stale sessions.
51
+
52
+ **Admin and authoring.** Manifest `uiSchema` can select operational collection
53
+ columns/tabs, staff report search/filter/CSV fields and collection or row
54
+ actions. Native columns render correctly in lists, and operation dialogs reset
55
+ their optimistic-concurrency state between actions. The handbook now starts
56
+ with a task-oriented overview, a complete Manifest feature table, typed-query
57
+ and Admin-rendering guides, and an explicit skill-install → pinned SDK →
58
+ project-skill handoff. The CLI points to those installed, version-matched docs.
59
+
60
+ **Upgrade note.** Regeneration is required because generated bindings and
61
+ projected skills gained APIs and instructions. Applications that declared one
62
+ of the newly reserved native column names as business data must rename that
63
+ field before upgrading. Backend-specific D1/IndexedDB cost inspectors and
64
+ server-side soak budgets remain deferred to
65
+ [#1040](https://github.com/aotter/mantle/issues/1040); the conservative local
66
+ harness is a preflight, not production cost evidence.
67
+
24
68
  ## 0.1.2 — 2026-09-21
25
69
 
26
70
  The first stable release, and Mantle's first public one. Everything before it
@@ -0,0 +1,52 @@
1
+ ---
2
+ description: Choose a Mantle integration, discover manifest capabilities, and find tutorials, task guides, concepts and field-level reference.
3
+ ---
4
+ # Mantle handbook
5
+
6
+ Mantle turns YAML manifests into a validated runtime plan, typed TypeScript
7
+ bindings, and optional HTTP, MCP and Admin surfaces. Your application owns the
8
+ host, storage and frontend. Four atoms describe the contract: **Schema** stores
9
+ data, **View** reads it, **Procedure** acts on it, and **Trigger** binds an action
10
+ to HTTP, MCP or lifecycle events.
11
+
12
+ This handbook describes the SDK snapshot that carries it. For an installed
13
+ project, read `node_modules/@aotter/mantle/docs/handbook/`; a website or Git
14
+ branch can describe a different version. The [release index](../releases/index.md)
15
+ links published releases. A prerelease capability is not a promise that the
16
+ current npm `latest` contains it.
17
+
18
+ ## Start with your integration
19
+
20
+ | Goal | Start here | Result |
21
+ |---|---|---|
22
+ | Understand what manifests can express | [Manifest feature reference](../reference/features.md) | A capability-to-field map across the four atoms. |
23
+ | Validate manifests in an existing tool | [Spec-only adoption](../../spec-only-host-adoption.md) | Parse and link without Runtime, storage or a UI. |
24
+ | Embed Runtime in an existing host | [Runtime and adapters](../concepts/runtime-and-adapters.md), then [typed queries](../guides/typed-queries.md) | Bind your storage and call the generated API. |
25
+ | Build a local Cloudflare API | [Minimal Worker tutorial](./quickstart-worker.md) | A running public View and a verified HTTP response. |
26
+ | Add a staff console | [Local Admin tutorial](./quickstart-admin.md) | Email OTP, Admin assets and a local human workflow. |
27
+ | Build on ChatGPT Sites | [Sites integration](../sites/index.md) | Host-owned sign-in and deployment with Mantle content. |
28
+ | Work through a coding agent | [Skill installation and handoff](../guides/agent-setup.md) | Bootstrap skill, pinned package, then project-local instructions. |
29
+
30
+ Human authors can follow these pages directly; installing an agent skill is
31
+ optional. Do not start with `mantle generate` in an empty directory: author the
32
+ manifests and host first, then generate and validate.
33
+
34
+ ## Find the right kind of documentation
35
+
36
+ - **Tutorials** walk through a running minimal service or local Admin.
37
+ - **Task guides** explain typed queries, Admin customization and agent setup.
38
+ - **Concepts** explain the four atoms, runtime, lifecycle, authorization and transports.
39
+ - **Reference** lists accepted fields, defaults, restrictions and diagnostics.
40
+ - **Host guides** cover Cloudflare and Sites wiring and operations.
41
+ - **Examples** supply complete domain manifests and runnable host references.
42
+
43
+ The [project and CLI guide](./project-and-cli.md) describes file ownership and
44
+ the verification loop. The [examples hub](../examples/hub.md) helps select a
45
+ domain model. Use the [field reference](../reference/manifest.md) when checking
46
+ exact syntax; do not infer grammar from a UI screenshot.
47
+
48
+ ## Source
49
+
50
+ - [Core package](../../../packages/mantle/README.md)
51
+ - [Handbook navigation](../navigation.json)
52
+ - [Consumer skills](../../../skills/README.md)
@@ -5,7 +5,7 @@ description: The files you own in a Mantle project, every mantle and mantle-harn
5
5
 
6
6
  This page describes a directly authored Mantle project: which files are yours, what the installed CLI does to them, and the loop you run before every commit. Surfaces are optional — take only what you need. [The minimal Worker](./quickstart-worker.md) is Spec + adapter without Admin. [Local Admin](./quickstart-admin.md) is the opt-in Dev UI path when humans need a console.
7
7
 
8
- Cold start from GitHub or a marketplace host is the install skill, not this page:
8
+ Agents can bootstrap with the install skill; human authors can follow this guide directly. For installation paths and the pinned-package handoff, see [Agent setup](../guides/agent-setup.md):
9
9
 
10
10
  ```sh
11
11
  npx skills add aotter/mantle --skill install
@@ -77,7 +77,7 @@ It does not project skills, update packages, change styling, provision providers
77
77
  | `createMantle({ storage, handlers, ports })` | Prepares storage eagerly once and returns the typed binding. No caching or retry. |
78
78
  | `bindMantle(runtime)` | The same typed binding over a runtime whose lifecycle the host already owns. |
79
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. Details are in [HTTP, MCP, CLI and packages](../reference/surface.md).
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
81
 
82
82
  ## The daily loop
83
83
 
@@ -3,7 +3,7 @@ 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 Core's API-only Worker reference as a from-scratch walkthrough. It is the embed / adapter path: View REST without Admin, Auth or a visitor frontend. Admin is opt-in when humans need a console — [Quickstart: local Admin](./quickstart-admin.md). Install every `@aotter/mantle*` package from the `latest` dist-tag; see [Versions](../reference/surface.md#versions).
6
+ This page reproduces Core's API-only Worker reference as a from-scratch walkthrough. It is the embed / adapter path: View REST without Admin, Auth or a visitor frontend. Admin is opt-in when humans need a console — [Quickstart: local Admin](./quickstart-admin.md). Resolve the intended release once and pin every `@aotter/mantle*` package to it; see [Versions](../reference/surface.md#versions).
7
7
 
8
8
  ## Prerequisites
9
9
 
@@ -13,7 +13,10 @@ This page reproduces Core's API-only Worker reference as a from-scratch walkthro
13
13
 
14
14
  ## 1. `package.json`
15
15
 
16
- Install every `@aotter/mantle*` package from the `latest` dist-tag and add the peers the Cloudflare adapter needs.
16
+ The `latest` entries below are bootstrap placeholders. Step 5 replaces both
17
+ with one exact version before the first build. For a prerelease evaluation,
18
+ select its exact version explicitly rather than mixing channels. The other
19
+ entries are the peers and tools used by this reference.
17
20
 
18
21
  ```json
19
22
  {
@@ -130,7 +133,9 @@ Both compatibility flags are required by the adapter. `MANTLE_AUTH_MODE` must be
130
133
  ## 5. Install, generate, validate, run
131
134
 
132
135
  ```sh
133
- pnpm install
136
+ # Resolve once; for a requested prerelease, set its exact version instead.
137
+ MANTLE_VERSION=$(pnpm view @aotter/mantle@latest version)
138
+ pnpm add --save-exact "@aotter/mantle@$MANTLE_VERSION" "@aotter/mantle-cloudflare@$MANTLE_VERSION"
134
139
  pnpm exec mantle generate
135
140
  pnpm exec mantle validate
136
141
  pnpm exec wrangler dev --local --ip 127.0.0.1 --port 8787
@@ -6,7 +6,7 @@ Runtime. This Spec-only path is allowed by
6
6
  [ADR-0019](adr/0019-sealed-manifest-runtime-pipeline.md), not a new adapter,
7
7
  manifest grammar, or fork of Core.
8
8
 
9
- This recipe targets `0.1.3-alpha.6`. Pin the package, record the tested version, and
9
+ This recipe targets `0.1.3`. Pin the package, record the tested version, and
10
10
  rerun compatibility checks when upgrading.
11
11
 
12
12
  ## What stays with the host
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aotter/mantle",
3
- "version": "0.1.3-alpha.6",
3
+ "version": "0.1.3",
4
4
  "description": "Embeddable Mantle Core umbrella with Spec and Runtime; Web, Admin, Auth, Bun, Vercel, Cloudflare, and Admin UI are optional peer packages.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://mantle.tools/",
@@ -83,8 +83,8 @@
83
83
  "README.md"
84
84
  ],
85
85
  "dependencies": {
86
- "@aotter/mantle-runtime": "0.1.3-alpha.6",
87
- "@aotter/mantle-spec": "0.1.3-alpha.6"
86
+ "@aotter/mantle-runtime": "0.1.3",
87
+ "@aotter/mantle-spec": "0.1.3"
88
88
  },
89
89
  "peerDependencies": {
90
90
  "aws4fetch": "^1.0.20",
@@ -92,13 +92,13 @@
92
92
  "hono": "^4.12.0",
93
93
  "@libsql/client": "^0.17.4",
94
94
  "zod": "^4.5.0",
95
- "@aotter/mantle-admin": "0.1.3-alpha.6",
96
- "@aotter/mantle-auth": "0.1.3-alpha.6",
97
- "@aotter/mantle-admin-ui": "0.1.3-alpha.6",
98
- "@aotter/mantle-bun": "0.1.3-alpha.6",
99
- "@aotter/mantle-vercel": "0.1.3-alpha.6",
100
- "@aotter/mantle-cloudflare": "0.1.3-alpha.6",
101
- "@aotter/mantle-web": "0.1.3-alpha.6"
95
+ "@aotter/mantle-admin": "0.1.3",
96
+ "@aotter/mantle-admin-ui": "0.1.3",
97
+ "@aotter/mantle-bun": "0.1.3",
98
+ "@aotter/mantle-auth": "0.1.3",
99
+ "@aotter/mantle-web": "0.1.3",
100
+ "@aotter/mantle-cloudflare": "0.1.3",
101
+ "@aotter/mantle-vercel": "0.1.3"
102
102
  },
103
103
  "peerDependenciesMeta": {
104
104
  "@aotter/mantle-admin": {
@@ -144,13 +144,13 @@
144
144
  "typescript": "^6.0.3",
145
145
  "vitest": "^4.1.11",
146
146
  "zod": "^4.5.4",
147
- "@aotter/mantle-admin": "0.1.3-alpha.6",
148
- "@aotter/mantle-admin-ui": "0.1.3-alpha.6",
149
- "@aotter/mantle-auth": "0.1.3-alpha.6",
150
- "@aotter/mantle-bun": "0.1.3-alpha.6",
151
- "@aotter/mantle-cloudflare": "0.1.3-alpha.6",
152
- "@aotter/mantle-web": "0.1.3-alpha.6",
153
- "@aotter/mantle-vercel": "0.1.3-alpha.6"
147
+ "@aotter/mantle-admin-ui": "0.1.3",
148
+ "@aotter/mantle-admin": "0.1.3",
149
+ "@aotter/mantle-auth": "0.1.3",
150
+ "@aotter/mantle-bun": "0.1.3",
151
+ "@aotter/mantle-cloudflare": "0.1.3",
152
+ "@aotter/mantle-vercel": "0.1.3",
153
+ "@aotter/mantle-web": "0.1.3"
154
154
  },
155
155
  "engines": {
156
156
  "node": ">=22"
package/skills/README.md CHANGED
@@ -75,7 +75,11 @@ codex plugin marketplace add aotter/mantle
75
75
  codex plugin add mantle@mantle
76
76
  ```
77
77
 
78
- Then follow the install skill to the CLI and handbook. After packages are
78
+ Read the path printed by the installer (for project-local Codex,
79
+ `.agents/skills/install/SKILL.md`). Only the selected brief is installed, not
80
+ the SDK or handbook. After choosing and installing an exact SDK version, read
81
+ `node_modules/@aotter/mantle/skills/install/SKILL.md` and its embedded docs;
82
+ that package supersedes the bootstrap Git-ref instructions. After packages are
79
83
  installed, `mantle skills` projects the installed package's own skills into the
80
84
  project, and `mantle skills --check` fails on drift.
81
85
 
@@ -17,8 +17,9 @@ docs govern runtime/API behavior.
17
17
  ## First Read
18
18
 
19
19
  1. `package.json` for the installed `@aotter/mantle*` versions.
20
- 2. `manifests/site.yaml`, the active adapter config (`wrangler.jsonc`), and
21
- the Worker entry. Custom Auth lives in that entry's `createAuth` factory.
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.
22
23
  3. Optional local context: `.mantle/plugins.json`, `.mantle/plugins.lock.json`,
23
24
  and `.mantle/recipes/`. Legacy launch/handoff files are context only.
24
25
  4. Installed Core docs in `node_modules/@aotter/mantle/docs/`.
@@ -75,6 +76,22 @@ Do not invent manifest kinds such as `Form`, `Feature`, `Workflow`, or
75
76
  `Membership`. Compose those from the four atoms plus TypeScript only where
76
77
  the atoms cannot express the behavior.
77
78
 
79
+ ## Choose the manifest feature first
80
+
81
+ Read installed `docs/handbook/reference/features.md` to map the requested
82
+ behavior to fields before adding handlers or a custom UI. For host-only reads,
83
+ `surface: internal` keeps a View out of REST/MCP/Admin while preserving its
84
+ `requires` checks. Read `docs/handbook/guides/typed-queries.md` for generated
85
+ View params/results, indexed entry reads, and their authorization boundary.
86
+ Use `from` for portable typed projections; SQL is for queries needing native
87
+ SQLite and produces `unknown` row types.
88
+
89
+ For Admin labels, inputs, collection columns/tabs, reports or action buttons,
90
+ read `docs/handbook/guides/admin-ui.md`. Prefer supported Schema/Procedure/View
91
+ metadata and `uiSchema` before custom frontend code. These control the Admin
92
+ console, not the visitor frontend. Regenerate and verify the actual console;
93
+ never edit generated `public/_mantle/admin/` assets.
94
+
78
95
  ## Content Edits
79
96
 
80
97
  - Follow the actual frontend content source. Use Admin or Staff MCP for