Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.

Commit 6dea96f

Browse files
committed
Merge main ce9811c into claude/issue-12082-census-freeze-leg-b
Claude-Session: https://claude.ai/code/session_01TYgwmFK1q4KJ6Qq2WRLzsD Co-authored-by: Claude <noreply@anthropic.com>
2 parents 07b86fe + ce9811c commit 6dea96f

30 files changed

Lines changed: 1784 additions & 228 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@object-ui/plugin-detail': patch
3+
---
4+
5+
A record activity feed shows an object's `activityMilestones` rows of type `completed`, such as "Case resolved", instead of hiding them as completed tasks (objectui#12106).
6+
7+
A milestone keeps the `type` its declaration names, so "Case resolved" declared with `type: 'completed'` arrived as a `completed` row. The feed mapped every `completed` row to a `task` item, and `showCompleted` is off by default, so the milestone was hidden on every record page that did not set it, including the default page.
8+
9+
plugin-audit now stamps `metadata.kind: 'milestone'` on a row a milestone fired (objectstack#22771). The feed reads that marker. A `completed` row that carries it renders as a `system` item, the presentation every other author-typed milestone already gets, and shows whatever `showCompleted` says. A task's own "Task completed" milestone shows on that task's page for the same reason.
10+
11+
A `completed` row without the marker is unchanged: it is a `task` item, hidden unless `showCompleted` is on. That covers rows from a runtime that does not stamp the marker yet, and rows an app inserts itself. `filterMode: 'tasks_only'` and `types: ['task']` still select tasks only, so they do not list a milestone. The `record:activity` block's own read and the console record page's feed both read rows through `activityRowToFeedItem`, so both change together. No export, prop or type changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@object-ui/types': patch
3+
---
4+
5+
A record-source refusal (`RECORD_SOURCE_REQUIRED`, raised by every arm that requires a record source) now reports the same path every time (objectui#5250).
6+
7+
The refusal's `path` was one array, built when the arm was defined and handed to every issue. zod copies an added issue shallowly and prefixes its `path` in place as the issue climbs out of an array slot or an object key, so the first refusal reported from inside a container rewrote the path of every later refusal of that arm for as long as the module stayed loaded. A process that judges many documents saw the drift: `objectui check` over a project, or `objectui validate` called repeatedly in one process, could report a root refusal at a path like `0 → 0 → 0 → 0`. Each issue now carries its own copy. The refusal, its message and its code are unchanged.

‎.github/workflows/doc-snippet-types.yml‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,15 @@ jobs:
185185
# narrowing what the gate scans.
186186
- name: Compile JSDoc `@example` blocks against the built types
187187
run: node scripts/check-doc-example-types.mjs
188+
189+
# objectui#5250 (the maintainer ruling's JSON-fence slice). Every `json` /
190+
# `jsonc` node document in `content/docs` is judged through the STRICT
191+
# authoring face — `StrictAnyComponentSchema`, read from the
192+
# `@object-ui/types` the build step above produced (the snippet gate's
193+
# closure carries it) — the face `objectui validate` judges with. A fence
194+
# that is deliberately not a complete node document is declared on the
195+
# line above it, and the declaration is re-judged on every run. Last of
196+
# the three, for the reason the step above gives: a newly wired blocking
197+
# gate must not mask an established one.
198+
- name: Judge JSON doc fences through the strict authoring face
199+
run: node scripts/check-doc-json-fences.mjs

‎content/docs/api/schema-reference.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ A single-record detail view with grouped fields, actions, and tabs.
710710
"title": "Customer Info",
711711
"fields": [
712712
{ "name": "customer", "label": "Customer", "type": "text" },
713-
{ "name": "email", "label": "Email", "type": "email" },
713+
{ "name": "email", "label": "Email", "type": "text" },
714714
{ "name": "created", "label": "Created", "type": "date", "format": "MMM d, yyyy" }
715715
]
716716
},

‎content/docs/blocks/authentication.mdx‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,17 @@ behaviour. Common customisations:
5454

5555
### Wire Up Submission
5656

57+
A control that runs something is its own node type, `action:button`, and its
58+
props go in the `properties` bag; `actionType: "api"` sends the request to
59+
`target`:
60+
5761
```json
5862
{
59-
"type": "button",
60-
"label": "Sign In",
61-
"action": {
62-
"type": "submit",
63-
"endpoint": "/api/auth/login",
63+
"type": "action:button",
64+
"properties": {
65+
"label": "Sign In",
66+
"actionType": "api",
67+
"target": "/api/auth/login",
6468
"method": "POST"
6569
}
6670
}

‎content/docs/blocks/dashboard.mdx‎

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,16 @@ Customize dashboard blocks for your needs:
3333

3434
### Add Real Data
3535

36+
A `card` fetches nothing. A live figure comes from a data-bound block: an
37+
`element:number` takes its object from the per-element `dataSource` binding and
38+
its aggregate from its `properties` bag (see the
39+
[Data Source guide](/docs/guide/data-source)):
40+
3641
```json
3742
{
38-
"type": "card",
39-
"dataSource": {
40-
"api": "/api/stats/revenue",
41-
"method": "GET"
42-
}
43+
"type": "element:number",
44+
"dataSource": { "object": "order" },
45+
"properties": { "aggregate": "count" }
4346
}
4447
```
4548

@@ -55,13 +58,16 @@ Customize dashboard blocks for your needs:
5558

5659
### Add Actions
5760

61+
A control that runs something is its own node type, `action:button`, and its
62+
props go in the `properties` bag; `actionType: "url"` navigates to `target`:
63+
5864
```json
5965
{
60-
"type": "button",
61-
"label": "View Details",
62-
"action": {
63-
"type": "navigate",
64-
"path": "/dashboard/details"
66+
"type": "action:button",
67+
"properties": {
68+
"label": "View Details",
69+
"actionType": "url",
70+
"target": "/dashboard/details"
6571
}
6672
}
6773
```

‎content/docs/blocks/ecommerce.mdx‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,30 @@ Customize e-commerce blocks for your store:
3939

4040
### Add Product Data
4141

42+
A `card` fetches nothing. Records come from a data-bound block that names its
43+
object in the per-element `dataSource` binding (see the
44+
[Data Source guide](/docs/guide/data-source)):
45+
4246
```json
4347
{
44-
"type": "card",
45-
"dataSource": {
46-
"api": "/api/products",
47-
"method": "GET"
48-
}
48+
"type": "object-grid",
49+
"dataSource": { "object": "product", "limit": 20 }
4950
}
5051
```
5152

5253
### Add to Cart Action
5354

55+
A control that runs something is its own node type, `action:button`, and its
56+
props go in the `properties` bag; `actionType: "api"` sends the request to
57+
`target`:
58+
5459
```json
5560
{
56-
"type": "button",
57-
"label": "Add to Cart",
58-
"action": {
59-
"type": "submit",
60-
"endpoint": "/api/cart",
61+
"type": "action:button",
62+
"properties": {
63+
"label": "Add to Cart",
64+
"actionType": "api",
65+
"target": "/api/cart",
6166
"method": "POST"
6267
}
6368
}

‎content/docs/blocks/forms.mdx‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,17 @@ or in a TypeScript-authored schema pass the real thing —
9393

9494
### Add Submit Action
9595

96+
A control that runs something is its own node type, `action:button`, and its
97+
props go in the `properties` bag; `actionType: "api"` sends the request to
98+
`target`:
99+
96100
```json
97101
{
98-
"type": "button",
99-
"label": "Submit",
100-
"action": {
101-
"type": "submit",
102-
"endpoint": "/api/contact",
102+
"type": "action:button",
103+
"properties": {
104+
"label": "Submit",
105+
"actionType": "api",
106+
"target": "/api/contact",
103107
"method": "POST"
104108
}
105109
}

‎content/docs/blocks/marketing.mdx‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,6 @@ Customize marketing blocks for your campaigns:
4646
}
4747
```
4848

49-
### Add Analytics
50-
51-
```json
52-
{
53-
"type": "button",
54-
"label": "Get Started",
55-
"action": {
56-
"type": "analytics",
57-
"event": "cta_clicked"
58-
}
59-
}
60-
```
61-
6249
### Customize Content
6350

6451
```json

‎content/docs/components/basic/icon.mdx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ The glyph is named by `icon`:
3434
`name` is the SDUI identity key every node carries, alongside `id`. It is **not**
3535
read as a glyph name on `ui:icon`, and writing one there renders no icon:
3636

37+
{/* doc-json: fragment — a deliberately refused node: it shows the retired name-as-glyph shape the paragraph below describes */}
3738
```json
3839
{ "type": "icon", "id": "save_icon", "name": "save_icon" }
3940
```

0 commit comments

Comments
 (0)