From e7308373b4a9cca41cc22a8a551dc574cc7f9936 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Oct 2026 20:32:41 +0000 Subject: [PATCH 1/2] chore(console): move the objectui pin 4016370af3c9 -> 12dc7b47c340 (WIP: manifest pending) Claude-Session: https://claude.ai/code/session_017QnMGFC4agzW9DVBSwQ6Cc Co-authored-by: Claude --- .changeset/24644-console-pin-12dc7b47c340.md | 66 ++++++++++++++++++++ .objectui-sha | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 .changeset/24644-console-pin-12dc7b47c340.md diff --git a/.changeset/24644-console-pin-12dc7b47c340.md b/.changeset/24644-console-pin-12dc7b47c340.md new file mode 100644 index 00000000000..82c189c7a81 --- /dev/null +++ b/.changeset/24644-console-pin-12dc7b47c340.md @@ -0,0 +1,66 @@ +--- +"@objectstack/console": minor +--- + +Console (objectui) refreshed to `12dc7b47c340`. Frontend changes in this range: + +Derived from the changesets objectui declared over the range — 28 releasing of 28 changesets added across 32 non-merge commits; omitted: 4 commits carrying no changeset (they ship no package code). + +- **minor** — Setup lists the sharing rules installed packages declare again, read-only, with Disable / Enable and Clone (objectui#12982). (objectui `12dc7b47c`) +- **minor** — `list-view` publishes the keys of its `@objectstack/spec` row that the renderer honours on a page node (objectui#13047). (objectui `a244a172a`) +- **minor** — **BREAKING** — An import undo that leaves rows unreverted now says so in the Import Wizard (objectui#13015). (objectui `a928aaa61`) +- **minor** — A `type: 'form'` action placed at `record_related` and fired from a related-list row now opens the clicked row's edit form (`/forms/NAME?recordId=ROW_ID&recordObject=CHILD`), as i… (objectui `9f1dd79fe`) +- **minor** — A field group whose `visibleWhen` cannot be evaluated is now hidden, header and members, on the form and on the record detail page (objectui#13055). (objectui `fb85637e1`) +- **minor** — The AI build chat's pending-drafts bar no longer covers the composer's input (objectui#12978). (objectui `51269f0fd`) +- **minor** — Bound record blocks draw an authored empty state when their binding answers no row (objectui#12932, the renderer half of objectstack-ai/objectstack#24266). (objectui `c2191654a`) +- **minor** — Publish `optionListDefault` (and its parameter type `OptionListFieldLike`) from the package entry: the reading of an option list's `default: true` that create forms seed from (obj… (objectui `b9e188762`) +- **minor** — Build `@objectstack/*` from objectstack `main` `f4755a68a7` (objectui#12971). (objectui `8aa8e3e1e`) +- **minor** — Two Cloud SDUI widgets are retired: `cloud:onboarding-next`, the Welcome page's next-step block, and `cloud:plan-status`, the pricing page's current-plan marker (objectui#12954).… (objectui `30083da91`) +- **minor** — Every app now has a report index at `/apps/APP/reports` (objectui#13020). It lists the reports the app's package ships, by their localized labels, each linking to its `report/NAME… (objectui `47508f3bb`) +- **minor** — A record page that shows the same unfiltered related list both as a `record:reference_rail` card and in a `page:tabs` count badge now reads that list once on open, not twice. The… (objectui `d0b9648ef`) +- **patch** — Studio's RLS policy editor now gives a predicate the runtime cannot lower the server's verdict: an error that holds Save and autosave (objectui#13061). A `USING` or `CHECK` clause… (objectui `2a75c83b2`) +- **patch** — A master-detail edit form now applies its line rules to the header record however late that record loads (objectui#13062). (objectui `bc98626ed`) +- **patch** — A deep link to an object read by name always leaves the "Opening your console…" splash (objectui#13052). (objectui `1ce071187`) +- **patch** — A kanban card move is announced to screen readers when its write answers, not when the card is dropped (objectui#13054). (objectui `083e80735`) +- **patch** — An `app` page that declares a `record` binding now reads that row, and its components' `visibleWhen` predicates read it as `record` (objectui#12931, the renderer half of objectsta… (objectui `a23a33d6f`) +- **patch** — One page open asks the server for one object document once (objectui#13044). The metadata provider's by-name object read now goes through the adapter's `getObjectSchema`, so the p… (objectui `65fe4c285`) +- **patch** — A record page no longer asks `POST /api/v1/security/explain` for a verdict nothing on screen uses (objectui#13045). (objectui `50ba1bb0a`) +- **patch** — Charts and dataset widgets read their object's metadata through the data source, so the widgets of one dashboard ask for one object's metadata once (objectui#13039). (objectui `988aa9fa1`) +- **patch** — The Undo of an `operation: 'update'` action covers the `patch` of the declared action its `name` names, and no action renderer forwards a page action row's own `patch` (objectui#1… (objectui `61ed5ada6`) +- **patch** — A list view draws a `referenceVia` pointer column's record when its columns do not show the type half (objectui#13036). (objectui `fe11eb12e`) +- **patch** — A record link in an assistant answer opens that record inside the console (objectui#13037). (objectui `633b8f18f`) +- **patch** — The chat's step line no longer shows the agent's tool-loading step, and no longer counts it (objectui#13038). (objectui `912bfd4a6`) +- **patch** — An assistant answer reads well in the narrow assistant panel (objectui#13032). Headings inside a chat answer render at chat size (15–16px, bold, set apart by weight and spacing in… (objectui `6f877f1df`) +- **patch** — The console's pending-approvals read now asks for one page of requests and takes the count from the route's `total` (objectui#13027). (objectui `d14ba9636`) +- **patch** — A record page of a `trackHistory` object reads its audit history when the History tab is shown (objectui#13010). (objectui `acefe6fa6`) +- **patch** — A record page reads its timeline, comments, user list and foot-of-page attachments when they are shown, not on every open (objectui#13010, part 2). (objectui `29c19cc1a`) + +⚠️ 1 of these carries a breaking change: 1 by the author's own breaking annotation in the changeset body — objectui declares no `major` inside a launch window (`scripts/check-changeset-no-major.mjs`). Each is marked **BREAKING** in the list above — read them before compiling the release record. + +**In this console build, declared nowhere** — objectui merged 4 commits in this range with no `.changeset/*.md`. The code is inside the pin above and ships here, but nothing upstream declared them, so they appear in no objectui CHANGELOG and in no entry above. Listed by subject rather than counted, because a count cannot tell a dependency bump from a form-behaviour change (objectstack#6174); the upstream gate that would prevent this is objectui#3387. + +- _(no changeset)_ fix(ci): read transient jobs-API failures, re-run attempts and stale shards without false reds in the aggregate Test gate (objectui#13064) (#13077) (objectui `90a4fc49b`) +- _(no changeset)_ tooling(pin): keep one pinned @objectstack build per machine and copy it into each new checkout (objectui#12972) (#13035) (objectui `f9401e6af`) +- _(no changeset)_ tooling(pin): commit the pin's packed manifests so a lockfile-only resolution needs no build (objectui#13008) (#13031) (objectui `b014f5eea`) +- _(no changeset)_ tooling: publish computes each @objectstack/* floor from .objectstack-sha (objectui#12958) (#13024) (objectui `4484a1104`) + +Clause-②: no + + + +objectui range: `4016370af3c9...12dc7b47c340` diff --git a/.objectui-sha b/.objectui-sha index f23fed226d2..01a0c5f69e9 100644 --- a/.objectui-sha +++ b/.objectui-sha @@ -1 +1 @@ -4016370af3c9c9dafec2bc5299afd8e8079701b8 +12dc7b47c340d9bd80b35406d890c2d27c8017dc From b1abdca63edbb41e95f459ad5fd63d00261328dd Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Oct 2026 20:52:59 +0000 Subject: [PATCH 2/2] chore(console): regenerate the SDUI manifest and the lockstep record at objectui 12dc7b47c340 Claude-Session: https://claude.ai/code/session_017QnMGFC4agzW9DVBSwQ6Cc Co-authored-by: Claude --- packages/sdui-parser/objectui-lockstep.json | 6 +- scripts/sdui-manifest.record.json | 6 +- sdui.manifest.json | 226 ++++++++++++++++++-- 3 files changed, 216 insertions(+), 22 deletions(-) diff --git a/packages/sdui-parser/objectui-lockstep.json b/packages/sdui-parser/objectui-lockstep.json index 83ebb54dc8f..b21dd370b2c 100644 --- a/packages/sdui-parser/objectui-lockstep.json +++ b/packages/sdui-parser/objectui-lockstep.json @@ -6,8 +6,8 @@ ], "objectui": { "repo": "https://github.com/objectstack-ai/objectui.git", - "rev": "4016370af3c9c9dafec2bc5299afd8e8079701b8", - "revDate": "2026-10-19T03:42:35+00:00", + "rev": "12dc7b47c340d9bd80b35406d890c2d27c8017dc", + "revDate": "2026-10-19T20:08:18+00:00", "source": "packages/sdui-parser/src", "files": [ "packages/sdui-parser/src/body-dialect.ts", @@ -21,7 +21,7 @@ "packages/sdui-parser/src/validate.ts" ] }, - "recordedAgainstPin": "4016370af3c9c9dafec2bc5299afd8e8079701b8", + "recordedAgainstPin": "12dc7b47c340d9bd80b35406d890c2d27c8017dc", "grammarRegion": { "file": "packages/sdui-parser/src/parse.ts", "delimiter": "/* ---------------------- the JS literal subset (#6614) ---------------------- */", diff --git a/scripts/sdui-manifest.record.json b/scripts/sdui-manifest.record.json index 0387ca12b69..00ec74acf49 100644 --- a/scripts/sdui-manifest.record.json +++ b/scripts/sdui-manifest.record.json @@ -11,12 +11,12 @@ "a pin bump without regeneration goes RED there — that is the anti-rot half of the freshness gate.", "Regenerate + re-record: pnpm objectui:build && node scripts/gen-sdui-manifest-node.mjs" ], - "objectuiSha": "4016370af3c9c9dafec2bc5299afd8e8079701b8", + "objectuiSha": "12dc7b47c340d9bd80b35406d890c2d27c8017dc", "source": "built-tree", - "modulesRoot": ".cache/objectui-4016370af3c9/apps/console", + "modulesRoot": ".cache/objectui-12dc7b47c340/apps/console", "objectuiWorkspaceVersion": "17.7.0", "generator": "scripts/gen-sdui-manifest-node.mjs", "generatedAt": "2026-10-19", - "sha256": "c6b03966dae9b17b1f5864323efa05c143b31d95eee3cd77e4572eac980ac0cb", + "sha256": "b7a53e34856fc4b34c5e615aaf62e149361b92ba6936290d9e1e6cbcbd068bf5", "components": 107 } diff --git a/sdui.manifest.json b/sdui.manifest.json index b0e8fb4fe65..249688000ac 100644 --- a/sdui.manifest.json +++ b/sdui.manifest.json @@ -230,19 +230,208 @@ }, { "name": "columns", - "type": "array" + "type": "array", + "description": "The fields the list shows, in order: field names (`[\"name\", \"stage\"]`) or the spec's `ListColumn` objects. They are also the query's `$select`. Optional on a page node: a node bound to a saved view through `dataSource.view` draws that view's columns." }, { "name": "filter", - "type": "array" + "type": "array", + "description": "The base query filter, the spec's `ViewFilterRule` array `[{ field, operator, value }]`, lowered to `$filter`." }, { "name": "sort", - "type": "array" + "type": "array", + "description": "The initial sort order, `[{ field, order }]`, lowered to `$orderby` in the order written." + }, + { + "name": "pagination", + "type": "object", + "description": "The spec's pagination config, `{ pageSize, pageSizeOptions }`: `pageSize` caps each query (`$top`), and `pageSizeOptions` offers those sizes to the user." + }, + { + "name": "searchableFields", + "type": "array", + "of": "string", + "description": "The field names the toolbar search box searches. A term typed into the box is sent with these fields only." + }, + { + "name": "label", + "type": [ + "string", + "object" + ], + "description": "The list's label: it names the exported file and heads the record-detail overlay. A plain string, or an inline per-locale map (`{ en: \"Open tasks\", \"zh-CN\": \"未完成任务\" }`) resolved against the display locale." + }, + { + "name": "description", + "type": [ + "string", + "object" + ], + "description": "One line about the list, drawn as the toolbar's info control (its tooltip and accessible name). A plain string, or an inline per-locale map resolved against the display locale. `appearance.showDescription: false` hides it." + }, + { + "name": "userFilters", + "type": "object", + "description": "The quick-filter bar above the list, the spec's `UserFilters` config: `{ element: \"dropdown\" | \"toggle\" | \"tabs\", fields | tabs }`. Each filter narrows the query." + }, + { + "name": "userActions", + "type": "object", + "description": "Which toolbar controls the user gets, the spec's `UserActionsConfig` of per-control toggles: a control set to `false` (for example `sort: false`) is taken off the toolbar, and the controls it does not name stay." + }, + { + "name": "compactToolbar", + "type": "boolean", + "description": "Gather the grouping, row colour, density and hide-fields controls into one Display form. On by default; `false` draws one toolbar button per control." + }, + { + "name": "appearance", + "type": "object", + "description": "The spec's appearance config, `{ showDescription, allowedVisualizations }`. `showDescription: false` hides the description. `allowedVisualizations` narrows the kinds a view switcher offers, and a page node draws no switcher, so on a page it changes nothing: the node's `type` is the kind drawn." + }, + { + "name": "exportOptions", + "type": "object", + "description": "The export menu, `{ formats, maxRecords, includeHeaders, fileNamePrefix, streaming }`. Declaring it offers the export on the toolbar, in the listed formats; `fileNamePrefix` names the file." + }, + { + "name": "allowPrinting", + "type": "boolean", + "description": "Draw a Print button that opens the browser's print dialog for the list." + }, + { + "name": "showRecordCount", + "type": "boolean", + "description": "The record count in the list's footer. On by default; `false` takes it off." + }, + { + "name": "emptyState", + "type": "object", + "description": "What the list draws when no record comes back, the spec's `EmptyState`: `{ title, message, icon, link }`. `title`, `message` and the link's `label` each take a plain string or an inline per-locale map." + }, + { + "name": "hiddenFields", + "type": "array", + "of": "string", + "description": "Field names taken out of `columns`. A name `columns` does not show takes nothing out." + }, + { + "name": "fieldOrder", + "type": "array", + "of": "string", + "description": "Field names that order the columns left after `hiddenFields`. A column not listed comes after every listed one; a listed name that is not a column orders nothing." + }, + { + "name": "rowHeight", + "type": "enum", + "enum": [ + "compact", + "short", + "medium", + "tall", + "extra_tall" + ], + "description": "Row density. Absent, rows are `compact`." + }, + { + "name": "resizable", + "type": "boolean", + "description": "Let users drag column borders to resize the grid's columns." + }, + { + "name": "selection", + "type": "object", + "description": "Row selection, `{ type: \"none\" | \"single\" | \"multiple\" }`." + }, + { + "name": "navigation", + "type": "object", + "description": "What clicking a row does, the spec's `NavigationConfig`: `{ mode: \"page\" | \"drawer\" | \"modal\" | \"split\" | \"popover\" | \"new_window\" | \"none\", … }`. An overlay mode opens the record over the list, headed by the list's `label`." + }, + { + "name": "grouping", + "type": "object", + "description": "Group the rows, `{ fields: [{ field, order, collapsed }] }`. The groups and their header counts come from the server." + }, + { + "name": "rowColor", + "type": "object", + "description": "Colour whole rows by a field's value, `{ field, colors: { VALUE: COLOR } }`." + }, + { + "name": "conditionalFormatting", + "type": "array", + "of": "object", + "description": "Row style rules, each `{ condition, style }`: a CEL `condition` over the row's `record.*` and a CSS `style` map. The first rule that matches styles the row." + }, + { + "name": "inlineEdit", + "type": "boolean", + "description": "Open the grid in inline-edit mode, for users who may update the object." + }, + { + "name": "rowActions", + "type": "array", + "of": "string", + "description": "Names of the actions offered on each row's menu." + }, + { + "name": "bulkActions", + "type": "array", + "of": "string", + "description": "Names of the actions offered once rows are selected. Needs a multi-row `selection`." + }, + { + "name": "bulkActionDefs", + "type": "array", + "of": "object", + "description": "Full bulk-action definitions, the spec's `BulkActionDef`: a mass update (`operation: \"update\"` with a `patch`) or delete, or a named action run once for the whole selection." }, { "name": "options", - "type": "object" + "type": "object", + "description": "Per-kind settings, `{ kanban, calendar, gantt, gallery, timeline, map, tree, chart }`, each judged by that kind's own block. The top-level block of the same name is the canonical spelling." + }, + { + "name": "kanban", + "type": "object", + "description": "The board, the spec's kanban block: `{ groupByField, columns, titleField, summarizeField }`. `groupByField` is the lane field and `columns` the fields on each card." + }, + { + "name": "calendar", + "type": "object", + "description": "The calendar, `{ startDateField, endDateField, titleField, colorField, allDayField }`." + }, + { + "name": "gantt", + "type": "object", + "description": "The gantt chart, `{ startDateField, endDateField, titleField, progressField, dependenciesField }`. Both date fields are needed to draw it." + }, + { + "name": "gallery", + "type": "object", + "description": "The gallery, `{ coverField, titleField, visibleFields, cardSize, … }`." + }, + { + "name": "timeline", + "type": "object", + "description": "The timeline, `{ startDateField, endDateField, titleField, groupByField, colorField, scale }`." + }, + { + "name": "map", + "type": "object", + "description": "The map, `{ locationField }` or `{ latitudeField, longitudeField }`, with `titleField`, `zoom` and `center`." + }, + { + "name": "tree", + "type": "object", + "description": "The tree, `{ parentField, labelField, fields, defaultExpandedDepth }`." + }, + { + "name": "chart", + "type": "object", + "description": "The chart a `type: \"chart\"` list draws, bound to an ADR-0021 dataset: `{ dataset, values, dimensions, chartType }`. There is no default binding." }, { "name": "dataSource", @@ -1444,6 +1633,11 @@ "of": "string", "description": "[ADR-0066] Capabilities the user must ALL hold — names that permission sets grant through `systemPermissions`, not object actions: `read` or `update` here is an ordinary capability name, not the object's read or edit permission. When the client has resolved the user's capabilities and any of these is missing, this block does not render its content; wherever it would otherwise render, an insufficient-permissions notice takes its place. Presentation only: it authorises nothing, and the data API still serves the same data to the same user. A client that cannot resolve the user's capabilities (no permission provider, or one that does not report `systemPermissions`) renders this block as if they were held — it fails open." }, + { + "name": "emptyState", + "type": "object", + "description": "What this block draws in its place when its `dataSource` binding answers no row, `{ title, message, icon, link }` — the list view's own empty-state shape: a Lucide `icon` name, a `title` (default: \"Record not found\"), a `message` (default: none) and one `link: { label, url }` the user follows (default: none), opened as a `url` action opens it. `title`, `message` and the link's `label` each accept a plain string or an inline per-locale map, resolved against the display locale. Drawn then and only then — never on a block with no `dataSource` (it reads the record page's record instead), never while the bound read is loading, and never in place of the error a failed read shows; a read the server refuses as forbidden reads as no row, so it is drawn for that too. Leave it out and a binding with no row keeps the block's own placeholder." + }, { "name": "dataSource", "type": "object", @@ -1488,6 +1682,11 @@ "of": "string", "description": "[ADR-0066] Capabilities the user must ALL hold — names that permission sets grant through `systemPermissions`, not object actions: `read` or `update` here is an ordinary capability name, not the object's read or edit permission. When the client has resolved the user's capabilities and any of these is missing, this block does not render its content; wherever it would otherwise render, an insufficient-permissions notice takes its place. Presentation only: it authorises nothing, and the data API still serves the same data to the same user. A client that cannot resolve the user's capabilities (no permission provider, or one that does not report `systemPermissions`) renders this block as if they were held — it fails open." }, + { + "name": "emptyState", + "type": "object", + "description": "What this block draws in its place when its `dataSource` binding answers no row, `{ title, message, icon, link }` — the list view's own empty-state shape: a Lucide `icon` name, a `title` (default: \"Record not found\"), a `message` (default: none) and one `link: { label, url }` the user follows (default: none), opened as a `url` action opens it. `title`, `message` and the link's `label` each accept a plain string or an inline per-locale map, resolved against the display locale. Drawn then and only then — never on a block with no `dataSource` (it reads the record page's record instead), never while the bound read is loading, and never in place of the error a failed read shows; a read the server refuses as forbidden reads as no row, so it is drawn for that too. Leave it out and a binding with no row keeps the block's own placeholder." + }, { "name": "dataSource", "type": "object", @@ -1872,6 +2071,11 @@ "type": "string", "description": "Passed to the Button primitive; a per-action size overrides it" }, + { + "name": "emptyState", + "type": "object", + "description": "What this block draws in its place when its `dataSource` binding answers no row, `{ title, message, icon, link }` — the list view's own empty-state shape: a Lucide `icon` name, a `title` (default: \"Record not found\"), a `message` (default: none) and one `link: { label, url }` the user follows (default: none), opened as a `url` action opens it. `title`, `message` and the link's `label` each accept a plain string or an inline per-locale map, resolved against the display locale. Drawn then and only then — never on a block with no `dataSource` (it reads the record page's record instead), never while the bound read is loading, and never in place of the error a failed read shows; a read the server refuses as forbidden reads as no row, so it is drawn for that too. Leave it out and a binding with no row keeps the block's own placeholder." + }, { "name": "dataSource", "type": "object", @@ -2405,12 +2609,7 @@ "enum": [ "update" ], - "description": "`update` declares a single-record field write: the runner dispatches it to the platform action route with `patch` merged under the collected values" - }, - { - "name": "patch", - "type": "object", - "description": "For `operation: update`: the field values written, merged UNDER the values the user supplies, so a collected value of the same name wins" + "description": "`update` declares a single-record field write: the row runs the declared action its `name` names, so it needs a `name`. The runner posts the collected values to the platform action route under that name, and the route writes that action's own `patch`" }, { "name": "confirmText", @@ -2709,12 +2908,7 @@ "enum": [ "update" ], - "description": "`update` declares a single-record field write: the runner dispatches it to the platform action route with `patch` merged under the collected values" - }, - { - "name": "patch", - "type": "object", - "description": "For `operation: update`: the field values written, merged UNDER the values the user supplies, so a collected value of the same name wins" + "description": "`update` declares a single-record field write: the row runs the declared action its `name` names, so it needs a `name`. The runner posts the collected values to the platform action route under that name, and the route writes that action's own `patch`" }, { "name": "confirmText",