Skip to content

Commit f3b4164

Browse files
committed
Merge origin/main into claude/project-thread-q3clql
Brings #30449 (#30300) onto the branch before the PR, at the seat's request. Claude-Session: https://claude.ai/code/session_01Utp6Cai3TgWyncLtR5EwF7 Co-authored-by: Claude <noreply@anthropic.com>
2 parents e950155 + f506b79 commit f3b4164

168 files changed

Lines changed: 9240 additions & 888 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/skills': patch
3+
---
4+
5+
docs(skills): the automation skill's OAuth recipe names a stdio MCP server's credential route as `transport.credentialEnv`
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
Recipe 6 of `objectstack-automation/references/integration-recipes.md` said a `stdio` server's credentials ride `transport.env` — the literal-in-metadata route the `connector-credential-literal` advisory warns against. It now says what the `mcp` provider does: the grant-bearing kinds stay `http` only; a `stdio` server takes a static `auth: { type: 'bearer', credentialRef }`, handed to the child process in the variable `transport.credentialEnv` names, never a literal in `transport.env`. Paid inside the file's token ceiling by dropping the opening paragraph's restatement of two facts that keep their homes: the packaged spec (SKILL.md § Integrations are declared, not coded) and where an `api` hook's secret goes (SKILL.md's `secretRef` row and recipe 4). No eval asserted the old route; none changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'@object-ui/plugin-detail': patch
3+
---
4+
5+
fix(plugin-detail): the record page's activity feed names the record as the reader reads it, as the record's heading does, when the object is named by a formula
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
An activity summary quotes the record's name as its writer read it: `sys_activity.record_label`, and the same text inside `summary`, are stored when the write happens. The server composes the rest of the summary in the reader's language on read, but not the name. For an object whose name field is a formula over `label(record.FIELD)`, that name is in the writer's language, so an en-US reader of a review a zh-CN user created read `Created Review "法务 · Legal Counsel 1"` while the heading above it read `Legal · Legal Counsel 1`.
11+
12+
Each activity row of the page's own record now names the record by the value of the object's name field on the record the page read, which is the heading's name. The change is made where the feed is drawn (`RecordActivityTimeline`), so the activity panel, the 动态 stream and the 动态 panel all read it. Only the name the summary quotes (`"…"`, or `「…」` in Japanese) is replaced.
13+
14+
What stays as stored:
15+
16+
- an object whose name field is a stored field (text and the like): the name a row stored is the name the record had then, and a rename does not rewrite older rows;
17+
- a row about another record, a row that carries no `record_label`, and a summary that does not quote the stored name;
18+
- a page with no record around the feed, or whose record has no name to show.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
'@object-ui/i18n': patch
4+
---
5+
6+
feat(app-shell): the Studio list-view panel configures the selection bar's actions (#30089)
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
The list-view panel of an object's grid view gains a "Selection actions" section. It edits two keys the list view already declares, and no other:
12+
13+
- `bulkActions`: pick the object's actions by label, plus the built-in Delete (`delete`). Each runs once per selected record, promoted with the action's own label and params.
14+
- `bulkActionDefs`: add, edit or remove a field update (`operation: 'update'`): a button label, the fields the dialog asks for (one required param per field, carrying a select's options and a lookup's object) and an optional confirmation. A def is written only once it has a label and a field and `BulkActionDefSchema` accepts it.
15+
16+
The section says what happens to the built-in Delete: shown while the view declares neither key, and kept once either is declared only when `bulkActions` names `delete`. A def of another kind (`delete`, an aggregate `custom` dispatch) is listed and can be removed; it is edited in metadata. An emptied key is removed, so a view that declares neither key saves as it was read. On an installed app's read-only view, the first edit goes through the same customization copy as every other setting of the panel. Strings are added in English and Chinese to the `studio` namespace of `@object-ui/i18n`.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
'@object-ui/i18n': patch
4+
---
5+
6+
fix(app-shell): Studio's publish review sheet says a customization lives in this environment's database and moves only by `os package export` (#30119)
7+
8+
Clause-②: yes (widening) — new `@object-ui/i18n` key `preview.changes.customizationEnvironment` in every pack; `preview/savedToCustomization` gains `customizationEnvironmentText` and `PACKAGE_EXPORT_COMMAND`
9+
Metadata-protocol: none
10+
11+
Reviewing a read-only package's customizations, the sheet adds one line under "Saved to BASE's customizations": the changes are kept in this environment's database as items of the `.custom` package it names (the id the server answered for the base), not in the project's source, and they reach another environment only through `os package export`.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@object-ui/console': patch
3+
'@object-ui/i18n': patch
4+
---
5+
6+
fix(console): a person who verifies their email during the mobile sign-in hand-off gets a mail link that works, and the hand-off's refusal time survives the verification pages (#30157)
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
On a server that requires email verification, a person signing up from the mobile app's sign-in (the hand-off `redirect` on `/register`) got a verification mail whose link landed on a Console page that does not exist (`/_console/api/v1/auth/one-time-token/handoff?…`). The mail is usually opened in a browser that is not the app's sign-in window, and often on another device, so the link now returns to `/verify-email?handoff=verified`: the page says the address is confirmed and to go back to the app and sign in there. It offers no Console sign-in and hands out no sign-in token in that browser. The same holds for the "Resend verification email" mail. Every other `redirect` (an invitation, a Console page) keeps the link it had.
12+
13+
The hand-off's refusal time (`handoff_refused_at`) is now carried through `/verify-email-prompt` on all three hops: `/login`'s "email not verified" branch, `/register`'s "verification required" branch, and "Back to login". Beside any other `redirect`, those links are unchanged.
14+
15+
New string: `auth.verifyEmail.handoffSuccessDescription` (all ten locales).
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
'@object-ui/plugin-grid': minor
3+
---
4+
5+
fix(plugin-grid)!: a list's selection bar and row menu draw only actions the object declares; an undeclared bare `bulkActions` / `rowActions` name draws nothing and warns once in development (#30169)
6+
7+
Clause-②: no (narrowing) — the grid stops drawing a bare `bulkActions` or legacy `rowActions` name that matches no action the object declares, which it drew before by humanized name. `packages/spec/src/ui/bulk-action.zod.ts` already says the member "names an action the object declares", and lint `action-name-undefined` (ADR-0049) refuses any other at authoring. Nothing is widened.
8+
Metadata-protocol: narrowed
9+
Skills-docs: no move — `skills/**` teaches no handler-only bulk or row action name (searched for `bulkActions` / `rowActions` examples and runner-handler text); `content/docs/ui/**` already names only declared actions in its `bulkActions` / `rowActions` examples.
10+
11+
<!-- adr-0087: not-required (no-migration-prescription) No key of any schema, export or stored row changes shape: `bulkActions` and `rowActions` keep their `string[]` form and meaning. What narrows is the renderer's draw set, back to the spec's own sentence. Whether an undeclared name was a misspelling, an action still to declare or a handler the host meant to keep is a judgement about the view, so no rewrite derives the fix; the development warning names each name. -->
12+
13+
**BREAKING** for a host that registered a runner handler under a bare name the object does not declare (`ActionProvider handlers` / `runner.registerHandler('NAME', …)`) and listed that name in a view's `bulkActions` or `rowActions`.
14+
15+
- **Before.** `resolveBulkActions` and `resolveLegacyRowActions` kept a name that matched no declared action, and `ObjectGrid` drew it by humanized name and dispatched it to the runner by name. A name nothing handled toasted "not executable" on click. This is how a list whose app had a package disabled kept a ghost button: the server withholds that package's actions from the served object, so their names matched nothing.
16+
- **Now.** Such a name gets no selection-bar button and no row-menu entry, and in development the console logs one warning per list naming the key, the block and each name. The resolvers return those names as `undeclared` (renamed from `unresolved`), used only for that warning. The canonical `'delete'` (and the row menu's `'edit'` / `'delete'`) keep their own paths, unchanged.
17+
- **Unchanged.** A name that matches a declared action is promoted to that action's def exactly as before, under the action's own label, icon, params, `visible` and `requiredPermissions`.
18+
19+
**Remedy.** No rewrite is derived, because which fix an undeclared name needs is a judgement about the view: declare the named action on the object, or remove the name from `bulkActions` / `rowActions`. The development warning names each one. An action withheld by a disabled package needs nothing: it draws again when the package is enabled.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@object-ui/console': patch
3+
'@object-ui/plugin-kanban': patch
4+
'@object-ui/plugin-form': patch
5+
---
6+
7+
fix(ui): the console form page Edit, the kanban drop prompt and the Edit wizard judge a field's `requiredWhen` as the engine does, a transition gate against the stored record
8+
9+
Clause-②: no
10+
Metadata-protocol: none
11+
12+
- **`@object-ui/console` form page (`/forms/:name?recordId=`):** an Edit no longer refuses a record that already sits inside a `requiredWhen` gate without the value (for example a contract activated before its signed-copy rule existed). The field shows no required marker there, and an unrelated edit saves, as REST `PATCH` already accepts. Still refused: the edit that moves a record into the gate without the value, and clearing the value of a record that held it. A create form enforces as before.
13+
- **`@object-ui/plugin-kanban` drop prompt:** dropping a card no longer asks for a field the engine lets rest. A record already inside the gate without the value moves between columns with no dialog; a drop that moves a compliant record into the gate still asks for the value first.
14+
- **`@object-ui/plugin-form` Edit wizard:** the final submit's cross-step check no longer refuses a record that already sits inside a `requiredWhen` gate without the value; it asks `requiredWhenRestsOnStoredRecord` about the record as first read. The record reaches only that stored-record check, so a `visibleWhen` reading `previous` is still unevaluable at that check, as before. Moving a compliant record into the gate is still refused, and a Create wizard enforces as before.
15+
16+
All three read the stored-record verdict `resolveFieldRuleState` already returns (`requiredWhenAtRest`, or its exported check `requiredWhenRestsOnStoredRecord`); no second rule.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/skills': patch
3+
---
4+
5+
docs(skills): the platform skill names every type a pair's declared override is served for, and that removing the pair's item serves the base's again
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
`skills/objectstack-platform/SKILL.md`, the "Customizing an installed package (ADR-0146)" paragraph: a `.custom` pair's declared override is served for a view, dashboard, report, email_template, translation, flow, page, app, dataset, doc, book or mapping (the paragraph named six), and removing the pair's item (`DELETE …?package=hotcrm.custom`) serves the base's document again (ADR-0146's revert, which the paragraph did not say). The package's evals gain a dataset-and-page override case and a removal case.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@objectstack/spec': patch
3+
'@objectstack/platform-objects': patch
4+
'@object-ui/app-shell': patch
5+
---
6+
7+
fix: on a zh-CN console every row of the view properties panel's collapsed sections (表格选项 / 分页 / 终端用户控制 / 导航与共享) reads in Chinese
8+
9+
Clause-②: no
10+
Metadata-protocol: none
11+
12+
- `viewForm` (`@objectstack/spec/ui`) now spells out the children of its `selection`, `pagination`, `userFilters`, `appearance`, `userActions`, `navigation` and `sharing` composites, and gives the rows that had none a hint. Each declared hint is the schema description the panel already showed, so an English console reads the same text; `os i18n extract` now emits a `metadataForms.view.fields['<parent>.<child>']` key per row.
13+
- `userFilters.fields` is enumerated as an inline-table repeater, and `UserFilterFieldSchema`'s six properties carry a `.meta({ title })` (Field / Label / Type / Options / Show Count / Default Values) — the English column heads, unchanged.
14+
- The panel no longer offers `navigation.view` and `sharing.type`: both are `retiredKey()` tombstones that the schema-derived child list used to render as editable rows. A stored value is untouched by a panel save (the composite editor spreads the block it was given).
15+
- The platform metadata-forms catalogs carry zh-CN, ja-JP and es-ES text for every new row, and the console's zh-CN overlay copies the zh-CN rows.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
'@object-ui/i18n': patch
4+
---
5+
6+
feat(app-shell): Studio edits a translation item as a source-to-translation table with its gaps counted
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
A `translation` item in Studio now opens on a table for its language: a row per string the package declares (objects, fields, options, apps, navigation, views, actions, dashboards and the rest), the source text beside the translation, grouped by item, with a count such as "37 of 120 untranslated" and an "Untranslated only" filter. The rows come from `collectExpectedEntries` in `@objectstack/lint`, the walk `os i18n extract` and `os lint` use, over the package's declared documents. The platform objects the package points at (for example the user object behind an owner lookup) are included, because their labels ship in a few languages only. A row also counts as translated when another bundle already serves the language at its key.
12+
13+
- Saving writes the same `translation` item to the same place as before (the `.custom` pair on a read-only package): each cell writes the item's JSON at its key. The item's label, language and description stay in the form above the table, and its JSON stays available as an advanced view for what the table does not list (messages, settings UI, metadata forms).
14+
- The "no custom renderer, editing as JSON" notice no longer appears on this page.
15+
- The metadata item list labels an item in a code package's `.custom` pair as customer-written, not as shipped in a code package.
16+
- Labels in English and Chinese.

0 commit comments

Comments
 (0)