feat(components,plugin-detail): 五个 GA 键发布为 inputs,page:tabs 补上被发布的那个拼写的读点 (#4668) - #5009
Conversation
…写的读点 (#4668) @objectstack/spec 17.0.0 GA 声明、渲染器一直兑现、`inputs` 从未发布的五个键 ——`page:header.maxVisible` / `page:header.mobileMaxVisible` / `page:tabs.alwaysShowStrip` / `record:details.inlineEdit` / `record:details.showHeader`——现在在各自注册位声明为 inputs,每条带 description。 这是无人报告的那个方向:`gen-manifest.ts` 把五个键全落在 `sdui.manifest.json` 与 `sdui-intrinsics.d.ts` 之外,`sdui-parser` 的 prop walk 对写了它的作者报 `unknown-prop`,而渲染器照样兑现。改前实测五键全部 `unknown-prop`,改后全部 CLEAN(`ga-honoured-inputs-author-reach.test.ts` 连同"检查未被静默"的对照钉住)。 page:tabs 另补一个读点。`alwaysShowStrip` 原先只按 `schema.properties.alwaysShowStrip` 读,而 `inputs` 发布的是顶层键——manifest 白名单、生成的 `.d.ts`、JSX-page 编译器判的都是顶层那个拼写。单标签页实测: wrapped 形式出条,flat 形式不出。只声明不补读点等于发布一个渲染器会丢掉的写法, 正是 parity 门自己要防的失效模式往里挪一层。现在规范拼写先读,`properties` 臂 保留给不经 SchemaRenderer hoist 的路径——与 `maxVisible` 一贯的双读一致。 parity 门里占位的五条 GA-pending 豁免随之删除(门自己的 `carries no stale unpublished-key exemption` 一旦发布就点名它们), `GA_PENDING_UNPUBLISHED_KEYS` 只剩 object-grid 那十条;五个键改为按名钉成 DECLARED,防止把声明换回豁免这条更省事的路。 类型按实测定:maxVisible / mobileMaxVisible 是正整数(0、-1、2.5 均被 spec 拒), 其余三个是纯 boolean,单臂无联合。 Fixes #4668 Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
|
PM 验收 ✅ ACCEPT(#4668,批次 20) 实物核验(merge-base CI 亲读:20/20 check runs completed,零失败(两项 path-filter skipped 计绿)。 范围外一行的裁定: 作者可见验收面:五键 unknown-prop → CLEAN,三层对照(块可解析 / 未声明探针键仍报 / 离臂值仍报)防「门被静音」误读。变异 1+2 合钉「删豁免与发布必须同 PR」,且变异 2 里 arming 测试保持绿的原因(它管 dormancy 跟不跟 spec,不管豁免过没过期)如实写明。 findings:#5006(数值臂粗于契约,三个权威两种答案,发布契约形状决策)已由 PM 挂 Generated by Claude Code |
Fixes #4668
@objectstack/spec@17.0.0GA 声明、渲染器一直兑现、inputs从未发布的五个键,现在在各自注册位声明为inputs,每条带 description;parity 门里占位的五条 GA-pending 豁免随之删除。前提验证:五个读点在现 main 重定位
卡面行号来自
6d4f5bd59,PR #4975 之后containers.tsx已动过。基线origin/main@ec1f4d728,逐个重定位并确认仍兑现:page:headermaxVisiblecontainers.tsx:1382??properties.*)page:headermobileMaxVisiblecontainers.tsx:1381page:tabsalwaysShowStripcontainers.tsx:637properties.*,见下record:detailsinlineEditrecord-details.tsx:234record:detailsshowHeaderrecord-details.tsx:257类型按实测定,不按措辞猜
实测
ComponentPropsMap的成员与判定:maxVisible/mobileMaxVisible——optional -> number,checks 为safeint+greater_than 0 (exclusive)。实测1/2/3/100通过,0/-1/1.5全部按值拒。单臂'number',无联合(ComponentInput.type无法表达 spec 的联合类型,于是发布面永远比契约窄一个 arm ——page:header.title的内联翻译映射今天就会被 manifest 门报type-mismatch#3832 的数组臂用不上)。alwaysShowStrip/inlineEdit/showHeader——optional -> boolean。实测true/false通过,1/0/'true'/null全部invalid_type。单臂'boolean'。用户可见验收面:改前全 unknown-prop,改后全 CLEAN
在 console 自己的 manifest 上(
manifestFromConfigs+validateTree,与 JSX-page 编译器和保存门同一对)实测对照。改前:改后五条全部空。
apps/console/src/__tests__/ga-honoured-inputs-author-reach.test.ts把这个面钉住,并且每个正向都配对照:三个 block 各探一个谁都没声明的键,unknown-prop必须照报(否则「无诊断」和「检查被静默」长得一样);另有 off-arm 探针(alwaysShowStrip: 1/inlineEdit: 'no'/maxVisible: true)确认声明的臂窄得有意义,而不是把type-mismatch一并关掉。page:tabs 另补一个读点(本 PR 唯一超出「加声明」的改动)
alwaysShowStrip原先只按schema.properties.alwaysShowStrip读,而inputs发布的是顶层键 —— manifest 白名单、生成的.d.ts、sdui-parser的 prop walk、JSX-page 编译器判的都是顶层那个拼写。单标签页实测(改前):只声明不补读点,等于发布一个渲染器会丢掉的写法 —— 正是 parity 门文件头写的那个失效模式(「manifest 告诉作者写一个平台会扔掉的键」)往里挪一层。所以规范拼写先读,
properties臂保留给不经SchemaRendererhoist 的路径,与maxVisible一贯的双读一致。page-tabs-always-show-strip.test.tsx两个拼写都钉住,并含对照(不写该键必须不出条)与范围守卫(多标签页不受影响;false与非布尔都读作「未设」)。反向验证(三个变异,预判先写后跑)
① 删豁免但不发布 inputs —— 预判 #3808 那向红点名五键。实测一致,6 红:
② 发布 inputs 但留豁免(五条同时加回
UNPUBLISHED_EXEMPTIONS与GA_PENDING_UNPUBLISHED_KEYS)—— 预判 stale-exemption 检查红点名五条。实测一致,2 红:预判里明确写了「arming 检查应当保持绿」,实测确认:
every GA-pending exemption arms exactly with the installed spec在 GA pin 上要求isDormantOnThisPin === false,而键被 spec 列出所以确实非 dormant —— 该检查管的是休眠是否跟着 spec 走,不是豁免是否过期。两个变异合起来钉住「删豁免与发布必须同 PR」。③ 回退
alwaysShowStrip的顶层臂 —— 预判恰好一条红(被发布的那个拼写),wrapped、对照、声明块保持绿。实测一致,1 红:这一条最值得看的是什么保持了绿:parity 门 65 条全绿、author-reach 4 条全绿。两者一个比顶层键名、一个读 manifest 诊断,都看不出渲染器读的是哪个载体 —— 只有行为测试能抓到。这也正是那个读点缺口能一路活到今天的原因。
三次变异后一律
git checkout --还原(未用 stash),树回到本 commit。parity 门的收尾
五条豁免条目删除,
GA_PENDING_UNPUBLISHED_KEYS只剩object-grid那十条(测试名all fifteen together随之改为all ten together,doc comment 从「TWO GROUPS」改为「ONE GROUP NOW」并记下离开的是哪一组、为什么 —— 一条永不落地的 pending 条目正是那个集合要暴露的腐坏)。删除处留下墓碑注释,含alwaysShowStrip读点缺口那笔,给下一个读者。五个键另按名钉成 DECLARED(
the five GA keys objectui#4668 declared are discoverable),理由与隔壁 #3808 五条、rc.6 record_picker 三条一致:派生的 reverse 循环在「声明被换回豁免」时一样绿,而那是时间压力下更省事的一步。验证
全部经
flock /tmp/os-heavy-verify.lock+--max-old-space-size=4096+--maxWorkers=2:apps/console全项目packages/components/packages/sdui-parser/+packages/plugin-detail/packages/layout/+packages/react/+packages/types/packages/app-shell/.../metadata-admin/+examples/turbo run type-check --concurrency=2node scripts/check-control-bytes.mjsgrep -naP六个改动文件,干净react-refresh/only-export-components)check-changeset-fixed/check-changeset-no-major均绿消费半径按「规则被谁读」而非「改了哪个包」扫过:
BLOCK_CONFIG(metadata-admin 设计器面板)是另一套人工策展面、无 parity 门,其page:header字段集被toEqual(['title','subtitle','breadcrumb'])精确钉住,本 PR 不动它;page-container-authorable-keys.test.tsx的精确集断言只覆盖page:card。两者都未受影响。顺手记录,未在本 PR 处理
ComponentInput.type只有粗粒度number臂,无法表达整数/正数约束:作者写maxVisible: 0时 objectui 侧零诊断、渲染器照渲、上游os validate按值拒。附带一半是readMax比契约更宽(接受0、小数下取整)。是发布契约的形状决定,列了四个方向待裁。GLOBALLY_UNPUBLISHED_SPEC_KEYS的理由串引用plugin-detail/src/index.tsx:335-337,实际差约 70 行(本 PR 之前就已错,本 PR 让它更远)。finding。Generated by Claude Code