Skip to content

finding(types): KanbanCard / KanbanColumn are declared four times in this tree and the published copies disagree (cards vs items, badges vs labels) #6155

Description

@yinlianghui-tw

Measured on origin/main228909995 while sweeping #6086 (prose restatements of a declared surface). Filed unassigned, not fixed — out of that card's scope, which owns docs prose, not the declarations underneath it.

The fact

Four declarations of each name coexist:

fileKanbanColumn membersKanbanCard notable members
packages/plugin-kanban/src/types.ts:15,49id, title, cards, limit, classNamebadges
packages/plugin-kanban/src/KanbanImpl.tsx:51,81id, title, cards, limit, classNamebadges, cardSubtitle, cardFieldCells, coverImage
packages/plugin-kanban/src/KanbanEnhanced.tsx:36,50id, title, cards, limit, className, collapsedbadges, coverImage
packages/types/src/complex.ts:28,58id, title, **items**, color, limit, collapsedlabels, assignees, dueDate, priority, content, data

The last row is the divergent one, and both sides are published:

  • @object-ui/plugin-kanban re-exports its own copy — packages/plugin-kanban/src/index.ts:111 exports KanbanCard, KanbanColumn from ./types.
  • @object-ui/types exports the complex.ts copy under the same two names.

So a consumer who writes import type { KanbanColumn } from '@object-ui/types' gets a shape whose rows live under items, and a consumer who imports the same name from @object-ui/plugin-kanban gets one whose rows live under cards. Neither import is wrong; they are different types wearing one name.

Why it is worth recording

It is not only a consumer hazard. It makes the name undecidable for any tool keyed on it. This was measured directly: a name-to-declaration resolver built for the #6086 sweep reported content/docs/plugins/plugin-kanban.mdx's cards and badges rows as contradicted keys, because it resolved KanbanColumn / KanbanCard to the @object-ui/types copy. The page is correct — it documents the plugin's own copy — and the false verdict came entirely from the ambiguity. Any future gate that checks a documented key list against "the declaration of that name" walks into the same wall here, and the failure mode is a confident wrong answer rather than an abstention.

Not decided here

Whether the fix is to collapse onto one declaration, to rename one side, or to leave two deliberately distinct shapes with distinct names, is a design call — the @object-ui/types copy carries object-driven-board fields (assignees, dueDate, priority) the plugin copy does not, so they may not be the same concept at all. Recording the measurement so the choice is made deliberately.

Reproduce

grep -rn "interface KanbanColumn\|interface KanbanCard" packages/*/src --include=*.ts --include=*.tsx
grep -n "KanbanCard, KanbanColumn" packages/plugin-kanban/src/index.ts

Refs: #6086 (where this was measured).


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:blocked

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions