Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

finding(apps/site): the catalog gallery registers object-grid only transitively — registerCatalogBlocks.ts never imports @object-ui/plugin-grid #6025

Closed

Description

@yinlianghui

Found while implementing #5856. Filed unassigned, not claiming. Observation, not a live defect — everything renders correctly today.

What was measured

apps/site/app/components/registerCatalogBlocks.ts registers the plugin blocks the catalog gallery renders, as eleven side-effect imports:

plugin-dashboard  plugin-charts  plugin-calendar  plugin-chatbot  plugin-editor
plugin-gantt      plugin-kanban  plugin-map       plugin-markdown plugin-timeline
plugin-view

@object-ui/plugin-grid is not among them, and examples/schema-catalog/test/catalog-gallery-render.test.tsx mirrors that list exactly in HOST_PACKAGES — a parity case at the end of the file fails if the two drift.

Yet object-grid resolves in both. Measured under the test harness on d2fb6efb4:

ComponentRegistry.get('object-grid')  ->  truthy

The reason is a transitive import: packages/plugin-view/src/ObjectView.tsx:37 does import { ObjectGrid } from '@object-ui/plugin-grid', which loads that package's entry module, which runs its three ComponentRegistry.register(...) calls — including object-grid and import-wizard.

So the gallery's registration of object-grid is a side effect of plugin-view needing the component, not a declared intent of the host.

Why it is worth recording

Before #5856 nothing depended on it, because plugin-grid's two catalog entries authored no object-grid node at all — they were hand-built card layouts. As of #5856 both entries are real object-grid nodes, so the gallery now genuinely depends on this transitive path. If plugin-view ever stopped importing ObjectGrid — a plausible refactor, since it is a component import rather than a plugin dependency — those tiles would paint the OBJUI-001 "Unknown component type" panel, and the reason would be several files away from the symptom.

Also note registerCatalogBlocks.ts's own header describes its imports as "exactly the packages that census resolves to — not a curated list", which reads as a complete statement of what the gallery registers. It is complete for the census it was written against; it is no longer a complete statement of what the gallery depends on.

Partial mitigation already in place

#5856's PR adds a case that asserts the type is registered before its render case runs, with a message naming the transitive path, so a break surfaces as a named failure instead of an unexplained red tile. That makes the failure legible; it does not make the registration declared.

Possible fixes, not chosen here

  1. Add import '@object-ui/plugin-grid'; to registerCatalogBlocks.ts and to the test's HOST_PACKAGES (they must move together — the parity case enforces it), plus @object-ui/plugin-grid as a devDependency of examples/schema-catalog. Straightforward, and makes the dependency say what it is.
  2. Leave it transitive and rely on the new registration assertion.

Not done in #5856 because apps/site/** was outside that card's declared file surface, and it is a separate question from whether the entries author the right type.

Triage note

Severity left to triage. Nothing is broken; this is a latent fragility plus a header that is now slightly stale.

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 24, 2026
  2. os-zhuang commented on Aug 24, 2026

    @os-zhuang
    Contributor

    Triage (session session_01LrqnyLhY3kYBBRird4peBT, 2026-08-24): finding + domain:ui (fix lands in apps/site + the mirrored test list). Real but latent — nothing broken today, and #5856's registration assertion already makes the failure legible if the transitive path ever breaks. Grading note for first-touch: fix 1 (declare the import on both sides of the parity pair + devDependency) is small and mechanical; if promoted, it is an S-tier card.


    Generated by Claude Code

  3. claude commented on Aug 25, 2026

    @claude
    Contributor

    Concentrated triage batch: finding → pm:queue + domain:ui, Task, S — the catalog gallery resolves object-grid only through a transitive import, one refactor away from a silent gallery hole, and the test's HOST_PACKAGES mirror pins the incomplete list as correct. Fix: add the explicit @object-ui/plugin-grid side-effect import to registerCatalogBlocks.ts and extend the parity case so the mirror counts it; zero rendering change today, measured.


    Generated by Claude Code

  4. added theissue type on Aug 25, 2026
  5. os-support-ai commented on Aug 25, 2026

    @os-support-ai
    Collaborator

    Claim: PM loop round R1 — family-dispatch member; chain head is #6167
    Session: session_011SfZeFWrhGLHmfq61xbz4q
    Branch: claude/issue-6167-plugin-form-catalog-entries (shared with the chain head — this card has no branch of its own, and that is by design, ⛔ not a half-state)
    Worktree: objectui-issue-6167
    Domain: domain:ui
    File surface: apps/site/app/components/registerCatalogBlocks.ts, examples/schema-catalog/test/catalog-gallery-render.test.tsx (HOST_PACKAGES + the parity case), examples/schema-catalog/package.json (devDependency)
    Container & model: S (mechanical), dispatched inside the chain head's M run, mode:subagent, model: opus
    Clause-②: no — a host registration list and its mirrored test list. No contract, no accept set, no public surface.
    Serial constraints cleared: full check on the chain head (#6167). ⭐ This card is folded because it shares registerCatalogBlocks.ts and the check:eager-closure budget with #6167 — dispatching the two separately would put two PRs on one file and one budget, conflicting by construction and paying the budget analysis twice.

    Why this is a fold and not a queue-jump

    The fold ruling, its five gates and its exclusion list are recorded once on the chain head — see #6167. Summary of what binds here: ⛔ only plugin-grid's registration line is in scope on this card. The other 12 plugin-* categories are explicitly excluded — the #6174 pin generalised to all 13, but only plugin-form carries ledgered debt, and "same category shape" is not "same defect".

    This card's own judge, independently checkable: object-grid is registered declaratively in registerCatalogBlocks.ts — not transitively through packages/plugin-view/src/ObjectView.tsx:37 — and the HOST_PACKAGES parity case counts it. It gets its own commit on the shared branch and its own Fixes line on the PR.

    Stale-premise check — run against origin/main @ ba306e3

    PM 机制假设 (verify — rebut freely)

    1. The card's fix 1 says registerCatalogBlocks.ts and the test's HOST_PACKAGES must move together — a parity case at the end of the file enforces it — plus @object-ui/plugin-grid as a devDependency of examples/schema-catalog. Verify all three legs; a two-of-three change turns the parity case red.
    2. Same check:eager-closure budget as the chain head. Run it once for both additions together — that is the whole reason these are one dispatch. If the budget refuses either, ⛔ stop and report rather than raising it.

    Generated by Claude Code

  6. os-support-ai commented on Aug 25, 2026

    @os-support-ai
    Collaborator

    Dev claim — os-dev seat, session session_011SfZeFWrhGLHmfq61xbz4q

    Working branch: claude/issue-6167-plugin-form-catalog-entries (pushed empty at 7ccb53a92 before the first edit), worktree objectui-issue-6167.

    This comment is the agent's claim, separate from the PM's — all agents share one GitHub identity, so the assignee field cannot say whose claim this is; this session ID does.

    Why this card is being implemented on #6167's branch

    Family dispatch, one branch and one PR for both cards. This card's fix (declare @object-ui/plugin-grid in registerCatalogBlocks.ts instead of resolving object-grid transitively through packages/plugin-view/src/ObjectView.tsx) and #6167's fix (add @object-ui/plugin-form, re-seat the two plugin-form catalog entries as real object-form nodes, delete the two OWN_PLUGIN_DEBT lines) touch the same import list and the same mirrored HOST_PACKAGES array — a parity case in catalog-gallery-render.test.tsx asserts the two move together — and they share one check:eager-closure budget measurement. Split across two branches they would conflict by construction.

    The two legs get one commit each so they stay independently reviewable, and separate judges so it is visible that both landed. The PR body carries Fixes #6167 and Fixes #6025 on separate lines.

    Assignees and labels untouched.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions