Skip to content

feat(components,plugin-detail): 五个 GA 键发布为 inputs,page:tabs 补上被发布的那个拼写的读点 (#4668) - #5009

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-4668-ga-five-inputs
Aug 17, 2026
Merged

feat(components,plugin-detail): 五个 GA 键发布为 inputs,page:tabs 补上被发布的那个拼写的读点 (#4668)#5009
yinlianghui merged 1 commit into
mainfrom
claude/issue-4668-ga-five-inputs

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #4668

@objectstack/spec@17.0.0 GA 声明、渲染器一直兑现、inputs 从未发布的五个键,现在在各自注册位声明为 inputs,每条带 description;parity 门里占位的五条 GA-pending 豁免随之删除。

前提验证:五个读点在现 main 重定位

卡面行号来自 6d4f5bd59,PR #4975 之后 containers.tsx 已动过。基线 origin/main @ ec1f4d728,逐个重定位并确认仍兑现:

block key 现读点 兑现
page:header maxVisible containers.tsx:1382 ✅ 双读(顶层 ?? properties.*)
page:header mobileMaxVisible containers.tsx:1381 ✅ 双读,默认 1
page:tabs alwaysShowStrip containers.tsx:637 ⚠️ properties.*,见下
record:details inlineEdit record-details.tsx:234 ✅ 顶层
record:details showHeader record-details.tsx:257 ✅ 顶层

类型按实测定,不按措辞猜

实测 ComponentPropsMap 的成员与判定:

用户可见验收面:改前全 unknown-prop,改后全 CLEAN

在 console 自己的 manifest 上(manifestFromConfigs + validateTree,与 JSX-page 编译器和保存门同一对)实测对照。改前:

page:header.maxVisible        -> unknown-prop: page:header has no prop "maxVisible"
page:header.mobileMaxVisible  -> unknown-prop: page:header has no prop "mobileMaxVisible"
page:tabs.alwaysShowStrip     -> unknown-prop: page:tabs has no prop "alwaysShowStrip"
record:details.inlineEdit     -> unknown-prop: record:details has no prop "inlineEdit"
record:details.showHeader     -> unknown-prop: record:details has no prop "showHeader"

改后五条全部空。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.tssdui-parser 的 prop walk、JSX-page 编译器判的都是顶层那个拼写。单标签页实测(改前):

WRAPPED  (properties.alwaysShowStrip: true)  strip present: true
FLAT     (alwaysShowStrip: true)             strip present: false
BASELINE (未写该键)                           strip present: false

只声明不补读点,等于发布一个渲染器会丢掉的写法 —— 正是 parity 门文件头写的那个失效模式(「manifest 告诉作者写一个平台会扔掉的键」)往里挪一层。所以规范拼写先读,properties 臂保留给不经 SchemaRenderer hoist 的路径,与 maxVisible 一贯的双读一致。page-tabs-always-show-strip.test.tsx 两个拼写都钉住,并含对照(不写该键必须不出条)与范围守卫(多标签页不受影响;false 与非布尔都读作「未设」)。

反向验证(三个变异,预判先写后跑)

① 删豁免但不发布 inputs —— 预判 #3808 那向红点名五键。实测一致,6 红:

page:header    publishes every top-level key … : expected [ 'maxVisible', 'mobileMaxVisible' ] to deeply equal []
page:tabs      publishes every top-level key … : expected [ 'alwaysShowStrip' ] to deeply equal []
record:details publishes every top-level key … : expected [ 'inlineEdit', 'showHeader' ] to deeply equal []
the five GA keys objectui#4668 declared are discoverable: page:header does not publish maxVisible
+ author-reach 两条(unknown-prop 回来)

② 发布 inputs 但留豁免(五条同时加回 UNPUBLISHED_EXEMPTIONSGA_PENDING_UNPUBLISHED_KEYS)—— 预判 stale-exemption 检查红点名五条。实测一致,2 红:

carries no stale unpublished-key exemption: expected [ 'page:header.maxVisible', …(4) ] to deeply equal []
the five GA keys objectui#4668 declared are discoverable: expected […(17)] to not include 'page:header.maxVisible'

预判里明确写了「arming 检查应当保持绿」,实测确认:every GA-pending exemption arms exactly with the installed spec 在 GA pin 上要求 isDormantOnThisPin === false,而键被 spec 列出所以确实非 dormant —— 该检查管的是休眠是否跟着 spec 走,不是豁免是否过期。两个变异合起来钉住「删豁免与发布必须同 PR」。

③ 回退 alwaysShowStrip 的顶层臂 —— 预判恰好一条红(被发布的那个拼写),wrapped、对照、声明块保持绿。实测一致,1 红:

shows a one-tab strip for the PUBLISHED top-level spelling: expected false to be true

这一条最值得看的是什么保持了绿: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 全项目 52 文件 / 575 测试 绿
packages/components/ 148 文件 / 1327 测试 绿
packages/sdui-parser/ + packages/plugin-detail/ 89 文件 / 846 测试 绿
packages/layout/ + packages/react/ + packages/types/ 99 文件 / 1216 测试 绿
packages/app-shell/.../metadata-admin/ + examples/ 183 文件 / 3314 绿(1 skipped)
仓根 turbo run type-check --concurrency=2 81/81 successful
node scripts/check-control-bytes.mjs OK(4459 文件);另做门盲区自扫 grep -naP 六个改动文件,干净
改动文件 eslint 0 error(112 warning 全是既有 react-refresh/only-export-components)
changeset 门 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 处理


Generated by Claude Code

…写的读点 (#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>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 25.3 KB 350 KB
Entry file index-C5CTXI-s.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) 500.23KB 111.77KB
core (index.js) 4.11KB 1.62KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 159.03KB 44.08KB
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) 241.12KB 60.43KB
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) 18.72KB 6.09KB
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(#4668,批次 20)

实物核验(merge-base ec1f4d728 与报告基线一致):7 files,+568/−45 —— 五键按 hideFields 范本在真实注册位声明(record:details 的注册位在 plugin-detail/src/index.tsx 而非卡面写的 renderer 文件,重定位正确);五条 GA-pending 豁免连同 GA_PENDING_UNPUBLISHED_KEYS 名单一并收割,「fifteen together」改「ten together」,doc comment 从两组改一组并记录哪组离开与为何 —— 自清机制照 #3809 的设计走完了第一个完整周期。模型标识 msg/diff 双 0;releases/ 零触碰。

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

范围外一行的裁定:alwaysShowStrip 的前提部分成立 —— 渲染器只从 properties.* 载体读,而 inputs 发布的是 validate.ts 走的顶层形状;只发布不加读会造出「发布了渲染器丢掉的写入」—— 恰是 parity 门文档记载的失败模式下沉一层。dev 加了一行 canonical 顶层读(保留 properties 臂镜像 maxVisible 的既有双读),先量后改、两拼法行为钉住、单独成节披露 —— 这不是扩围,是让卡面目标真正成立的必要件,验收采纳。变异 3 的读数最有价值:回退那一行读时 parity 门 65 条与 author-reach 4 条全绿 —— 两个门都看不见渲染器读哪个载体,行为测试是唯一抓手,这解释了该读缺口为何能长期存活。

作者可见验收面:五键 unknown-prop → CLEAN,三层对照(块可解析 / 未声明探针键仍报 / 离臂值仍报)防「门被静音」误读。变异 1+2 合钉「删豁免与发布必须同 PR」,且变异 2 里 arming 测试保持绿的原因(它管 dormancy 跟不跟 spec,不管豁免过没过期)如实写明。

findings:#5006(数值臂粗于契约,三个权威两种答案,发布契约形状决策)已由 PM 挂 needs-user-decision;#5007(理由串行号引用漂移,#4902 家族)入池。undraft + auto-merge(squash)。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 17, 2026 15:02
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit 98eab36 Aug 17, 2026
20 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-4668-ga-five-inputs branch August 17, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

page:header / page:tabs / record:details: five keys spec 17.0.0 GA declares and the renderers already honour are never published as inputs

2 participants