Skip to content

Commit 498cdd7

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/project-thread-0pu6d9
2 parents 3c970bb + 81bba6c commit 498cdd7

325 files changed

Lines changed: 4434 additions & 3674 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: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@object-ui/components': patch
3+
'@object-ui/i18n': patch
4+
---
5+
6+
fix(components): a refused submit moves focus to the first invalid field and no longer toasts the field list over the dialog's title
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
- **Before.** A submit refused by field validation, on the client or by the server's `fields[]`, raised an error toast naming the fields ("Please check the highlighted fields: First name, Last name, Company…") on top of the message already written under each input. The toast cut its list after three names, and in a record create / edit dialog it was drawn over the title row.
12+
- **Now.** The form raises no toast for a refusal that every field carries inline. It scrolls to the first invalid field in form order and focuses it, and first activates that field's tab when it is on a background tab. The message under each input is the whole report.
13+
- **A field with nothing drawn to carry it.** When the server rejects a field that has no drawn input, for example one on a tab or section a `visibleWhen` predicate hides, the form shows the form-level banner and its toast with the server's sentence, the same path a rejection naming an unknown field already takes. The hidden tab is not activated.
14+
- **Earlier outcomes retire.** A refusal on the client now takes down the previous attempt's banner and toast, and a clear-on-hide notice, as an attempt that passes validation already did. Before, the refusal toast replaced them under the form's outcome id.
15+
- **`validation.formInvalid` removed.** The toast's sentence ("Please check the highlighted fields: {{fields}}") had no other reader, so it leaves the form's default map and all ten `@object-ui/i18n` locale packs. `validation.formInvalidJoiner` stays: the clear-on-hide notice, the faulted-`visibleWhen` refusal and the option-group hint still join field labels with it. A host bundle that overrides `validation.formInvalid` can drop the entry; nothing reads it.
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/console': patch
4+
'@object-ui/i18n': patch
5+
---
6+
7+
fix(app-shell,console): an invitee who opens the invitation link signed out is greeted for the invitation, offered "Create an account and join" first, and the accept page names the inviter
8+
9+
Clause-②: yes
10+
Metadata-protocol: none
11+
12+
- **Login page.** A signed-out visitor arriving at `/login?redirect=/accept-invitation/ID` used to see the returning-user card ("Welcome back · Sign in to continue your work") with a small "Sign up" link under the form. Both login pages (the console's own and `DefaultLoginPage`) now title the card "Accept your invitation · Use the email address the invitation was sent to." Where the server offers sign-up to this visitor, a full-width "Create an account and join" link (the new `InvitationSignUpPrompt` export) sits above the sign-in form in place of the small link. With sign-up switched off, the visitor gets the invitation header and the sign-in form only.
13+
- **Register page.** From an invitation redirect, both register pages title the form "Create an account to join" and ask for the address the invitation was sent to, because only that account can accept it.
14+
- **Accept page.** `DefaultAcceptInvitationPage` shows an "Invited by" row with the inviting member's email, which `GET /organization/get-invitation` already returns as `inviterEmail`. That route returns no inviter name.
15+
- **Not in this change.** The signed-out pages name no organization, inviter or invited address, and do not prefill the email. The only invitation read the server serves answers a signed-out caller `401`, so a preview for signed-out visitors needs a new server read first.
16+
- New locale keys in all ten packs: `auth.login.invitationTitle`, `auth.login.invitationDescription`, `auth.login.invitationSignUpButton`, `auth.login.invitationSignInDivider`, `auth.register.invitationTitle`, `auth.register.invitationDescription`, `organization.accept.invitedBy`.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@object-ui/plugin-map': patch
3+
'@object-ui/i18n': patch
4+
---
5+
6+
fix(plugin-map): a map whose style or tiles fail to load shows the record list with a translated notice, instead of a grey canvas under an English alert
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
- **`@object-ui/plugin-map`:** when MapLibre reports a style or tile load failure (an intranet or proxied deployment that cannot reach the tile host, an unreachable style URL), the map view now removes the map and lists its records in its place, the same list a browser without WebGL2 already got: searchable, and each row opens the record the way its marker did. A "Try the map again" button brings the map back. The notice above the list keeps MapLibre's reason and names a remedy that exists: a view with its own map style is told to check that URL, and a view on the public default style is told to ask an administrator to set a map style for the view. It no longer says the markers are "listed in the search box" or asks for a "custom map style for production use" setting that does not exist. That notice, the WebGL2 notice, the list's label and empty text, and the "records excluded for missing or invalid coordinates" count now read the translation bundle, so a zh-CN console shows them in Chinese.
12+
- **`@object-ui/i18n`:** eight new `element.map.*` keys in all ten packs.
13+
14+
What to do: nothing. A deployment-wide map style setting is not part of this change.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
'@object-ui/i18n': patch
3+
---
4+
5+
chore(i18n): delete 92 message keys nothing reads from all ten locale packs
6+
7+
Clause-②: yes (TranslationKeys narrows by 92 unread members; patch per the #4730 retirement precedent)
8+
Metadata-protocol: none
9+
10+
`ui/scripts/check-i18n-dead-keys.mjs` listed 122 keys with no call site and no textual occurrence anywhere in the repository. 92 of them are deleted from `ar`, `de`, `en`, `es`, `fr`, `ja`, `ko`, `pt`, `ru` and `zh`; no key is renamed or added, and no screen changes, because no code asked for any of them. The largest groups are `appDesigner.*` (20 keys), `report.*` (9), `publicForm.*` (8), `table.*` (7) and `layout.appSwitcher.*` (7).
11+
12+
Two groups the script also listed stay:
13+
14+
- 28 `_one` / `_other` plural forms (`preview.changes.typeCount.*`, `notifications.arrivalMany` / `arrivalRepeats`, `fields.relativeDate.overdue`). Their base keys are called with `count`, and i18next reads the plural form, so they are in use.
15+
- `console.ai.agentLabels.dataChat` and `metadataAssistant`, which the pack keeps on purpose for external overrides.
16+
17+
`TranslationKeys` (`typeof en`) and the other pack objects' types lose the 92 members. A host that reads one of them by property gets a type error; nothing in this repository does, and no `t()` call anywhere asks for one.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@object-ui/core': patch
3+
'@object-ui/plugin-form': patch
4+
'@object-ui/plugin-grid': patch
5+
---
6+
7+
feat(ui): an edit form's `state_machine` select offers only the moves the server accepts
8+
9+
Clause-②: yes
10+
Metadata-protocol: none
11+
12+
A record whose `status` is governed by an error-severity `state_machine` validation used to offer every option in the edit form, and the server refused the invalid ones only after submit, without naming the allowed next states. The form now offers the persisted value plus the states the machine declares as its next moves.
13+
14+
- **`@object-ui/core`:** new export `stateMachineNextValues(objectSchema, fieldName, currentValue)`. It returns the set of values a field may move to from its persisted value, or `null` for "don't constrain". It narrows only where the server refuses: rules with `severity: 'error'` (the default), `active` not `false`, and `events` covering `update` (the default covers it). A from-state the transition map does not declare stays unconstrained, and several applicable rules on one field intersect. It is a read of the declared transition map for choice controls, not a client-side rule engine.
15+
- **`@object-ui/plugin-form`:** `gateFormFields` takes an optional `previousValues` (the persisted record) and narrows each single-value select governed by such a machine, on both the entry's own `options` and its `field.options`. Every layout passes its persisted record: the simple, modal, drawer, tabbed, split and wizard forms. The from-state is the stored row, never the live form value. A create form is unconstrained, and the current value always stays offered. Options outside the reachable set are left out rather than drawn disabled.
16+
- **`@object-ui/plugin-grid`:** `stateMachineNextValues` is now re-exported from `@object-ui/core`. The grid's inline editor therefore stops narrowing on a `warning` / `info` machine, an inactive one, or one whose `events` leave out `update`. The server never refuses those moves, so the editor now offers every option for them.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
'@objectstack/account': patch
3+
'@objectstack/cli': patch
4+
'@objectstack/client': patch
5+
'@objectstack/client-react': patch
6+
'@objectstack/cloud-connection': patch
7+
'@objectstack/connector-imap': patch
8+
'@objectstack/connector-mcp': patch
9+
'@objectstack/connector-openapi': patch
10+
'@objectstack/connector-rest': patch
11+
'@objectstack/connector-slack': patch
12+
'@objectstack/console': patch
13+
'@objectstack/core': patch
14+
'@objectstack/driver-memory': patch
15+
'@objectstack/driver-mongodb': patch
16+
'@objectstack/driver-sql': patch
17+
'@objectstack/driver-sqlite-wasm': patch
18+
'@objectstack/driver-turso': patch
19+
'@objectstack/embedder-openai': patch
20+
'@objectstack/formula': patch
21+
'@objectstack/hono': patch
22+
'@objectstack/knowledge-memory': patch
23+
'@objectstack/knowledge-ragflow': patch
24+
'@objectstack/lint': patch
25+
'@objectstack/mcp': patch
26+
'@objectstack/metadata': patch
27+
'@objectstack/metadata-core': patch
28+
'@objectstack/metadata-fs': patch
29+
'@objectstack/metadata-protocol': patch
30+
'@objectstack/objectql': patch
31+
'@objectstack/observability': patch
32+
'@objectstack/organizations': patch
33+
'@objectstack/platform-objects': patch
34+
'@objectstack/plugin-approvals': patch
35+
'@objectstack/plugin-audit': patch
36+
'@objectstack/plugin-auth': patch
37+
'@objectstack/plugin-dev': patch
38+
'@objectstack/plugin-email': patch
39+
'@objectstack/plugin-hono-server': patch
40+
'@objectstack/plugin-pinyin-search': patch
41+
'@objectstack/plugin-security': patch
42+
'@objectstack/plugin-sharing': patch
43+
'@objectstack/plugin-webhooks': patch
44+
'@objectstack/rest': patch
45+
'@objectstack/runtime': patch
46+
'@objectstack/sdui-parser': patch
47+
'@objectstack/service-analytics': patch
48+
'@objectstack/service-automation': patch
49+
'@objectstack/service-cache': patch
50+
'@objectstack/service-cluster': patch
51+
'@objectstack/service-cluster-redis': patch
52+
'@objectstack/service-datasource': patch
53+
'@objectstack/service-i18n': patch
54+
'@objectstack/service-job': patch
55+
'@objectstack/service-knowledge': patch
56+
'@objectstack/service-mailbox': patch
57+
'@objectstack/service-messaging': patch
58+
'@objectstack/service-package': patch
59+
'@objectstack/service-print': patch
60+
'@objectstack/service-queue': patch
61+
'@objectstack/service-realtime': patch
62+
'@objectstack/service-settings': patch
63+
'@objectstack/service-sms': patch
64+
'@objectstack/service-storage': patch
65+
'@objectstack/setup': patch
66+
'@objectstack/skills': patch
67+
'@objectstack/spec': patch
68+
'@objectstack/studio': patch
69+
'@objectstack/trigger-api': patch
70+
'@objectstack/trigger-record-change': patch
71+
'@objectstack/trigger-schedule': patch
72+
'@objectstack/types': patch
73+
'@objectstack/verify': patch
74+
'create-objectstack': patch---
75+
76+
chore(packages): publishing metadata — per-format types in `exports`, declared `sideEffects`, and a README for the 18 published packages without one
77+
78+
Clause-②: no
79+
Metadata-protocol: none
80+
81+
Measured on a fresh `origin/main` build of all 73 published packages outside `ui/`, each staged as `npm pack` would ship it, with publint 0.3.25 and @arethetypeswrong/cli 0.18.5. Before: 73 of 73 packages carried at least one publint message and 48 carried an attw problem. After: 3 packages carry a publint message and 16 carry an attw problem, each remaining class needing a change this one deliberately does not make — an export-map shape change, or a dual-build fix in `@objectstack/core`.
82+
83+
- **Types per module format.** On 38 manifests one `types` entry served both formats, so a TypeScript consumer importing the ESM build was handed the CJS declarations — every one of attw's 38 `FalseCJS`. Each `{types, import, require}` entry becomes `{import: {types, default}, require: {types, default}}` pointing at the declaration file the same tsup run already emits for that format. No subpath is added or removed, and no JavaScript target moves. `@objectstack/core` keeps its single `types` entry: its `.d.ts` and `.d.cts` declare the same classes with private members, so serving them per format gives a consumer that reaches `core` through both resolution modes two incompatible `ObjectKernel` types, which is `@objectstack/plugin-dev`'s declaration build (it awaits `import('@objectstack/objectql')` inside a CommonJS build). Its `FalseESM` therefore stays, measured and unfixed here.
84+
- **`sideEffects` on the 72 manifests that declared none**, read per package rather than set in bulk: `@objectstack/service-cluster-redis` registers its `redis` cluster driver at module load and `create-objectstack`'s bin reaches its program through a bare import, so both declare their entry files side-effectful; everything else is `false`.
85+
- **`publishConfig: { access: 'public' }`** on the 17 that had none, the value the other 56 already declare.
86+
- **`type`** on the 39 that shipped `.js` without declaring a format — every `.js` under their `dist/` was read first and is CommonJS, which is what the absent field already meant — **`engines.node >= 22.0.0`** on the 22 that had no `engines`, and **`repository.url`** as the full `git+https://` git URL on 71.
87+
- **A README for 18 published packages that had none**: one paragraph, the first import a reader writes, and a link to the package's docs page. They are the pages npm renders, and for these 18 npm rendered nothing.

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,12 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
167167

168168
- 表未覆盖的包首次分诊时归类并走 PR 更新本表;新增或退役 `domain:*` 必须同批改本表。
169169
- 退役 `domain:*` 只退流通,对象保留;`domain:engine`/`domain:services`/`domain:cli` 读作 `domain:server`。
170-
- `domain:*` 只由分诊席产出,例外一:在飞卡衍生 sub-issue 承父卡域;无标签的卡 ⛔ 不得认领。
171-
- 预贴标签只是建议,队列与级别只由分诊落笔(例外一同承);无分诊审计评论 ⛔ 不得认领。
170+
- `domain:*` 只由分诊产出,两例外:sub-issue 承父卡域、main-red 锚卡;无标签的卡 ⛔ 不得认领。
171+
- 预贴标签只是建议,队列与级别只由分诊落笔;无分诊审计评论 ⛔ 不得认领;两例外豁免。
172172
- 跨域例外路径:拆不动的跨域单 PR 由分诊席指定一个车道 PM 认领,认领评论申报文件面。
173173
- 派发前在飞检查:读 `pm:dispatched` 卡认领评论申报的文件面,本地求交、不另发查询。
174174
- 跨域例外路径的范围加上该单文件面触及各域的在飞单;相交 ⇒ 排该 PR 之后串行或让行。
175-
- 跨域相交只经三条越界通道:跨域例外路径、认领席跟到底的越界面、接手无主阻塞项。
175+
- 越界只四通道:跨域例外路径、认领席跟到底的越界面、接手无主阻塞项、main-red 锚卡。
176176
- 合并队列是共享串行资源:车道买到的是并行编写,不是并行落地。
177177
- 谁发现 flake 谁修或立单,⛔ 不绕行。
178178

‎.claude/skills/pm-dispatch/references/execution-duties.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- 整车道一次读全,本地求交:`list_issues` 带 `labels: [domain:X]` + 最小字段拿回全车道 open 集。
88
- 候选 = open、未 assign、无 `needs-user-decision`、无 `pm:retriage`;⛔ 排除三门皆无的 `tooling` 卡。
99
- `tooling` 卡至多占一轮派发的 10%,溢出留积压、⛔ 不入 `pm:queue`;⛔ 无门禁无脚本强制。
10-
- 无分诊审计评论的卡不是候选,预贴 `pm:queue` 视同无;例外一的 sub-issue 承父卡首触。
10+
- 无分诊审计评论即非候选;例外:sub-issue 承父卡首触,main-red 锚卡见 `landing-operations.md`。
1111
- 已排队父单的 open sub-issue 自动是候选,`pm:epic` 父单的子树除外。
1212
- 每张候选读全文 + 全部评论,写派发词前做决策复读:评论读到最后一页。
1313
- 维护者裁决逐字引入派发词裁决分区作约束,无则写明无裁决。
@@ -37,7 +37,7 @@
3737
- 阻塞解除后延后单重定价:前一单派发词必答 #X 变简单、变难、不必要或无影响。
3838
- 派发后一单前用该回答重读它的选项与成本,⛔ 不沿用立单时那份。
3939
- 在飞卡衍生三分:不修它验收过不过;in-scope ⇒ 父卡 sub-issue,认领席自有、优先级继承。
40-
- 该 sub-issue 带父卡域与优先级直接派发,绕过分诊;sweep 事后扫,重复关 `duplicate`。
40+
- 该 sub-issue 与 main-red 锚卡各带域与级直接派发,绕过分诊;sweep 事后扫,重复关 `duplicate`。
4141
- 排队卡含他车道项 ⇒ 发现席自拆:新卡无 `domain:*`,首行 `carries item k of #N; #N keeps items …`。
4242
- 分诊首触定域可改判;拆出卡 ⛔ 不承父卡域(承域只及本车道 sub-issue),父卡余项照 `Fixes`。
4343
- 自在飞派发升级出的卡首行一句:本卡承哪一半、父卡留哪一半;缺此行不入队不入箱。

‎.claude/skills/pm-dispatch/references/landing-operations.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@
5858
- 落地评论 = 两个读数的探针表 + 一行状态变更(摘标/关卡/收口),⛔ 不复述 `## 席位核对`。
5959
- 契约复核 PASS 落地的 PR 到窗口时已 ready 且 auto-merge 在挂,见 `contract-review.md`。
6060
- 转 ready/入队前跑 `check-governed-merges.mjs --pr N`:受管面照两层;>3000 行(含生成物)照 Tier H。
61-
- 受管路径全在 `.claude/**` 者 Tier S:席内达档复核过落地前检两条即转正式入队。
62-
- Tier H(其余受管面)者:四件套留 draft 等人批,⛔ 不翻正式不入队;获授权批准后认领席落地。
6361
- ⛔ 两层不由席位批准;清标即落地同受此闸,漏判会被队列守卫在 merge group 里拒收。
6462
- 再读 `mergeable_state`:`dirty` ⇒ 先 merge `origin/main` 再挂;生成物在面上按 A 的固定序。
6563
- 挂 auto-merge 的同一动作里重测生成物漂移,⛔ 不复用更早的零;非零 ⇒ 按 A 的固定序。
@@ -79,8 +77,10 @@
7977
- MERGED 或关闭即退订,同刻把 `mode:cloud` 派的会话 `archive_session`。
8078
- 触发条件是卡终局且报告已收复核;⛔ 合并前不归档,误归档可 unarchive 但容器现场已失。
8179
- 暂停或交接时把在挂订阅清点进座位贴,⛔ 不留孤儿订阅。
82-
- main-red 约定①:p0 fix-forward 允许跳队,限 p0、机械、根因已核实的止血 PR。
83-
- 也可按既有 governed 例外由维护者人工直合一行修复;仅限 main-red 修复。
80+
- main-red 约定①:见主干/队列全量红的席位先找锚卡,无则立 p0 锚卡(门类 ①),域随失败面。
81+
- 认领并派止血,⛔ 不等分诊首触、不等维护者;首触事后补,可改域、⛔ 不改动作。
82+
- 首道止血 = 回退引入红的提交(主干末绿与首红之间找),根因另立卡。
83+
- p0 fix-forward 止血跳队,限机械、根因已核实;维护者可按 governed 例外人工直合一行修复。
8484
- main-red 约定②:一个失败 check 只锚一张卡,先立者赢,后见者评论到锚卡,⛔ 不另立。
8585

8686
## C. 依赖前棒才能转绿的 PR:draft 停放 + 签名级预期红清单

0 commit comments

Comments
 (0)