@cloudhal/core-contracts 0.3.4 → 0.3.5

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.
@@ -1,434 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://cloudhal.dev/schemas/v1/section.schema.json",
4
- "title": "Section",
5
- "description": "A block inside a page, discriminated by `kind`. Variants are written inline (not via $ref) and `kind` is a single-value string enum so that TypeScript gets a literal union and Rust gets a serde internally-tagged enum.",
6
- "oneOf": [
7
- {
8
- "type": "object",
9
- "title": "HeroSection",
10
- "additionalProperties": false,
11
- "required": [
12
- "id",
13
- "kind",
14
- "heading"
15
- ],
16
- "properties": {
17
- "id": {
18
- "$ref": "#/$defs/Id"
19
- },
20
- "kind": {
21
- "type": "string",
22
- "enum": [
23
- "hero"
24
- ]
25
- },
26
- "heading": {
27
- "type": "string",
28
- "minLength": 1,
29
- "maxLength": 300
30
- },
31
- "subheading": {
32
- "type": "string",
33
- "maxLength": 1000
34
- },
35
- "image": {
36
- "$ref": "#/$defs/ImageRef"
37
- },
38
- "cta": {
39
- "$ref": "#/$defs/Link"
40
- }
41
- }
42
- },
43
- {
44
- "type": "object",
45
- "title": "RichTextSection",
46
- "additionalProperties": false,
47
- "required": [
48
- "id",
49
- "kind",
50
- "format",
51
- "body"
52
- ],
53
- "properties": {
54
- "id": {
55
- "$ref": "#/$defs/Id"
56
- },
57
- "kind": {
58
- "type": "string",
59
- "enum": [
60
- "richText"
61
- ]
62
- },
63
- "format": {
64
- "type": "string",
65
- "enum": [
66
- "markdown",
67
- "html"
68
- ]
69
- },
70
- "body": {
71
- "type": "string",
72
- "maxLength": 200000
73
- },
74
- "profile": {
75
- "$ref": "#/$defs/BodyProfile"
76
- },
77
- "blocks": {
78
- "$ref": "#/$defs/BodyBlocks"
79
- }
80
- }
81
- },
82
- {
83
- "type": "object",
84
- "title": "ImageSection",
85
- "additionalProperties": false,
86
- "required": [
87
- "id",
88
- "kind",
89
- "image"
90
- ],
91
- "properties": {
92
- "id": {
93
- "$ref": "#/$defs/Id"
94
- },
95
- "kind": {
96
- "type": "string",
97
- "enum": [
98
- "image"
99
- ]
100
- },
101
- "image": {
102
- "$ref": "#/$defs/ImageRef"
103
- },
104
- "caption": {
105
- "type": "string",
106
- "maxLength": 1000
107
- }
108
- }
109
- },
110
- {
111
- "type": "object",
112
- "title": "ContentListSection",
113
- "description": "Renders the newest entries of a content collection (e.g. blog posts).",
114
- "additionalProperties": false,
115
- "required": [
116
- "id",
117
- "kind",
118
- "collection",
119
- "limit",
120
- "sort"
121
- ],
122
- "properties": {
123
- "id": {
124
- "$ref": "#/$defs/Id"
125
- },
126
- "kind": {
127
- "type": "string",
128
- "enum": [
129
- "contentList"
130
- ]
131
- },
132
- "collection": {
133
- "$ref": "#/$defs/Slug"
134
- },
135
- "limit": {
136
- "type": "integer",
137
- "minimum": 1,
138
- "maximum": 100
139
- },
140
- "sort": {
141
- "type": "string",
142
- "enum": [
143
- "newest",
144
- "oldest",
145
- "title"
146
- ]
147
- },
148
- "filter": {
149
- "type": "string",
150
- "description": "Filter expression over term assignments (RFC-0002), e.g. 'category:news+tag:ai' or 'category:news>*'.",
151
- "minLength": 1,
152
- "maxLength": 512
153
- }
154
- }
155
- },
156
- {
157
- "type": "object",
158
- "title": "ComponentSection",
159
- "description": "A typed block from the block registry (RFC-0015): `type` names a registered block type (one global namespace of English names), `props` follow that type's props schema, which the store validates.",
160
- "additionalProperties": false,
161
- "required": [
162
- "id",
163
- "kind",
164
- "type",
165
- "props"
166
- ],
167
- "properties": {
168
- "id": {
169
- "$ref": "#/$defs/Id"
170
- },
171
- "kind": {
172
- "type": "string",
173
- "enum": [
174
- "component"
175
- ]
176
- },
177
- "type": {
178
- "type": "string",
179
- "pattern": "^[a-z][a-z0-9-]{1,40}$"
180
- },
181
- "props": {
182
- "type": "object",
183
- "description": "Validated against the type's props schema by the store, not by this contract.",
184
- "additionalProperties": true
185
- }
186
- }
187
- },
188
- {
189
- "type": "object",
190
- "title": "SurfaceSection",
191
- "description": "A generative UI surface (RFC-0020): a flat list of catalog components with a `root`, plus a data model their props may bind to. Written and streamed by agents as data, never code; the store checks the tree, the catalog and the limits.",
192
- "additionalProperties": false,
193
- "required": [
194
- "id",
195
- "kind",
196
- "catalog",
197
- "components"
198
- ],
199
- "properties": {
200
- "id": {
201
- "$ref": "#/$defs/Id"
202
- },
203
- "kind": {
204
- "type": "string",
205
- "enum": [
206
- "surface"
207
- ]
208
- },
209
- "catalog": {
210
- "type": "string",
211
- "description": "The catalog the surface was written for: `<theme>@<major>` (RFC-0018 manifest).",
212
- "pattern": "^[a-z][a-z0-9-]{0,40}@[0-9]{1,4}$"
213
- },
214
- "components": {
215
- "type": "array",
216
- "minItems": 1,
217
- "maxItems": 200,
218
- "items": {
219
- "$ref": "#/$defs/SurfaceComponent"
220
- }
221
- },
222
- "data": {
223
- "type": "object",
224
- "description": "The surface's data model: JSON its components bind to with `{path}` (at most 64 KB serialized; the store enforces the size).",
225
- "additionalProperties": true
226
- }
227
- }
228
- }
229
- ],
230
- "$defs": {
231
- "Actor": {
232
- "type": "object",
233
- "additionalProperties": false,
234
- "required": [
235
- "kind",
236
- "id"
237
- ],
238
- "properties": {
239
- "kind": {
240
- "$ref": "#/$defs/ActorKind"
241
- },
242
- "id": {
243
- "$ref": "#/$defs/Id"
244
- },
245
- "name": {
246
- "type": "string",
247
- "maxLength": 200
248
- }
249
- }
250
- },
251
- "ActorKind": {
252
- "type": "string",
253
- "description": "Who performed an action. Humans and agents share one actor model so the policy engine treats them uniformly.",
254
- "enum": [
255
- "human",
256
- "agent",
257
- "system"
258
- ]
259
- },
260
- "BodyBlock": {
261
- "type": "object",
262
- "description": "One top-level block of a markdown body in the store's index (RFC-0014 §3). Written by the store only: a client's values are replaced on every write. `by`, `via` and `at` say who last changed the block's content, through which channel and when; they are absent for content written before the index existed.",
263
- "additionalProperties": false,
264
- "required": [
265
- "id",
266
- "hash"
267
- ],
268
- "properties": {
269
- "id": {
270
- "type": "string",
271
- "pattern": "^blk_[0-9A-Za-z]{8,24}$",
272
- "description": "Stable across writes that keep the block's content or its place among unchanged blocks."
273
- },
274
- "hash": {
275
- "type": "string",
276
- "pattern": "^[0-9a-f]{64}$",
277
- "description": "SHA-256 (hex) of the block's markdown without trailing whitespace."
278
- },
279
- "by": {
280
- "$ref": "#/$defs/Actor"
281
- },
282
- "via": {
283
- "type": "string",
284
- "enum": [
285
- "studio",
286
- "mcp",
287
- "api",
288
- "import",
289
- "ai-command",
290
- "proposal"
291
- ],
292
- "description": "The channel of that change."
293
- },
294
- "at": {
295
- "$ref": "#/$defs/Timestamp"
296
- }
297
- }
298
- },
299
- "BodyBlocks": {
300
- "type": "array",
301
- "description": "A markdown body's block index, in body order (RFC-0014 §3). Absent means not indexed (yet, or an HTML body), never empty.",
302
- "maxItems": 5000,
303
- "items": {
304
- "$ref": "#/$defs/BodyBlock"
305
- }
306
- },
307
- "BodyProfile": {
308
- "type": "integer",
309
- "enum": [
310
- 1
311
- ],
312
- "description": "The markdown dialect a body follows (RFC-0014 §1): 1 = Cloudhal Markdown v1 (CommonMark + GFM + `asset:` + directives; raw HTML escaped). Set by the store on markdown bodies."
313
- },
314
- "Id": {
315
- "type": "string",
316
- "description": "Prefixed, URL-safe identifier, e.g. site_01HZX8K3Q9. The prefix names the entity kind; agents and the MCP server pass these as opaque handles.",
317
- "pattern": "^[a-z]+_[A-Za-z0-9]{6,32}$",
318
- "minLength": 8,
319
- "maxLength": 48
320
- },
321
- "ImageRef": {
322
- "type": "object",
323
- "description": "Reference to an image. With `assetId` the image is an Asset node (RFC-0004): the store writes its media URL into `src`, and its size into `width` and `height`, as a fallback for readers that do not resolve assets. Without it, `src` is a relative path or an absolute URL, as before.",
324
- "additionalProperties": false,
325
- "required": [
326
- "src",
327
- "alt"
328
- ],
329
- "properties": {
330
- "assetId": {
331
- "$ref": "#/$defs/Id",
332
- "description": "The Asset node shown (RFC-0004). Renderers that know assets resolve it and ignore `src`."
333
- },
334
- "src": {
335
- "type": "string",
336
- "minLength": 1,
337
- "maxLength": 2048
338
- },
339
- "alt": {
340
- "type": "string",
341
- "maxLength": 500
342
- },
343
- "width": {
344
- "type": "integer",
345
- "minimum": 1
346
- },
347
- "height": {
348
- "type": "integer",
349
- "minimum": 1
350
- }
351
- }
352
- },
353
- "Link": {
354
- "type": "object",
355
- "additionalProperties": false,
356
- "required": [
357
- "label",
358
- "href"
359
- ],
360
- "properties": {
361
- "label": {
362
- "type": "string",
363
- "minLength": 1,
364
- "maxLength": 200
365
- },
366
- "href": {
367
- "type": "string",
368
- "minLength": 1,
369
- "maxLength": 2048
370
- },
371
- "external": {
372
- "type": "boolean"
373
- }
374
- }
375
- },
376
- "Slug": {
377
- "type": "string",
378
- "description": "Lower-case URL segment.",
379
- "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
380
- "minLength": 1,
381
- "maxLength": 128
382
- },
383
- "SurfaceComponent": {
384
- "type": "object",
385
- "description": "One element of a generative UI surface (RFC-0020 §1), in a flat list: `component` names a catalog entry (a PascalCase built-in primitive such as `Stack`, or a registry block type such as `callout`), `children` refer to other ids of the same surface, and `props` follow the entry's schema, which the store checks. Field names follow A2UI v0.9.",
386
- "additionalProperties": false,
387
- "required": [
388
- "id",
389
- "component"
390
- ],
391
- "properties": {
392
- "id": {
393
- "$ref": "#/$defs/SurfaceComponentId"
394
- },
395
- "component": {
396
- "type": "string",
397
- "pattern": "^(?:[A-Z][A-Za-z0-9]{1,40}|[a-z][a-z0-9-]{1,40})$"
398
- },
399
- "children": {
400
- "type": "array",
401
- "maxItems": 200,
402
- "items": {
403
- "$ref": "#/$defs/SurfaceComponentId"
404
- }
405
- },
406
- "props": {
407
- "type": "object",
408
- "description": "Literal values, `{path}` bindings into the surface's data, or `{call}` named functions; validated by the store against the catalog, not by this contract.",
409
- "additionalProperties": true
410
- },
411
- "visible": {
412
- "type": "object",
413
- "description": "A visibility condition over the surface's data (`eq`, `ne`, `gt`, `lt`, `and`, `or`, `not`); validated by the store.",
414
- "additionalProperties": true
415
- },
416
- "motion": {
417
- "type": "object",
418
- "description": "Motion presets for this component (RFC-0024 §2): `reveal`, `hover`, `speed`, `delay`, `stagger`, `replay` and later `scroll`, `loop`; enums and clamped numbers only, validated by the store against the catalog. The renderer turns them into CSS; agents never write CSS.",
419
- "additionalProperties": true
420
- }
421
- }
422
- },
423
- "SurfaceComponentId": {
424
- "type": "string",
425
- "description": "A component's id, unique within its surface; `root` is the tree's root (RFC-0020 §1).",
426
- "pattern": "^[a-z][a-z0-9-]{0,40}$"
427
- },
428
- "Timestamp": {
429
- "type": "string",
430
- "description": "RFC 3339 / ISO 8601 instant in UTC.",
431
- "format": "date-time"
432
- }
433
- }
434
- }