Skip to content

feat(types,sdui-parser): ComponentInput.type 可声明联合,五个标本停止对合法写入告警 (#3832) - #4975

Merged
yinlianghui merged 4 commits into
mainfrom
claude/issue-3832-componentinput-union
Aug 17, 2026
Merged

feat(types,sdui-parser): ComponentInput.type 可声明联合,五个标本停止对合法写入告警 (#3832)#4975
yinlianghui merged 4 commits into
mainfrom
claude/issue-3832-componentinput-union

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #3832

按 2026-08-09 维护者裁定方向 (a):ComponentInput.type 学会表达联合,checkType 任一臂命中即过,三处声明位同移,消费者同 PR 跟进,五个实测标本改声明真实联合。

本正文里的诊断消息把尖括号写成 < tag >(带空格):GitHub 的正文净化器会把「< 紧跟字母」当 HTML 标签吃掉,原始消息里没有这个空格。

前提验证(先做,后写码)

卡正文给的行号已漂移,先重定位并实测:

卡里写的 实际(1b21b1aaa)
packages/types/src/base.ts:215 :357(接口)/ :366(type 那一行)
packages/types/src/plugin-scope.ts:172 :170 / :172
validate.ts:106-142 checkType 位置未变,逻辑与卡里描述一致
containers.tsx:1584 / :703 :1696 / :753

卡正文说「两声明位」,实际是三处 —— 第三处 packages/core/src/registry/Registry.ts:14 才是所有组件注册真正 import type { ComponentInput } 的那一份。漏掉它的话五个标本连编译都过不去。另外 packages/types/src/zod/base.zod.tsComponentInputSchema 是这个契约被强制的那一半,也必须同步。四处都改了,结构副本本身另立 finding(见下)。

五个标本的当前告警,用 app 真正搭 manifest 的那对函数(manifestFromConfigs + validateTree,与 page.tsx:462kind:'jsx' 编译同一条路)实测:

page:header.title       (i18n map) -> warning/type-mismatch: < page:header > prop "title" expected a string
page:header.subtitle    (i18n map) -> warning/type-mismatch: < page:header > prop "subtitle" expected a string
page:card.title         (i18n map) -> warning/type-mismatch: < page:card > prop "title" expected a string
record:alert.title      (i18n map) -> warning/type-mismatch: < record:alert > prop "title" expected a string
record:alert.body       (i18n map) -> warning/type-mismatch: < record:alert > prop "body" expected a string
element:text_input.defaultValue (42) -> warning/type-mismatch: < element:text_input > prop "defaultValue" expected a string

前提成立(premise_still_valid: true),六个键全部复现。

「五个标本」= 卡里那张表的五行(第三行 record:alert.title / .body 是一行两个键),共六个键

spec 侧同时实测(ComponentPropsMap,pin 在 @objectstack/spec 17.0.0-rc.6):

  • page:header.title / .subtitle / page:card.titlestring=OK i18n-map=OK number=no boolean=no,即 string-or-record 联合;
  • element:text_input.defaultValuestring=OK number=OK i18n-map=no boolean=no;
  • record:alertComponentPropsMap 里没有这个块,所以这两个键的第二条臂不是对 spec 得来的,是对渲染器得来的:renderers/record-alert.tsx:126-127 两个键都过 pickLocalized。这一点在代码注释里写明了,不装作有 spec 依据。

编码选择:type 收数组,而不是新增 types?: ControlType[]

裁定把编码留给实施者,硬约束是「既有单字符串形态保持合法」。两个选项都满足,选 type: ControlType | ControlType[],理由:

  1. 一个事实一个位置。 types?: 会让同一件事有两处拼法,并且可以互相矛盾(type: 'string', types: ['number'] 语法完全合法)—— 要么再加一条「types 必须包含 type」的规则去缝,要么留一个二义的发布面。这正是 AGENTS.md #0.1 反对的第二种方言,只不过这次两种方言在同一个对象里。
  2. AI 作者写错的成本。 数组形态下作者只能写出一个答案;types?: 下最自然的写法是两处都写(冗余),而冗余的两处一定会漂。
  3. 契约面反而更小。 types?:新增一个已发布字段,老消费者读 type 会静默拿到「一条臂」,永远看不见另一条 —— 与今天的错误行为完全一样,只是从此变成设计。数组形态下老消费者的 switch (input.type) 拿到数组会掉进 default,行为是「不报告」而不是「报错」——所以我把每一个读点都找出来改了(见下),而不是指望类型报错;这一点在变异 ① 里被实测钉住了。

三条约束把「向后兼容扩展」做成可测的事实:

  • 单字符串形态零行为变化:单臂诊断逐字不变(invalid-enum 及其 error severity 也不变);
  • 序列化折叠:manifestFromConfigs 把单元素数组折回裸字符串,所以已发布 sdui.manifest.json 里每一个既有条目序列化结果不变,数组只出现在真正声明了联合的地方(实测:全公开面共 5 个联合条目,就是那五个公开层标本键,其余一个不动);
  • zod 收紧而不是放宽:数组必须非空互异。空臂表声明了一个谁也满足不了的 input(序列化还得替作者发明一条臂),重复臂说明作者以为自己说了什么而没说 —— 在创作期响,而不是被悄悄归一化。

联合放宽的是「什么算合法」,不是把检查关掉:不命中任何一条臂照旧报告;多臂不命中时按最严的那条臂的 severity 报告(含 enum 臂 → error,否则 warning),这样「在 enum 旁边加一条臂」不能把 enum 的封闭表降级成可忽略的 warning;code 用 type-mismatch(报告的事实是「不命中任何已声明的臂」),消息里带上 allowed 值,作者仍看得到那张表。

消费点清单

按「谁读 ComponentInput.type / ManifestInput.type」扫出来的,不按包猜。

# 消费点 处置
1 packages/sdui-parser/src/validate.ts checkType 已适配 —— 拆成 armAccepts / armExpectation,任一臂命中即过;'slot' 与词表外的臂照旧接受一切(保住原 default: return null 分支)
2 packages/sdui-parser/src/index.ts manifestFromConfigs 已适配 —— 原 INPUT_TYPES.has(i.type) ? i.type : 'string' 换成 canonicalizeInputType(折叠单臂、去重、保序、丢弃词表外臂)
3 packages/sdui-parser/src/codegen.ts generateDts(emitInterface 的 slot 过滤 + tsType) 已适配 —— 联合产出 TS 联合并按 TS 类型去重;slot 过滤从 i.type !== 'slot' 改成「有没有非 slot 臂」(旧写法会让 ['slot','string'] 漏过过滤,再被 tsType 的 default 兜成 string)
4 packages/sdui-parser/src/codegen.ts generateBlockList 结构上无需适配 —— 只读 name / required / binding
5 packages/sdui-parser/src/types.ts ManifestInput.type 声明位,已扩
6 packages/sdui-parser/src/index.ts RegistryConfigLike.inputs[].type 已适配 —— string → `string
7 packages/types/src/base.ts ComponentInput.type 声明位,已扩 + 新增 ComponentInputControlType(臂词表,唯一一份)
8 packages/types/src/plugin-scope.ts ComponentInput.type 声明位,已扩 —— 臂词表 import 自 base.ts,不再复制那 11 个字面量
9 packages/core/src/registry/Registry.ts ComponentInput.type 声明位,已扩 —— 注册真正用的就是这一份,同样 import 臂词表
10 packages/types/src/zod/base.zod.ts ComponentInputSchema.type 已适配 —— union(单臂 / 非空互异数组),并导出 ComponentInputControlTypeSchema
11 packages/components/src/renderers/layout/page.tsx:464(kind:'jsx' 页面编译) 结构上无需适配 —— 把 meta?.inputs 原样交给 manifestFromConfigs,归一化在 #2 完成
12 packages/sdui-parser/scripts/gen-manifest.ts / scripts/dump-public-manifest.mjs 结构上无需适配 —— 只做 getPublicConfigs()manifestFromConfigs → 写文件
13 designer 面板(plugin-designerPropertyEditor / PageDesigner / ReportDesigner / ProcessDesigner / DataModelDesigner) 结构上无需适配 —— 且这一条是实测,不是假设:PropertyEditor 有自己的词表('text' | 'number' | 'boolean' | 'select' | 'color' | 'textarea',与粗类型词表不是一个东西),PageDesignerpropertyFields 是硬编码的 label/x/y/width/height。全仓 \.inputs\b 扫描下,designer 侧没有任何一处读注册的 inputs —— 也就是说裁定里点名的「designer 面板」在今天的代码里根本没有连上这个字段。这本身是另一个形状的问题(设计器不消费发布面),不在本卡范围
14 packages/types/src/widget.ts WidgetInput.type 不在本卡范围 —— 另一个类型(widget 注册面),不经 checkType / manifest;结果是 widget 面现在比组件面窄一条臂,记进 finding #4972

发布产物没有需要重新生成的已提交基线:sdui.manifest.json / sdui-intrinsics.d.ts / sdui-blocks.md 全部是构建期由浏览器 dump 产出的,仓库里不存在提交版本(已确认)。产物变化面实测:公开面 5 个条目获得数组形态,PageHeaderProps / PageCardProps / RecordAlertProps 三个接口的相应键变成 string | Record< string, unknown >,其余逐字不变。

五标本前后告警对照

改后声明 合法写入(改前) 合法写入(改后) 对照(不命中任何臂,改后)
page:header.title ['string','object'] warning/type-mismatch … expected a string CLEAN title={true} → 照旧 type-mismatch
page:header.subtitle ['string','object'] 同上 CLEAN subtitle={42} → 照旧报
page:card.title ['string','object'] 同上 CLEAN title={['Account']} → 照旧报
record:alert.title ['string','object'] 同上 CLEAN title={7} → 照旧报
record:alert.body ['string','object'] 同上 CLEAN 同上
element:text_input.defaultValue ['string','number'] warning/type-mismatch … expected a string CLEAN(42,尤其配 inputType: 'number') defaultValue={true}defaultValue={{ en: … }} → 都照旧报(spec 在这个键上拒绝映射,所以故意不给 object 臂)

臂要对齐契约,不是用来放宽门的。同族里刻意不动的一个:element:record_picker.emptyText 保留单 'string' 臂 —— 契约确实是联合,但该渲染器把值直接塞进文本节点、不做 locale 解析(#4163),声明一条渲染器丢掉的臂等于广告一个到不了屏幕的形状。它原来的注释把窄化归因于「类型表达不了」,那条理由现在不成立了,已改写成真正的理由;标本测试里也为它留了一条反向断言。

测试

新增两个文件,分工不同:

  • packages/sdui-parser/src/__tests__/input-type-union.test.ts —— 机制面(任一臂、对照、消息、最严 severity、slot、单臂逐字不变、canonicalizeInputType 的折叠/去重/丢弃、generateDts 的联合产出、整条 compile 管线);
  • apps/console/src/__tests__/component-input-union-specimens.test.ts —— 用户可见验收面,走 console 真正注册的 registry。每个标本都配一条对照断言(不命中任何臂必须仍然报告),这不是装饰:变异 ① 实测出来,只撤回 checkType 的任一臂逻辑时,正向断言会因为什么都没产出而继续绿,红的只有对照。

改动的既有 fixture,逐个判处置(不是批量重拼):

  • packages/components/src/__tests__/text-input-inputs-spec-parity.test.ts —— 整条替换。它原来钉的就是我删掉的那条肢:expect(input('defaultValue')?.type).toBe('string'),注释里写着这是有意的窄化。把它改指向新值只会钉住声明、而放掉它存在的理由(两条臂必须就是 spec 接受的那两种),所以改成把臂当集合、对 spec 的 safeParse 裁决逐条比对 —— 任一侧动了都红。
  • packages/components/src/__tests__/record-picker-inputs-spec-parity.test.tsapps/console/src/__tests__/registry-inputs-spec-parity.test.ts 文件头、packages/layout/src/index.ts 注释 —— 只改叙述:这三处都把「ComponentInput.type 表达不了联合」当事实在讲,断言不受影响。console 那条尤其重要:它列的是这个门检查什么,表达力这一半现在关掉了,而比对那一半没有,新的真相与 finding [finding] 声明的粗类型「臂」没有任何门禁与 spec 比对 —— #3832 让臂可写之后,一条假臂能让 manifest 门放行 spec 拒绝的值,且全绿 #4971 一起写在那里。

按规则的消费半径扫 fixture(不按包扫):manifestFromConfigs / validateTree / generateDts 的调用点共 21 个文件,跨 packages/sdui-parserpackages/componentspackages/layoutpackages/plugin-chartsapps/consoleexamples/schema-catalogscripts/,全部跑过。

pnpm exec vitest run packages/sdui-parser/                                  → Test Files 6 passed,   Tests 42 passed
pnpm exec vitest run apps/console/.../component-input-union-specimens       → Test Files 1 passed,   Tests 6 passed   (改前:4 failed | 2 passed)
pnpm exec vitest run packages/types/ packages/sdui-parser/ packages/layout/ examples/schema-catalog/
                                                                            → Test Files 69 passed,  Tests 2248 passed
pnpm exec vitest run packages/components/src/__tests__/ packages/plugin-detail/ packages/core/src/registry/
                                                                            → Test Files 171 passed, Tests 1642 passed
pnpm exec vitest run apps/console/.../public-block-binding-reach + registry-inputs-spec-parity + plugin-charts
                                                                            → Test Files 3 passed,   Tests 83 passed
pnpm exec tsx packages/sdui-parser/verify.ts                                → exit 0
pnpm exec turbo run type-check --concurrency=2                              → Tasks 81 successful, 81 total
node scripts/check-control-bytes.mjs                                        → OK (4432 tracked text files)
node scripts/check-doc-component-types.mjs                                  → OK(manifest 生成侧的门,不红)
node scripts/check-changeset-presence.mjs / check-changeset-no-major.mjs     → OK
node scripts/check-spec-symbol-derivation.mjs / check-package-self-import.mjs → OK

三条变异记录(先书面预判,后跑;变异前已 commit,还原用 git checkout)

① 把 checkType 的任一臂逻辑撤回单臂 switch(保留数组声明)。
预判(刻意不是「前绿后红」):正向断言会继续绿,而且是空绿 —— switch (input.type) 拿到数组不匹配任何 case,掉进 default: return null,那个 prop 什么都不产出;红的应该是对照断言。
实测:9 条红。四个标本的失败点逐个落在对照行(specimens.test.ts:104 / :122 / :142 / :164),报的都是 AssertionError: expected [] to include 'type-mismatch' —— 空数组,即什么都没产出。机制面同时红在「不命中任何臂仍报告」「消息列出每条臂」「一个 prop 一条诊断」「含 enum 臂时最严 severity」「compile 管线」。预判命中,这也正是「对照断言不是装饰」的实测依据。

② 向后兼容对照:把五处标本声明还原成单字符串,保留新代码。
预判:全部既有测试保持绿(单字符串形态在新代码下零行为变化),只有本卡新增的臂断言红。
实测:Test Files 2 failed | 117 passed,Tests 5 failed | 2624 passed —— 红的 5 条全部是本卡的臂断言(4 条标本 + 改写后的 text-input 那条)。2624 条既有断言无一变化,其中包含所有老 manifest fixture:examples/schema-catalog 的 pageheader 门、packages/layoutinvalid-enum severity 钉子(#3985)、sdui-parser 的 compile / tier / render、components 的各 parity 测试。预判命中

③ 给标本声明一条假臂(spec 不接受的 type)。两半答案不同,如实记录。
预判:「联合不是放行一切」这半成立(不命中任何臂照旧报告);但「臂对齐契约」这半今天没有门禁,所以有 per-block spec 断言的键会红、没有的键会全绿。
实测:

  • ③a element:text_input.defaultValue'object' 臂 → ,expected [ 'number', 'object', 'string' ] to deeply equal [ 'number', 'string' ](本 PR 改写的那条 per-block 断言把臂当集合对 spec 比对)。
  • ③b page:card.title'number' 臂 → 全绿(Test Files 93 passed, Tests 856 passed)。同一次变异下门的行为:string/i18n map/number 都 CLEAN(数字标题被放行,而 spec 拒绝它),booleanarray 照旧 type-mismatch … expected a string or an object or a number

即联合确实不是放行一切,但「臂是否对齐契约」靠的是 per-block 纪律而不是门禁。预判命中,并且这半个空缺单独立了 finding #4971 —— 没有塞进本 PR 顺手扩围。

changeset

.changeset/component-input-type-union-arms.md,types / core / sdui-parser / components / plugin-detail 全部 minor。发布面扩展(不是破坏):单字符串形态保持合法、诊断逐字不变、单臂序列化字节相同 —— 按 AGENTS.md「objectui 不声明 major」的固定组规则,扩展记 minor(与 #3985 同档)。packages/layout 只动了一行注释,不单独记 bump。

顺手发现的相邻缺陷(都立卡,不并入本 PR)

PR #3795 的 member-shape 姊妹题没有并入(ComponentInput 依然是扁平的,数组/对象 input 的成员形状仍只能写在 description 里)—— 那是另一维,本卡只动同一层的类型本身。

草稿状态,等 PM 验收后再 undraft。


Generated by Claude Code

`ComponentInput.type` 只能承载一个粗类型,而 spec 有一批键接受多种形状。
声明只能挑一条臂,于是本仓自己的 manifest 门就对另一条臂的合法值报
`type-mismatch` —— 其中四个标本是最刺眼的形状:input 自己的 description
教作者写内联翻译映射,同一个 input 的 `type: 'string'` 又让 `checkType`
对这个映射告警。severity 是 warning,所以页面照样编译渲染,代价是正确
写入上的噪音会训练作者(含 AI 作者)忽略真的 `unknown-prop` /
`type-mismatch`。

按 2026-08-09 维护者裁定方向 (a):`type` 除单个粗类型外还接受粗类型
**数组**,任一臂命中即过。三处声明位(types 的 base.ts / plugin-scope.ts
与 core 注册表自己的那份)同移,`ComponentInputSchema` 同步收紧为
非空、互异的臂数组 —— 空臂表或重复臂在创作期就被拒,而不是被悄悄归一化。

五处声明改为契约的真实形状,这五条合法写入上的 `type-mismatch` 消失:
`page:header.title` / `.subtitle`、`page:card.title`(字符串或内联翻译
映射,对 rc.6 的 `ComponentPropsMap` 实测,渲染器两条臂都过
`pickLocalized`)、`record:alert.title` / `.body`(同两种形状;固定的
spec 不带 `record:alert` props schema,故依据渲染器)、
`element:text_input.defaultValue`(`string | number`,原先窄化为
`'string'` 并只在 description 里点出 number 臂)。

向后兼容:单字符串形态保持合法且仍是单臂键的规范拼法 —— 校验行为逐字
不变(单臂诊断连 `invalid-enum` 及其 error severity 都是字节相同),
`manifestFromConfigs` 把单元素数组折回裸字符串,所以已发布
`sdui.manifest.json` 里的既有条目序列化结果不变,数组只出现在真正声明了
联合的地方。`generateDts` 同 PR 跟进,联合输入产出 TS 联合类型,作者
type-check 的 .d.ts 与门接受的形状一致。

联合放宽的是「什么算合法」,不是把检查关掉:不命中任何一条臂照旧报告,
多臂不命中按最严的那条臂的 severity 报告(含 `enum` 臂时为 error),
并且臂要对齐契约而非放宽门 —— `element:text_input.defaultValue` 故意
不加 `object` 臂(spec 在该键上拒绝映射),`element:record_picker.emptyText`
保留单 `'string'` 臂(该渲染器丢掉映射形态,objectui#4163)。

Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 24.7 KB 350 KB
Entry file index-CEnx7c_C.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 9.56KB 3.59KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 8.92KB 3.41KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 25.13KB 5.40KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.79KB
auth (createAuthenticatedFetch.js) 6.34KB 2.43KB
auth (index.js) 2.71KB 1.22KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.02KB 0.88KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 498.83KB 111.26KB
core (index.js) 4.06KB 1.61KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 157.40KB 43.42KB
fields (index.js) 233.27KB 58.22KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.35KB 1.38KB
i18n (pickLocalized.js) 3.69KB 1.73KB
i18n (provider.js) 23.12KB 7.62KB
i18n (useDisplayLocale.js) 2.84KB 1.45KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 39.16KB 10.97KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 9.35KB 3.31KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 4.42KB 1.42KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.81KB 0.83KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.62KB 12.83KB
plugin-charts (index.js) 64.75KB 18.37KB
plugin-chatbot (index.js) 181.21KB 43.14KB
plugin-dashboard (index.js) 127.85KB 32.73KB
plugin-designer (index.js) 212.39KB 42.83KB
plugin-detail (index.js) 239.93KB 60.02KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 120.42KB 29.03KB
plugin-gantt (index.js) 164.10KB 39.87KB
plugin-grid (index.js) 197.58KB 53.00KB
plugin-kanban (index.js) 52.72KB 14.54KB
plugin-list (index.js) 111.23KB 26.97KB
plugin-map (index.js) 17.91KB 5.72KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 41.97KB 11.33KB
plugin-timeline (index.js) 26.68KB 7.66KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 83.81KB 20.49KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 27.53KB 9.41KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.28KB 0.68KB
react (schema-input.js) 1.45KB 0.83KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (index.js) 4.77KB 2.16KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 10.76KB 3.17KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 6.92KB 2.40KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 3.05KB 1.52KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Collaborator Author

合并顺序提示(与 PR #4967 / #3809 的一处文本重叠)

两个 PR 都动 apps/console/src/__tests__/registry-inputs-spec-parity.test.ts,但改的是不同的事,没有重复实施:

两处在同一个 JSDoc 列表里且只隔两行,所以后合的那个必然遇到冲突,而且冲突长得像「一段散文改了两次」,很容易被顺手取一边。正确的解法是两半都要:

我这边不做规避性改动(把这条留在原文=在仓里留一句本 PR 刚证伪的话)。PM 决定合并顺序即可,先合哪个都行。


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

已 merge origin/main(4249142c3),并在新 pin 上重测了一遍 —— 三条 CI 红是 main 侧的,不是本 PR 的

首轮 CI(head 6d6865d99):Type Check ✅、Build & E2E ✅、Changeset Fixed Group ✅、Control Bytes ✅、Doc Component Types ✅、Test (shard 4/4) ✅;shard 1 / 2 / 3 ❌。

三条红逐条归因,全部跨三个本 PR 一行都没碰的包:

shard 失败 归因
1 packages/cli/.../app-generator.test.tslucide-react expected '^1.29.0' to be '^1.31.0'(2 条) dependabot #4946 只移了仓内区间,没移生成器模板
2 packages/create-plugin/.../templates.test.ts@testing-library/jest-dom expected '^7.0.0' to be '^7.0.1' dependabot #4948,同一形状
3 packages/fields/.../FilterConditionField.operators.test.tsexpected [ '$like', '$ilike' ] to deeply equal [] main 把 @objectstack/spec 推到 ^17.0.0 GA;已开卡 #4911

判据(不是推断):这三个文件在 merge 之前的本分支上全绿 —— Test Files 3 passed, Tests 105 passed;merge origin/main 之后同一条命令在本地复现出同样 4 条失败。差集只有 main 的 pin 前移。前两条记进了 #4974(那一族的持有卡,#4098 是上一轮同缺陷、已关),没另立孪生卡。

**顺带一个真问题被这次 merge 暴露出来并已处理:**本 PR 的 spec 侧证据原本测在 17.0.0-rc.6,而 main 已经换成 GA。pin 变了,证据就得重测,否则等于拿一个不再存在的 pin 上的结论去合并。GA(17.0.0,ComponentPropsMap 37 条)上重测,六个键的裁决与 rc.6 逐字相同:

page:header.title        string=OK  i18n-map=OK  number=no  boolean=no  array=no
page:header.subtitle     string=OK  i18n-map=OK  number=no  boolean=no  array=no
page:card.title          string=OK  i18n-map=OK  number=no  boolean=no  array=no
record:alert.title/.body -> 仍然 NO SPEC SCHEMA(GA 也不带 record:alert,所以那两条臂依据渲染器的判断不变)
element:text_input.defaultValue  string=OK  number=OK  i18n-map=no  boolean=no  array=no

所以五处声明的臂在两个 pin 上都正确,element:text_input.defaultValue 故意不加 object 臂这一条在 GA 上同样成立。

merged tree 上的完整重验证:

pnpm exec vitest run packages/sdui-parser/ packages/types/ packages/components/src/__tests__/ packages/layout/
  packages/plugin-detail/ examples/schema-catalog/ apps/console/.../component-input-union-specimens
  apps/console/.../registry-inputs-spec-parity
                                              → Test Files 238 passed,  Tests 3867 passed
pnpm exec turbo run type-check --concurrency=2 → Tasks 81 successful, 81 total
node scripts/check-control-bytes.mjs           → OK (4439 files)
node scripts/check-changeset-presence.mjs      → OK (21 src files / 7 released packages / 1 changeset)

merge 冲突:无(main 的改动集中在 package.json / lockfile / 另外几个包,与本 PR 的 22 个文件不相交)。与 PR #4967registry-inputs-spec-parity.test.ts 文件头的那处文本重叠仍然存在,处置见上一条评论。


Generated by Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 24.7 KB 350 KB
Entry file index-CEnx7c_C.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 9.56KB 3.59KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 8.92KB 3.41KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 25.13KB 5.40KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.79KB
auth (createAuthenticatedFetch.js) 6.34KB 2.43KB
auth (index.js) 2.71KB 1.22KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.02KB 0.88KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 498.83KB 111.26KB
core (index.js) 4.06KB 1.61KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 157.40KB 43.42KB
fields (index.js) 233.27KB 58.22KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.35KB 1.38KB
i18n (pickLocalized.js) 3.69KB 1.73KB
i18n (provider.js) 23.12KB 7.62KB
i18n (useDisplayLocale.js) 2.84KB 1.45KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 39.16KB 10.97KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 9.35KB 3.31KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 4.42KB 1.42KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.81KB 0.83KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.62KB 12.83KB
plugin-charts (index.js) 64.75KB 18.37KB
plugin-chatbot (index.js) 181.21KB 43.14KB
plugin-dashboard (index.js) 127.85KB 32.73KB
plugin-designer (index.js) 212.39KB 42.83KB
plugin-detail (index.js) 239.93KB 60.02KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 120.42KB 29.03KB
plugin-gantt (index.js) 164.10KB 39.87KB
plugin-grid (index.js) 197.58KB 53.00KB
plugin-kanban (index.js) 52.72KB 14.54KB
plugin-list (index.js) 111.23KB 26.97KB
plugin-map (index.js) 17.91KB 5.72KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 41.97KB 11.33KB
plugin-timeline (index.js) 26.68KB 7.66KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 83.81KB 20.49KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 27.53KB 9.41KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.28KB 0.68KB
react (schema-input.js) 1.45KB 0.83KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (index.js) 4.77KB 2.16KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 10.76KB 3.17KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 6.92KB 2.40KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 3.05KB 1.52KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 24.7 KB 350 KB
Entry file index-CEnx7c_C.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 9.56KB 3.59KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 8.92KB 3.41KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 25.13KB 5.40KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.79KB
auth (createAuthenticatedFetch.js) 6.34KB 2.43KB
auth (index.js) 2.71KB 1.22KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.02KB 0.88KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 498.83KB 111.26KB
core (index.js) 4.06KB 1.61KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 157.40KB 43.42KB
fields (index.js) 233.27KB 58.22KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.35KB 1.38KB
i18n (pickLocalized.js) 3.69KB 1.73KB
i18n (provider.js) 23.12KB 7.62KB
i18n (useDisplayLocale.js) 2.84KB 1.45KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 39.16KB 10.97KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 9.35KB 3.31KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 4.42KB 1.42KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.81KB 0.83KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.62KB 12.83KB
plugin-charts (index.js) 64.75KB 18.37KB
plugin-chatbot (index.js) 181.21KB 43.14KB
plugin-dashboard (index.js) 127.85KB 32.73KB
plugin-designer (index.js) 212.39KB 42.83KB
plugin-detail (index.js) 239.93KB 60.02KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 120.42KB 29.03KB
plugin-gantt (index.js) 164.10KB 39.87KB
plugin-grid (index.js) 197.58KB 53.00KB
plugin-kanban (index.js) 52.72KB 14.54KB
plugin-list (index.js) 111.23KB 26.97KB
plugin-map (index.js) 17.91KB 5.72KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 41.97KB 11.33KB
plugin-timeline (index.js) 26.68KB 7.66KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 83.81KB 20.49KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 27.53KB 9.41KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.28KB 0.68KB
react (schema-input.js) 1.45KB 0.83KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (index.js) 4.77KB 2.16KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 10.76KB 3.17KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 6.92KB 2.40KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 3.05KB 1.52KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Collaborator Author

PM 验收 ✅ ACCEPT(#3832,批次 19 —— 维护者 2026-08-09 裁定方向 (a) 的实施件)

实物核验(按真实 merge-base 对账):22 files,+944/−118 —— 编码选 type: ControlType | ControlType[] 的三条理由成立(一个事实一个位置 / 作者只能写出一个答案 / 不新增已发布字段),且「老消费者 switchdefault」的风险不是靠类型报错兜底,而是 14 条消费点逐读点排查(四条「无需适配」各有实测依据,designer 那条实测出「设计器根本不消费发布面」这个独立事实);单臂序列化字节不变 + zod 非空互异收紧 + 最严 severity 规则,三条约束都有钉子。卡面「两声明位」实为三处 + zod 共四处,dev 全找齐 —— 漏 Registry.ts 那份编译都过不去。模型标识 grep = 0;releases/ 零触碰;changeset minor×5 按扩展档(与 #3985 同档)。

CI 亲读:20/20 check runs completed,零失败(两项 path-filter skipped 计绿)。

反向验证读数:①预判「正向断言空绿、红在对照」实测命中(9 红全落对照与机制面)—— 对照断言不是装饰的实测依据;②2624 条既有断言零变化钉住向后兼容;③b 假臂全绿如实报告并单独立 #4971,没有顺手把门禁塞进本 PR。record_picker.emptyText 刻意保留单臂(渲染器丢掉的臂不广告)判断正确,原注释的错误归因一并改写。

#4970(element:text.content / element:button.label 第 6、7 标本)按裁定字面「the five measured specimens」不扩围单独立卡正确 —— 本 PR 落 main 后即派。findings #4971/#4972 入池。undraft + auto-merge(squash)。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 17, 2026 12:37
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 17, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Aug 17, 2026
Resolve the one header-narrative conflict in registry-inputs-spec-parity.test.ts:
keep this branch's rewritten types bullet (expressiveness closed by #3832, the
comparison half tracked as #4971) and drop this branch's pre-#3809 tombstone
bullet — main already records that limit as closed (#3809 landed via #4967),
so the LIMIT list stays at exactly the two items its preamble announces.

Co-authored-by: Claude <noreply@anthropic.com>
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit 279fb13 Aug 17, 2026
21 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-3832-componentinput-union branch August 17, 2026 12:53
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 24.7 KB 350 KB
Entry file index-9azZSDjk.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 9.56KB 3.59KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 8.92KB 3.41KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 25.13KB 5.40KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.79KB
auth (createAuthenticatedFetch.js) 6.34KB 2.43KB
auth (index.js) 2.71KB 1.22KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.02KB 0.88KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 498.83KB 111.26KB
core (index.js) 4.11KB 1.62KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 157.40KB 43.42KB
fields (index.js) 233.27KB 58.22KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.35KB 1.38KB
i18n (pickLocalized.js) 3.69KB 1.73KB
i18n (provider.js) 23.12KB 7.62KB
i18n (useDisplayLocale.js) 2.84KB 1.45KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 39.16KB 10.97KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 9.35KB 3.31KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 4.42KB 1.42KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.81KB 0.83KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.62KB 12.83KB
plugin-charts (index.js) 64.75KB 18.37KB
plugin-chatbot (index.js) 181.21KB 43.14KB
plugin-dashboard (index.js) 127.85KB 32.73KB
plugin-designer (index.js) 212.39KB 42.83KB
plugin-detail (index.js) 240.05KB 60.05KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 120.42KB 29.03KB
plugin-gantt (index.js) 164.10KB 39.87KB
plugin-grid (index.js) 197.61KB 53.03KB
plugin-kanban (index.js) 52.72KB 14.54KB
plugin-list (index.js) 111.22KB 26.98KB
plugin-map (index.js) 17.91KB 5.72KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 41.97KB 11.33KB
plugin-timeline (index.js) 26.68KB 7.66KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 83.81KB 20.49KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 27.53KB 9.41KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.28KB 0.68KB
react (schema-input.js) 1.45KB 0.83KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (index.js) 4.77KB 2.16KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 10.76KB 3.17KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 6.92KB 2.40KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 3.05KB 1.52KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants