Skip to content

Commit 0641640

Browse files
claude[bot]claude
andauthored
docs(cli): name the reader of each _views tail per side, and reconcile objectui's inert-key pin (#17721)
* docs(cli): name the three readers of `_views.<view>.*` separately, per tail The `pushViewEntries` docblock attributed all three tails it emits to one browser-side reader: "the convention the runtime resolver reads (`viewLabel` / `viewDescription` / `viewEmptyState` in @object-ui/i18n)". Measured against `origin/main` and the objectui checkout, the three tails have three different readers and the sentence was wrong about two of them: - `label` is read on BOTH sides — `resolveViewLabel` (`packages/spec/src/system/i18n-resolver.ts:403`) via `translateView` (:907), registered as `view:` in `METADATA_DOCUMENT_TRANSLATORS` (:991) from which `TRANSLATABLE_METADATA_TYPES` is derived (:1008) and read by `packages/rest/src/rest-server.ts:363`; and `useObjectLabel().viewLabel` client-side. - `description` is read SERVER-SIDE ONLY, by `resolveViewDescription` (:424, called at :908). objectui#7219 removed the `useObjectLabel().viewDescription()` member, and the objectui source says so in as many words at `packages/i18n/src/useObjectLabel.ts:485`. The old prose therefore pointed the reader at a symbol that no longer exists, for a key that is still resolved and still reaches the screen — the inversion #15180 read as "declared, accepted, read by nothing". - `emptyState` is read CLIENT-SIDE ONLY. `emptyState` has zero occurrences in `i18n-resolver.ts` (positive control in the same file: `description`, 90 occurrences) and `resolveViewEmptyState` has zero occurrences tree-wide (positive control: `resolveViewLabel`, present), while `useObjectLabel().viewEmptyState` is live at `useObjectLabel.ts:512`. The second clause was re-checked rather than carried over and is TRUE: the platform bundle does carry `sys_user._views.all_users.label` (`packages/platform-objects/src/apps/translations/en.objects.generated.ts:124` `_views` → `:128` `all_users` → `label: "All Users"`). Across all nine shipped `en.objects.generated.ts` bundles, `_views` blocks carry `label` leaves and no `description` leaf, so naming `.label` there is exact. `viewLabel` and `viewEmptyState` are NOT retired: objectui kept the `viewSuffixes` helper all three shared and dropped only the `'description'` tail. The added warning says that, so the next reader does not over-apply objectui#7219 and delete two current citations. `pushViewEmptyState`'s own docblock (:453) names `viewEmptyState` in @object-ui/i18n and is left untouched — on this measurement it is accurate. Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c Co-authored-by: Claude <noreply@anthropic.com> * chore(changeset): patch @objectstack/cli for the `_views` reader-per-tail docblock Measured rather than assumed: `@objectstack/cli` builds with plain `tsc -p tsconfig.build.json`, so JSDoc survives into `dist/utils/i18n-extract.js`, which is inside the package's `files[]`. A comment-only diff therefore moves published bytes here, and `skip-changeset` would be wrong — the false sentence is text an upgrading agent can grep in the published tarball. Positive control on the same probe: the docblock's `sys_user._views.all_users.label` phrase is likewise present in the built `dist/utils/i18n-extract.js`, and absent from the emitted `.d.ts`. Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c Co-authored-by: Claude <noreply@anthropic.com> * docs(cli): reconcile objectui's "inert" pin with the server reader of `_views.<view>.description` Successor pass on the R73 draft. The draft's reader topology re-derived and CONFIRMED; one omission corrected and the changeset reversed. Corrected. The draft said "⛔ The absence of a browser-side helper is not evidence the key is inert" and stopped there. objectui does not merely lack a helper — it PINS this key as "an inert catalog entry" (`packages/i18n/src/__tests__/useObjectLabel-view.test.tsx`, a whole `describe`), and measured across all nine shipped `en.objects.generated.ts` bundles, `_views` blocks author `label` (104) and `emptyState` (9) leaves and ZERO `description` leaves. A reader who greps objectui hits "inert catalog entry" and deletes this emission — the same defect class as the sentence this card is about, aimed the other way. The block now names both facts, scopes them to the browser path objectui#7219 removed, and says neither reaches the server reader. The reach claim is now cited rather than asserted: the overlay lands on the served view document's `description`, which objectui relays (`packages/app-shell/src/views/ObjectView.tsx` `description: viewDef.description ?? listSchema.description`) and renders (`packages/plugin-list/src/ListView.tsx`, `pickLocalized(schema.description, displayLocale)`). Changeset REVERSED to `skip-changeset`. The draft argued `patch` because the JSDoc is emitted into `dist/utils/i18n-extract.js` inside `files[]`. That premise is true — re-measured — but it shows bytes moving, not a release. Measured with a positive control, the docblock reaches NO `.d.ts` (an exported symbol's JSDoc in the same file does), and `pushViewEntries` is not exported, so nothing a consumer can call or type against moves. House precedent is directly on point and went the other way: a comment-only edit to `packages/objectql/src/engine.ts` and `validation/rule-validator.ts` — a released package that also ships `dist` — took `skip-changeset` and no changeset file. Left standing deliberately, both re-measured as ACCURATE: the `pushViewEmptyState` docblock naming `viewEmptyState` in @object-ui/i18n (live), and the `formViews` comment naming `viewLabel` (live) — which `packages/lint` quotes verbatim, so editing it would dangle that citation. Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f6e37e9 commit 0641640

1 file changed

Lines changed: 35 additions & 4 deletions

File tree

‎packages/cli/src/utils/i18n-extract.ts‎

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,41 @@ function defaultListViewKey(object: string, container: any): string | undefined
360360

361361
/**
362362
* Emit label / description / emptyState for ONE view under
363-
* `objects.<object>._views.<viewName>.*` — the convention the runtime resolver
364-
* reads (`viewLabel` / `viewDescription` / `viewEmptyState` in
365-
* @object-ui/i18n) and the one the shipped platform bundles already carry
366-
* (`en.objects.generated.ts`: `sys_user._views.all_users.label`).
363+
* `objects.<object>._views.<viewName>.*` — the address the shipped platform
364+
* bundles already carry (`en.objects.generated.ts`:
365+
* `sys_user._views.all_users.label`).
366+
*
367+
* **The three tails do not share one reader**, and for `description` the
368+
* reader is not in the browser at all. Getting that backwards reads as "this
369+
* key is dead" — the inference #15180 drew and #17546 corrected.
370+
*
371+
* - **`label` — read on BOTH sides.** `resolveViewLabel`
372+
* (`packages/spec/src/system/i18n-resolver.ts`) through `translateView`,
373+
* which `@objectstack/rest` applies at the REST metadata boundary off
374+
* `TRANSLATABLE_METADATA_TYPES`; and `useObjectLabel().viewLabel` in
375+
* `@object-ui/i18n`, client-side.
376+
* - **`description` — read SERVER-SIDE ONLY**, by `resolveViewDescription`
377+
* in that same resolver and through that same `translateView`. objectui#7219
378+
* removed the `useObjectLabel().viewDescription()` member, so the server
379+
* overlay is this key's ONE reader: it lands on the `description` of the
380+
* served view document, which objectui relays (`ObjectView`) and renders
381+
* (`ListView`, via `pickLocalized`).
382+
* ⚠️ objectui pins this key as "an inert catalog entry", and no bundle in
383+
* this repo authors a `description` leaf under `_views` (the nine shipped
384+
* `en.objects.generated.ts` carry `label` and `emptyState` leaves only).
385+
* ⛔ Neither fact licenses deleting this emission: both are scoped to the
386+
* BROWSER path objectui#7219 removed, and the server reader above is
387+
* untouched by them. Absence of a browser-side helper, and absence of an
388+
* authored value, are not evidence the key is unread.
389+
* - **`emptyState` — read CLIENT-SIDE ONLY**, by
390+
* `useObjectLabel().viewEmptyState` in `@object-ui/i18n`. The spec resolver
391+
* declares no empty-state reader at all, which is why `pushViewEmptyState`
392+
* below is the site that cites the client convention.
393+
*
394+
* ⚠️ `viewLabel` and `viewEmptyState` were NOT retired alongside
395+
* `viewDescription`: objectui kept the `viewSuffixes` helper all three shared
396+
* and dropped only the `'description'` tail passed to it. Naming those two
397+
* here is current, not residue.
367398
*/
368399
function pushViewEntries(out: ExpectedEntry[], objectName: string, viewName: string, view: any): void {
369400
const root = ['objects', objectName, '_views', viewName];

0 commit comments

Comments
 (0)