Repository navigation
Commit b8f596c
fix(app-shell): Studio Interfaces item header names a label-less object entry by its label, as the rail does (#26974)
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8LSNZTBKB5UepDXQ6qob588)_
Fixes #26746
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:Studio「界面」条目标题(标题、读屏说明、定义抽屉标题)改为与左侧导航行同一套标签解析,每次渲染现解析。
- 为什么改:无标签的对象导航项(脚手架生成的就是这种)标题显示机器名 `repairs_ticket`,而侧栏已显示「Repair
Ticket」。
- 风险与回滚:仅 app-shell 一个私有包、一个文件的显示文本;回滚即 revert 本 PR,无数据或契约变化。
- 先看:`StudioDesignSurface.tsx` 中新增的 `ifTitleText` 一段;其次新测试文件
`StudioDesignSurface.itemHeaderLabel-26746.test.tsx`。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/app-shell/src/views/studio-design/StudioDesignSurface.itemHeaderLabel-26746.test.tsx`,预期
3 个测试全绿。
- 需要你做的:无,席位落地。
## What changes
The Interfaces item header read `current.label || current.name` in three
places: the header title, its screen-reader caption beside the kind
chip, and the definition sheet's title
(`engine.studio.if.definitionTitle`). `current.label` is the open leaf's
display text frozen when its Surface was made. On the first load that
happens before the resolver knows every label. For example, a draft-only
object's `_drafts` row lands after the app load picks its first leaf.
The rail asks the resolver again on every render, so it read "Repair
Ticket" while the header kept "repairs_ticket · Object".
The three sites now read one value, `ifTitleText`. It finds the open
leaf's entry in `railTree` (the tree the rail draws, served text
included) by `navId` and names it through the rail's own
`navEntryLabelText` with the same `useNavTargetLabel` resolver. No
second resolver is added. A Surface without a `navId` keeps
`current.label`, and an empty text keeps the existing `current.name`
fallback.
## Why
The rail and the header name the same leaf, and the label wins over the
machine name everywhere (ruling B of objectui#11201, the
`navEntryLabelText` contract). Triage 6448317687: "Resolve the object
label the way the rail does."
## Tests
New `StudioDesignSurface.itemHeaderLabel-26746.test.tsx` mounts the
whole surface and holds the `_drafts` answer until the header has opened
on its first leaf:
- a label-less object entry: the header, its caption and its tooltip
read "Repair Ticket" once the label arrives, with the machine name only
on the tooltip;
- a labelled entry: the header reads its authored label, unchanged;
- a label-less group: the rail's group header reads what the runtime
sidebar's `resolveNavItemLabel` gives it, and a leaf inside it is named
alike in the rail and the header.
Ablation, after the fix was committed: `scripts/ablation-replace.mjs`
replaced the resolver line with `const text = current.label;` (the old
`current.label || current.name`). Tests 1 and 3 went red with `Received:
repairs_ticket · Object`, the QA symptom; test 2 stayed green. The
restore leg was verified by blob: HEAD and disk both `d05fa2404f2a`,
`git diff HEAD` empty. The test imports the surface by relative path, so
there is no dist leg.
## Acceptance notes
- Label-less groups: the rail shows a label-less group's `id` (for
example `nav_item_2`, drawn uppercase by the rail group style). This is
the runtime's own rule: `resolveNavItemLabel` in `@object-ui/layout`
falls to the entry `id` for a group, and the running app's sidebar shows
the same text. The header never names a group, because a group is not a
Surface. So the rail and the header already agree, and `NavTreeGroup` is
unchanged. Test 3 pins that the rail matches the runtime. Giving
label-less groups a different text would be a change to the runtime
rule, not to this header.
- Outside this card's surface, the same frozen-label read remains in two
places, reported only: the Automation pillar header's `current.label ||
current.name`, and the `onSurfaceLabelChange` report to the dock, which
reads `current.label`.
## Verification
All readings are on head `052aae45`, the last commit before this PR.
<details><summary>Derived gates: 24 of 24 exit 0, `--ran`
reconciled</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 24 families. Each one ran, its exit
code was captured before any pipe, and `--ran` printed "24 derived
famil(ies) accounted for — 24 run, 0 NOT-MEASURED". The set includes
`node scripts/check-sdui-manifest.mjs` (and `--self-test`), `pnpm --dir
ui exec vitest run scripts/` under the lock,
`check:cross-package-test-inputs`, `check:test-source-alias`,
`check:nul-bytes`, `check:type-check-coverage` and
`check:type-check-debt`. All exit 0.
</details>
<details><summary>Package checks</summary>
- `pnpm --filter @object-ui/app-shell type-check`: exit 0 (lock VERDICT
command-exit 0).
- `pnpm --dir ui exec vitest run
packages/app-shell/src/views/studio-design/`: Test Files 234 passed
(234), Tests 1693 passed (1693) (lock VERDICT command-exit 0).
- eslint on the two changed files: 0 errors, 14 warnings, all on
pre-existing lines outside this hunk.
- `pnpm --dir ui run check:new-line-citations`: 0 new citations, exit 0.
</details>
No changeset: `@object-ui/app-shell` is `private: true`, and the diff
touches only it, so the PR carries `skip-changeset`.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (eslint on the changed
files: 0 errors)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset. (nothing
publishes; both declaration lines filled in)
- [x] 6. `packages/spec` touched: n/a.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01JQwxbY5nVXXfxvWqYPEQAe
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbY5nVXXfxvWqYPEQAe)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 1986d25 commit b8f596c
2 files changed
Lines changed: 232 additions & 3 deletions
File tree
- ui/packages/app-shell/src/views/studio-design
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4506 | 4506 | | |
4507 | 4507 | | |
4508 | 4508 | | |
| 4509 | + | |
| 4510 | + | |
| 4511 | + | |
| 4512 | + | |
| 4513 | + | |
| 4514 | + | |
| 4515 | + | |
| 4516 | + | |
| 4517 | + | |
| 4518 | + | |
| 4519 | + | |
| 4520 | + | |
| 4521 | + | |
| 4522 | + | |
| 4523 | + | |
| 4524 | + | |
| 4525 | + | |
| 4526 | + | |
| 4527 | + | |
| 4528 | + | |
4509 | 4529 | | |
4510 | 4530 | | |
4511 | 4531 | | |
| |||
4629 | 4649 | | |
4630 | 4650 | | |
4631 | 4651 | | |
4632 | | - | |
| 4652 | + | |
4633 | 4653 | | |
4634 | 4654 | | |
4635 | 4655 | | |
| |||
4644 | 4664 | | |
4645 | 4665 | | |
4646 | 4666 | | |
4647 | | - | |
| 4667 | + | |
4648 | 4668 | | |
4649 | 4669 | | |
4650 | 4670 | | |
| |||
5035 | 5055 | | |
5036 | 5056 | | |
5037 | 5057 | | |
5038 | | - | |
| 5058 | + | |
5039 | 5059 | | |
5040 | 5060 | | |
5041 | 5061 | | |
| |||
0 commit comments