spec(types,plugin-detail,vscode-extension): TS twins of the zod-only node arms, the README's Activity tab on its declared properties, and Export to React's typed schema constant (objectui#11515) - #11519
Conversation
…chema-renderer and cloud:plan-status, parity-paired (objectui#11515) `@object-ui/types` declared no TypeScript type for three arms its zod face already publishes. Each gains a twin beside its arm's module (`DetailSectionNodeSchema` in views.ts, `AppSchemaRendererNodeSchema` in app.ts, `CloudPlanStatusSchema` in a new cloud.ts), joins `AnySchema`, and is registered as a `zod-mirror-parity` pair instead of an exclusion. `cloud:plan-status` measures clean. The other two are born ledgered with the reading their by-reference member already carries one level up: `fields` (the DetailViewField `options` divergence) and `schema` (the app document's SCHEMA-NODE wider reading). Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
…y's declared properties, not the host feed slot `items` (objectui#11515)
`items` is the host's feed slot, which the `record:activity` node refuses
by name. The tab now authors `properties: { limit, showCompleted }`, as the
plugin-detail guide does, and the note below the block says where the feed
comes from: a record host, or the empty state in a bare `DetailView`.
Rendered through `DetailTabs` and the real registry, the tab draws the
block's empty state. The zod docblock that named this README as a host
composition passing `items` gets a dated parenthesis.
Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC
Co-authored-by: Claude <noreply@anthropic.com>
…chemaRendererProps['schema'], and the doc sample authors declared types (objectui#11515) Unannotated, every `type` in the emitted constant widens to `string`, which a prop that discriminates on the literal `type` refuses (objectui#11466). `SchemaNode`, the annotation the card named, was measured and does not compile today or under that change: it admits `number` and `boolean`, which the prop leaves out, and the initializer's narrowing does not reach the component body. `SchemaRendererProps['schema']`, from the package the file already imports, compiles in both. The compile pin gains a leg against the REAL prop type: `@object-ui/types` resolves to its source entry and the `@object-ui/react` declaration carries the `SchemaRendererProps` body read out of SchemaRenderer.tsx, with a positive control refused on the constant's own line. The two documented mirrors follow the new preamble, and the mdx sample writes `text` with its `h1` variant. Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
…e pending entries it makes false, and the cli pin on the README's full document - `@object-ui/types` minor (the three TS twins), `object-ui` patch (the Export to React annotation), `@object-ui/plugin-detail` patch (the README's Activity tab). - Dated notes on 8114 and 11321 (the README no longer hands `record:activity` its `items`) and 11478 (`AnySchema` gains three members). - `validate-passing-keys-11440.test.ts` described the README's second tab as the host feed; it now validates the full document as the page writes it and keeps the host-feed row as the refusal's control. Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
… `h1` node (objectui#11515) `h1` is a declared type (`HtmlElementSchema`, objectui#8499), and `check-doc-component-types.test.ts` pins it in this very sample as the registered replacement for `heading`. With the constant annotated, the `h1` sample compiles against the built packages today and with objectui#11466 applied (measured with tsc and with check:doc-snippets on both trees), so the `text` / `variant: 'h1'` rewrite the card proposed is not needed and is reverted. The compile pin's documented sample follows. Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Inputs: card #11515 (body and its 3 comments: claim 5962501941, os-dev report 5963118595, seat answers 5963138450); PR #11519 (body, 19-file list, net diff against ① Derived judgments
Public-surface summary: ② Semver level
③ Boundary flagsEach deviation and open question in report 5963118595, with the seat's answer in comment 5963138450 and my own check of the head:
Check-runs on Implemented-by: VERDICT: PASS |
Fixes #11515
Clause-②: yes (widening)
Part of the preparation for objectui#11466 (V1, draft PR #11512). On PR #11512's head,
check:doc-snippetsjudges 776 blocks and refuses 2: the plugin-detail README'sdetail-view"With Tabs" example and the Export to React "Output Example" incontent/docs/utilities/vscode-extension.mdx. This PR settles both. Measured under a throwaway probe (this branch plus PR #11512's commits, merged without a commit, never pushed), the same gate judges 776 and refuses 0. With V1's own copies of the two documents in that probe, it refuses exactly those 2.Block 1 — TS twins of the zod-only node arms (ruling A)
Before.
@object-ui/typesdeclared no TypeScript type for three arms its zod face already validates:detail-section(views.zod.ts#DetailSectionNodeSchema),app-schema-renderer(app.zod.ts#AppSchemaRendererNodeSchema) andcloud:plan-status(cloud.zod.ts#CloudPlanStatusSchema).SchemaByTypeof each literal wasnever, and the parity census carried all three asEXCLUSIONS("no TS declaration in this package restates the node").After. Each gains a twin beside its arm's module, member for member:
views.zod.ts#DetailSectionNodeSchemaDetailSectionNodeSchema(views.ts, inViewComponentSchema).picks fromDetailViewSectionSchema(title,description,icon,fieldsrequired,collapsible,defaultCollapsed,columns,showBorder,headerColor,hideEmpty), eachDetailViewSection's own member by indexed access;body/children?: neverapp.zod.ts#AppSchemaRendererNodeSchemaAppSchemaRendererNodeSchema(app.ts, inAnySchema)schema?: AppComponentSchema(the arm's member ISAppComponentSchema),basePath?: string,mobileNavMode?: 'drawer' or 'bottom_nav';body/children?: nevercloud.zod.ts#CloudPlanStatusSchemaCloudPlanStatusSchema(newcloud.ts, inAnySchema)properties: { plan: string }, required and closed;body/children?: neverNo zod schema, validator verdict or runtime behaviour changes. The widening is the TS face's declared surface only, matching what the zod face already publishes (the
Clause-②line above).Pins.
zod-mirror-parity.test.ts: the three pairs move fromEXCLUSIONSintoMIRRORS/Declared;EXPECTED_MIRROR_PAIRS191 to 194.cloud:plan-statusmeasures clean in all four directions. Two pairs are born ledgered, each with the reading its by-reference member already carries one level up (same cause, not a new finding):KnownDriftgainsviews.zod.ts#DetailSectionNodeSchema: 'fields', theDetailViewFieldoptionsEXPECTED DIVERGENCE, as onviews.zod.ts#DetailViewSectionSchema. Header figures 49 / 87 to 50 / 88, with the history sentence.WiderThanDeclaredgainsapp.zod.ts#AppSchemaRendererNodeSchema: 'schema', one SCHEMA-NODE arm: the app document's own wider reading throughNavigationItemSchema'sz.ZodTypeofanyannotation, theapp.zod.ts#AppComponentSchemaareasrow's cause. Header figures 3 / 3 / 3 (2 / 1 / 0 / 0) to 4 / 4 / 4 (3 / 1 / 0 / 0).anyschema-declared-node-types-11478.test.tsstays green: the three types areAnySchemamembers.node-recursion-point-8344's measured set exists only on PR feat(types,react,core,plugin-dashboard)!: a node slot and SchemaRenderer'sschemaprop take the declared-node union, V1; the dashboard producers name declared nodes and an envelope's object-metric retires (objectui#11466) #11512's head. Onmainthat pin readsnever, becauseSchemaNode's object arm is stillBaseSchema. Measured in the probe: with these twins, V1'sMeasuredArmDrift11466pin goes red (TS2344) until exactlydetail-section,app-schema-rendererandcloud:plan-statusare deleted from it, and is green after (typestype-checkexit 0). That deletion lands on PR feat(types,react,core,plugin-dashboard)!: a node slot and SchemaRenderer'sschemaprop take the declared-node union, V1; the dashboard producers name declared nodes and an envelope's object-metric retires (objectui#11466) #11512 when it mergesmain.schemaprop take the declared-node union, V1; the dashboard producers name declared nodes and an envelope's object-metric retires (objectui#11466) #11512 conflicts inzod-mirror-parity.test.ts(three hunks, both sides' rows kept). The union measures 6 / 6 / 8 (3 / 3 / 0 / 2) forWiderThanDeclared, confirmed by the derived-figure pin in the probe.The README's Activity tab. It authored
record:activitywithitems: activityData, the host feed slot the node refuses by name (objectui#11321). It now authors the declared input,properties: { limit: 20, showCompleted: false }, as the plugin-detail guide does; theFeedItemimport andactivityDatago. The note under the example says where the feed comes from. Rendered throughDetailTabsand the real registry (a one-off probe, not kept), the tab drawsActivity (0), theAll Activityfilter andNo activity recorded, with no unknown-type panel and no error banner. The zod docblock inpublic-blocks.zod.tsthat named this README as a host composition passingitemsgets a dated parenthesis.Block 2 — the Export to React generator (ruling A, route changed by measurement)
Before. The emitted constant was unannotated, so every
typewidened tostring; under V1 the one JSX line is refused for every schema (TS2322 against the declared-node union).The card's annotation, measured.
const schema: SchemaNodedoes NOT compile, today or under V1:SchemaNodealso admitsnumberandboolean, whichSchemaRendererProps['schema']leaves out, and the narrowing at the initializer does not reach the body ofGeneratedComponent. With it, the JSX line was refused for every schema on both trees, including the documented sample. That is the ruling's own premise ("it exists today and compiles both now and after V1") measured false, so the route follows the ruling's intent instead: a type that exists today, is notDeclaredNode, and compiles against the prop on both trees.After. The constant is typed
SchemaRendererProps['schema'], imported type-only besideSchemaRendererfrom the package the file already imports (no new dependency). Emitted output for the documented sample, before and after:tsc(strict,react-jsx,noUnusedLocals) on the emitted file, against the BUILT packages of each tree:divwith anh1child)typeThe
SchemaNodeannotation and asatisfies SchemaNodevariant were measured on the same grid; the table is in the report on the card.The documented sample keeps
"type": "h1". The card readsh1as undeclared; it is declared, one of the HTML passthrough tagsHtmlElementSchemadeclares (objectui#8499), andscripts/__tests__/check-doc-component-types.test.tspins"type": "h1"in this very sample as the registered replacement forheading. Annotated, theh1sample compiles on both trees (table above, andcheck:doc-snippetson both). A rewrite totextwithvariant: 'h1'was tried and reverted when that pin went red; the PM may still order it (one sample edit plus that pin).Pins. The emitter has tests:
export-to-react-compiles.test.tsandexport-to-react-preamble.test.ts.unknown, so it could not see an annotation. A new leg compiles the emitted file against the REAL prop type with no build:@object-ui/typesresolves to its source entry, and the@object-ui/reactdeclaration carries theSchemaRendererPropsbody and its@object-ui/typesimport read out ofpackages/react/src/SchemaRenderer.tsxat test time, so it follows the prop when V1 retypes it. Its positive control is a schema with notype, refused on the constant's own line.mainthe control turns red (the refusal moves from the constant's line to the JSX line); in the V1 probe both legs turn red (the sample is refused with TS2322, widenedtype: string).DESIGN.mdsection 4 and the docs page) follow the new preamble, held by the existing objectui#7976 pin.Corpus documents re-judged
packages/plugin-detail/README.md, "With Tabs": re-authored (above). Itsdetail-sectiontab was refused under V1 for want of a TS type; with the twins it compiles under V1 unchanged.content/docs/utilities/vscode-extension.mdx, "Output Example": new preamble and annotated constant; sample unchanged.packages/vscode-extension/DESIGN.md, section 4: new preamble.packages/cli/src/__tests__/validate-passing-keys-11440.test.tsdescribed the README's second tab as the host feed. It now validates the full example document as the README writes it (green onobjectui validate), and keeps the host-feed row as the refusal's control.Pending changesets
8114-detail-tab-activity-timeline.md(itsitems, not databullet and theactivityDatasentence),11321-record-feed-host-slots.md(the README as theitemscomposition),11478-anyschema-declared-node-types.md(ViewComponentSchema's four members;AnySchemagains three).10919-cloud-plan-status,11440-arm-passing-types,11494-types-app-schema-renderer-schema,11494-layout-app-schema-renderer-adapter(all state the zod face and the registration; none says the TS face lacks a type),7837,7862and7976(Export to React preamble history; the side-effect import, the absent React import and the mirror binding all still hold), and the 25 entriescheck:changeset-claimslists as naming a touched file (each describes another pair, key or README section).11515-types-ts-twins-zod-only-arms.md(@object-ui/typesminor),11515-vscode-export-react-annotation.md(object-uipatch),11515-plugin-detail-readme-activity-properties.md(@object-ui/plugin-detailpatch).Verification (head
afb660b7)pnpm --filter @object-ui/types run type-check(all threetsclegs),pnpm --filter @object-ui/cli run type-check,pnpm --filter object-ui run type-check: exit 0.pnpm exec vitest run packages/types/ packages/vscode-extension/plus the cli validate test, the plugin-detail README reader andscripts/__tests__/check-doc-component-types.test.ts:Test Files 349 passed (349),Tests 9299 passed (9299).pnpm check:doc-snippets:776 of 776 block(s) judged, 0 failed.check:doc-types,check:doc-examples,check-changeset-no-major,check-changeset-presence,check:new-line-citations,check:control-bytes: green.check:changeset-claimsis report-only (read above).type-checkexit 0 with the three names out of the 8344 set; the parity, 8344, node-slot-union and AnySchema suites pass;check:doc-snippetsjudges 776 and refuses 0. The probe's plugin-dashboard build needed four throwawayas nevercasts at the producer sites PR feat(types,react,core,plugin-dashboard)!: a node slot and SchemaRenderer'sschemaprop take the declared-node union, V1; the dashboard producers name declared nodes and an envelope's object-metric retires (objectui#11466) #11512 already reports red; they never left the probe.check:sdui-registration-pins(no registration input moved; it needs a console build), repo-wide lint (CI's).Acceptance notes
export-to-react-compiles.test.ts'sSAMPLE_SCHEMAstill writes the retiredbodywhile its comment calls it theemptytemplate's shape (the template writeschildren). Inert under the hermetic stub; not touched here.Generated by Claude Code