fix(spec): gen:docs 内联形状里的长枚举按测得阈值省略,并印出被隐藏的成员数 (#5340) - #6211
Merged
Conversation
…, with a count of what was hidden (#5340) `formatType()` capped how many KEYS an inline object summary prints (`INLINE_KEY_LIMIT = 4`) but never capped how wide one key's TYPE could be, so a long enum reached through a summary printed every member into a single table cell. Filed on `BulkActionDef.params` (~900 chars); the corpus measurement found worse — the 261-member error-code vocabulary inlined into `error` shapes on 80 rows across 13 `api/*.mdx` pages, at 6242 characters in one cell. An `Enum<…>` body rendered below a summary's `{ … }` is now cut to `INLINE_ENUM_WIDTH_LIMIT` (80 characters) and the count of what was cut is printed in its place: `Enum<'text' | 'textarea' | … +42 more>`. The count is the safety property — a silent prefix would leave the page looking complete while it was not, which is a worse defect than a wide cell for pages that are the authoritative input for AI authors (ADR-0033). Only a SECOND copy is cut. `ctx.inShapeSummary` is set once, where a summary renders a child, and inherited downward; a schema's own row, a union variant on its own row (`Enum<…> | string`), a top-level `Record<string, Enum<…>>` and an array of a top-level enum all still print every member. For 457 of the 805 in-shape occurrences that is where the elided copy's full list still lives, on the same page. The 80 is measured, not chosen: across 216 pages / 8541 type cells / 1768 enum occurrences the in-shape population is bimodal and its per-character density collapses at 80 (3.6/char over (64,80], 1.6 over (80,100], 0.5 over (100,200]). An elision must also pay for its own marker, so a body a member or two over budget is left whole and the limit is not a cliff at exactly 81. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5
…5340) `pnpm --filter @objectstack/spec gen:schema && gen:docs` output only — no hand edits (`content/docs/references/` is AUTO-GEN). 42 pages, 144 rows, one direction: every changed row is shorter (462,140 characters removed in total, largest single row -6266) and every one carries a `… +N more` marker — no row was silently truncated and none grew. Cells over 900 characters 76 → 4, over 200 characters 246 → 145, p99 cell width 643 → 247, p95 unchanged at 145. The widest cell left is `api/contract.mdx` `code` at 6092 — the error-code vocabulary on its OWN row, deliberately untouched because it is the only full copy of that list on the page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckNo hand-written docs reference the 0 changed package(s). ✅ |
This was referenced Aug 7, 2026
Closed
os-zhuang
marked this pull request as ready for review
August 7, 2026 11:18
This was referenced Aug 7, 2026
os-zhuang
added a commit
that referenced
this pull request
Aug 7, 2026
生成物 `content/docs/references/**` 一律取 origin/main 版本(#4675 第二步: 生成树用 checkout 定向取一侧,不手工解冲突),使本合并提交成为确定性基线 —— 两侧各自从不同源码状态生成过,文本自动合并虽无冲突,得到的却是「陈旧组合」。 主线带入 #6211(#5340,内联长枚举省略,落点 `lib/format-type.ts`); 本分支落点 `lib/file-description.ts`,两者互不重叠。 注:本提交刻意以 `--no-verify` 落下 —— os-regen 钩子(正确地)指出生成物相对 源码已陈旧。#4675 要求合并与重跑分成两个提交以便分别 review,故此处保留陈旧 状态,由紧随其后的提交整体重跑 `gen:schema && gen:docs` 修正。PR head 上的 CI 校验的是最终树,不是这个中间提交。
os-zhuang
added a commit
that referenced
this pull request
Aug 7, 2026
纯生成物,由 `pnpm --filter @objectstack/spec build && … gen:docs` 在合并后的 源码树上整体产出(#4675 第四步),而非把两侧各自的生成物文本拼接。 与 #6211(#5340 内联长枚举省略)同树共存已核实: - 省略标记 `… +N more` 全语料 160 处,与 origin/main 完全一致(160)。 - 两者受影响页面交集 33 张,逐页复核 description 区(本 PR)与 type 单元格 (#6211)各自的效果同时在位。例如 integration/connector.mdx 第 68 行「另见」 为单个可点链接(#6136),同页 3 处 `… +N more`(#6211);security/explain.mdx 开篇跨行行内代码跨度完整(#5553),同页 4 处省略标记。 - 验收复跑:`[../[` 归零;按段落计未配对反引号归零;代码跨度内 `\{` 残留归零。 - 全量 216 张参考页经 @mdx-js/mdx 编译通过。 - 无页面新增或丢失开篇描述。
This was referenced Aug 7, 2026
docs-gen:
getCategoryTitle() 只给 UI/AI/API 大写,qa 渲染成 "Qa Protocol"(参考页标题 + meta.json + 根索引导航三处)
#5853
Closed
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5340
先复价:立单时的行号与文件归属都已过期,但前提仍然成立
按派发要求先在
origin/main上核实,不沿用立单时的坐标:INLINE_KEY_LIMIT与内联摘要装配确实在packages/spec/scripts/lib/format-type.ts(不在build-docs.ts);retiredKey()墓碑渲染成any—— 嵌套两层时连[REMOVED]处方都没有,退役键读起来像自由槽 #5606 / PR fix(spec): docs-gen 把 retiredKey() 墓碑渲染成 never,而不是 any (#5606) #6058 的墓碑剔除、参考文档生成器把数值字面量 z.literal(2) 渲染成带引号的 '2',数值型联合被记成字符串型 #5729 / PR fix(spec): 参考文档生成器按 typeof 决定字面量是否加引号,数值字面量不再被记成字符串 (#5729) #6127 的formatLiteral()都在本文件,且 参考文档生成器把数值字面量 z.literal(2) 渲染成带引号的 '2',数值型联合被记成字符串型 #5729 的定价答复属实 —— 成员字符串已归一化,本单只需在formatEnum里接手一个已经排好的string[]。~900 字符的实例仍然复现(
content/docs/references/ui/bulk-action.mdx的BulkActionDef.params)。而且量了整个语料后发现:立单时那个实例远不是最坏的 —— 261 个成员的错误码词表被内联进 13 个api/*.mdx的error形状里,共 80 行,单个单元格 6242 字符。读者现在看到什么,完整词表还在哪里
一个被省略的枚举渲染成:
…沿用本文件已有的「还有更多」记号(键省略用的就是它),+42 more是让这次省略在信息上安全的那一半:纯前缀截断会让页面看起来是完整的而实际不是 —— 读者无法区分「一个 7 项的词表」和「49 项里的前 7 项」。这些页面是 AI 作者的权威输入(ADR-0033),一个靠省略说谎的页面比一个过宽的单元格更糟(与 #5059 同类)。⛔ 所以没有做无标记截断。完整词表在哪里,按读者会先撞到的顺序:
ctx.inShapeSummary只在摘要的{ … }之下被置位,所以下面四种位置全部原样打印每一个成员:schema 自己的行(BulkActionParam.type、ErrorResponse.code)、顶层联合分支(Enum< … > | string,即PageComponent.type那个形状)、顶层Record< string, Enum< … > >、以及顶层枚举的数组。量过:805 个内联位置里有 457 个,同一页上就有这份完整拷贝(BulkActionDef.params就是 —— 往下两节的BulkActionParam.type带着全部 49 项;每个api/*.mdx的error形状也是,它的码表印在ErrorResponse.code上)。json-schema/下的 JSON Schema 仍然是它一直以来的权威。标记不能做成指向 (1) 的锚点:Zod 会把枚举内联,到达
formatType的节点是一个裸的{ type: 'string', enum: [...] },既没有$ref也没有名字可链;硬造一个等于去猜页面上哪个小节恰好带着同一批成员。阈值是量出来的,不是拍的
语料:216 个生成页 / 8541 个类型单元格 / 1768 处
Enum,其中 805 处在摘要内联位置。这 805 处的 body 宽度是明显双峰的,每字符的分布密度正好在 80 处塌掉:80 以下是读者本来就想看全的短词表(
'asc' | 'desc'、四项的控件模式),80 以上是清单。候选阈值实测(在真实语料上跑,不是估算):
收紧到 24 要多省略 446 处,只多省 4% 的字符 —— 因为宽度几乎全在那 ~91 个巨型清单里,任何阈值都抓得到。固定成员数上限在每一档都更差:上限 4 会把
Enum<'a' | 'b' | 'c' | 'd' | 'e'>(31 字符,完全可读)也切掉,却仍留下 134 个 200+ 的单元格。另外加了一条**「标记必须挣回自己的位置」**的守卫:只超出一两个成员的 body,省下的还不如
… +N more本身占的多。没有这条守卫时,189 次省略里有 29 次省下的字符少于标记占的位置(其中 14 次只藏了一个成员、省 2–3 个字符)—— 拿一个真实拼写换一个计数和一次页面改写,是净亏。加上之后实际生效 160 处,另有 31 处(body 81–107)原样保留,阈值因此不是 81 处的悬崖。重生成结果(独立 commit)
gen:schema && gen:docs产物,未手改。42 页 / 144 行,方向单一:… +N more标记 —— 无一行是无标记截断(已机器核对:diff 里新增行中不含标记的有 0 行);wholeCell/topUnion/inRecord三类位置一处未动。剩下最宽的单元格是
api/contract.mdx的code,6092 字符 —— 错误码词表自己那一行,故意不动,因为它是该页上唯一一份完整拷贝。Pin 与反向验证(两个方向都实测,不是预测)
新增 15 条 pin(
packages/spec/scripts/format-type.test.ts),覆盖派发要求的三档:阈下不变、阈上带标记省略、边界;外加 #5729 / #5606 的交叉影响与「无 ctx 不省略」的显式降级声明。… +N more的用例。formatEnum(prop.enum, true),即这次改动最显然的一行版本):5 failed | 46 passed ——NOT elided那组里的 4 条,加上「无 ctx 不省略」那条。第一版注释里我预测的是「6 failed | 41 passed」和「那五条」,两个都猜错了,已按实测数字改写(#5729 的注释里也记过同样的自我更正)。
leaves short enums inside a summary是两个方向下都绿的那条,原因诚实地写在注释里:两项枚举在哪一版都在预算内,所以它守的是预算而不是位置。验证
消费半径已扫:
formatType只有build-docs.ts三处调用,其他包没有任何 fixture 拼写内联枚举(grep 过),所以不存在 #5046 那种「改在 lint、坏在 cli fixture」的跨包遗漏。一点观察(仅建议,本 PR 不做)
format-type.ts的摘要装配面现在同时承载三件事:墓碑剔除(#5606)、逐值引号(#5729)、宽度省略(本单)。我认为目前仍是内聚的,理由与是否该抽取的判断写在给 PM 的报告里,这里不展开,也没有在本 PR 里做任何抽取。Generated by Claude Code