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

Commit 59e3aaf

Browse files
committed
feat(types): name CommandItem and CommandGroup on the root barrel (objectui#9526)
The element types of `CommandSchema.groups` and its `items` were published on `@object-ui/types/form` only, while `CommandSchema` sat on the root barrel's `./form.js` re-export list, so the root spelling read TS2305. Two names join that list, additively; the declarations stay in `form.ts`. `form-barrel-mirror-9406.test.ts` had ledgered the pair as ABSENT_PENDING_DECISION; both rows are removed so the derived gap check now holds them to the list, and a type-level block pins the root spellings as the containment `CommandSchema` actually carries, with `CommandSchema` itself as the lit control. Claude-Session: https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNC Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8b1f066 commit 59e3aaf

3 files changed

Lines changed: 78 additions & 17 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
"@object-ui/types": minor
3+
---
4+
5+
`CommandItem` and `CommandGroup` are now named exports of `@object-ui/types` itself, not
6+
only of `@object-ui/types/form` (objectui#9526). They are the element types of
7+
`CommandSchema`: `groups` holds `CommandGroup`, and each group's `items` hold `CommandItem`.
8+
9+
Before this release, `import type { CommandItem } from '@object-ui/types'` read `TS2305`
10+
(and the same for `CommandGroup`), while `CommandSchema`, the schema that contains them,
11+
resolved from the same entry point in the same compilation pass.
12+
13+
The change is purely additive: the two names join the root barrel's existing named
14+
re-export list from `./form.js`, beside `CommandSchema`. Nothing is removed, renamed or
15+
narrowed, the declarations stay in `form.ts`, and the `/form` subpath keeps working. It is
16+
the third instance of one class, repaired by the same route each time: objectui#7697 for
17+
`ComboboxOption`, and objectui#9406 (decision batch #133 item 2, letter (a)) for
18+
`InputShorthandSchema` and `UiCalendarSchema`.
19+
20+
`form-barrel-mirror-9406.test.ts` had found these two names and ledgered them as undecided,
21+
because objectui#9406's ruling covered exactly two other names. Both rows are gone now, and
22+
that pin holds the pair to the barrel list the same way it holds every other name `form.ts`
23+
exports.

‎packages/types/src/__tests__/form-barrel-mirror-9406.test.ts‎

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* subpath and invisible from the root, with nothing to say whether that was a
2121
* decision or an oversight.
2222
*
23-
* It has now been found twice, one name at a time:
23+
* It has now been found three times, one card at a time:
2424
*
2525
* - objectui#7697 -- `ComboboxOption`. `import type { ComboboxOption } from
2626
* '@object-ui/types'` read `TS2305` while its two siblings on the same list
@@ -29,6 +29,11 @@
2929
* the zod barrel by objectui#9067 and still unnamed on this one. Repaired
3030
* the same way, by the director seat's decision batch #133 item 2, letter
3131
* (a), maintainer 2026-09-14.
32+
* - objectui#9526 -- `CommandItem` and `CommandGroup`, the element types of
33+
* `CommandSchema.groups` and its `items`. THIS pin found them on its first
34+
* run and ledgered them `ABSENT_PENDING_DECISION`, because objectui#9406
35+
* authorised exactly two names; objectui#9526 moved both onto the list by
36+
* the same additive route and emptied that ledger.
3237
*
3338
* ⭐ What made the second one worse than "the name is not there" is the
3439
* compiler's guess: the root spelling answered `error TS2724: '"@object-ui/
@@ -84,6 +89,17 @@ import type { UiCalendarSchema as UiCalendarFromForm } from '../form';
8489
import type { InputSchema as InputFromRoot } from '../index';
8590
import type { CalendarSchema as CalendarFromRoot } from '../index';
8691

92+
// objectui#9526 -- the element types of `CommandSchema.groups` and its `items`.
93+
// RED on the base that card measured: `TS2305` on each root spelling below,
94+
// while the `/form` spellings and the control resolve in the same pass.
95+
import type { CommandItem as CommandItemFromRoot } from '../index';
96+
import type { CommandGroup as CommandGroupFromRoot } from '../index';
97+
import type { CommandItem as CommandItemFromForm } from '../form';
98+
import type { CommandGroup as CommandGroupFromForm } from '../form';
99+
// The control: the schema that CONTAINS them, already on the root barrel's
100+
// list before objectui#9526. If it fails to resolve, the block is dark.
101+
import type { CommandSchema as CommandFromRoot } from '../index';
102+
87103
const require = createRequire(import.meta.url);
88104

89105
const readSource = (relative: string): string => readFileSync(require.resolve(relative), 'utf8');
@@ -197,22 +213,10 @@ const ABSENT_BY_DECISION: Readonly<Record<string, string>> = {};
197213
* "nobody has decided yet", and it is the honest answer for a name a card found
198214
* but was not authorised to move.
199215
*/
200-
const ABSENT_PENDING_DECISION: Readonly<Record<string, string>> = {
201-
CommandItem:
202-
'An element type of `CommandSchema.groups[].items` (`CommandGroup` is the other). Found by '
203-
+ 'this pin at objectui#9406 and NOT covered by its ruling, which names `InputShorthandSchema` '
204-
+ 'and `UiCalendarSchema` and says "additive, no other line moves" -- so moving these two as '
205-
+ 'well would be widening a published surface past the decision that authorised it. The shape '
206-
+ 'is objectui#7697 exactly (an option/item element type reachable only through the `/form` '
207-
+ 'subpath while its schema `CommandSchema` sits on the root list), and that card ruled the '
208-
+ 'repair sound for `ComboboxOption` -- but it ruled it for that name. Reported for filing '
209-
+ 'with the objectui#9406 report; whoever takes it owns BOTH rows, since one card should '
210-
+ 'settle a pair that is declared and consumed together.',
211-
CommandGroup:
212-
'The element type of `CommandSchema.groups`, holding `CommandItem[]`. The same finding, the '
213-
+ 'same card, the same reason -- see the `CommandItem` row above. Ledgered rather than '
214-
+ 'repaired because objectui#9406 authorises exactly two names.',
215-
};
216+
const ABSENT_PENDING_DECISION: Readonly<Record<string, string>> = {};
217+
// Empty since objectui#9526: its two rows, `CommandItem` and `CommandGroup`,
218+
// were settled by putting both names on the barrel list, so the liveness check
219+
// below would have failed them as stale.
216220

217221
const LEDGER: Readonly<Record<string, string>> = { ...ABSENT_BY_DECISION, ...ABSENT_PENDING_DECISION };
218222

@@ -295,6 +299,30 @@ describe('objectui#9406 -- the two names resolve from the root barrel', () => {
295299
});
296300
});
297301

302+
describe('objectui#9526 -- the element types of `CommandSchema` resolve from the root barrel', () => {
303+
it('each root spelling is the element type the root `CommandSchema` actually contains', () => {
304+
// Pinned as the CONTAINMENT, not as a member list: `groups` holds
305+
// `CommandGroup`, and `CommandGroup.items` holds `CommandItem`. That is the
306+
// whole reason the card moved the pair together.
307+
const group: Eq<NonNullable<CommandFromRoot['groups']>[number], CommandGroupFromRoot> = true;
308+
const item: Eq<CommandGroupFromRoot['items'][number], CommandItemFromRoot> = true;
309+
expect([group, item]).toEqual([true, true]);
310+
});
311+
312+
it('each root spelling is the SAME declaration as its `/form` spelling', () => {
313+
// The same reason as the objectui#9406 block above: a barrel line naming
314+
// a different type would satisfy the containment reading only by accident.
315+
const item: Eq<CommandItemFromRoot, CommandItemFromForm> = true;
316+
const group: Eq<CommandGroupFromRoot, CommandGroupFromForm> = true;
317+
expect([item, group]).toEqual([true, true]);
318+
});
319+
320+
it('CONTROL -- the schema that contains them already resolved from the root', () => {
321+
const command: Eq<CommandFromRoot['type'], 'command'> = true;
322+
expect(command).toBe(true);
323+
});
324+
});
325+
298326
/* == (b) the instrument: the barrel list against `form.ts`'s exports ========= */
299327

300328
describe('objectui#9406 -- the root barrel mirrors `form.ts`, or says why not', () => {

‎packages/types/src/index.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,16 @@ export type {
204204
// tidy cannot silently drop either one.
205205
ComboboxOption,
206206
CommandSchema,
207+
// The element types `CommandSchema` contains — `groups` holds `CommandGroup`,
208+
// whose `items` hold `CommandItem` — listed next to their schema the way
209+
// `ComboboxOption` is above (objectui#9526). Both were already published on
210+
// `@object-ui/types/form`, and their zod twins `CommandItemSchema` /
211+
// `CommandGroupSchema` on `@object-ui/types/zod`, while the root spelling read
212+
// TS2305. Purely ADDITIVE, the objectui#7697 / objectui#9406 route; the gap pin
213+
// `form-barrel-mirror-9406.test.ts` had ledgered the pair as undecided and
214+
// now holds it to this list.
215+
CommandItem,
216+
CommandGroup,
207217
InputOTPSchema,
208218
ToggleSchema,
209219
FormSchema,

0 commit comments

Comments
 (0)