Repository navigation
Commit 1dbb993
Fixes #10287
Clause-②: no
## What was wrong
objectstack#19789 added a `doc` member to the spec's navigation item
union. In `packages/plugin-designer/src/NavigationDesigner.tsx`,
`NAV_TYPE_META` is a `Record` keyed by the spec-derived
`NavigationItemType`, and it had nine entries and no `doc`. So `Spec
Main Shape Gate`, which compiles objectui against `@objectstack/spec`
built from objectstack `main`, failed with TS2741 on that map on `main`
and on every PR head. The TS7016 errors in app-shell's `AppContent.tsx`
were a knock-on effect of the failed `plugin-designer` build.
## What changed
- `NAV_TYPE_META` gets a `doc` entry: `labelKey:
'appDesigner.navTypeDoc'`, `bg-blue-100 text-blue-700` (a colour none of
the other nine use), and lucide `BookOpen`.
- **It has to compile against two specs.** The pinned
`@objectstack/spec` 17.4.0 has no `doc`, so a plain `doc:` key is an
excess property there (TS2353). objectstack `main` has `doc`, so the
gate fails without the key (TS2741). The map is now a `Record` keyed by
`NavigationItemType | 'doc'`, which compiles against both. A comment in
the code says the `| 'doc'` goes at the pin bump that ships `doc`. The
map is still a `Record` over the spec-derived union, not `Partial` and
not string-keyed.
- `appDesigner.navTypeDoc` is added to the `useDesignerTranslation`
English fallback table and to all ten locale packs, each in its own
language.
- Guard test
`packages/plugin-designer/src/__tests__/NavigationDesigner.specNavTypes.test.tsx`:
it reads the discriminants of the **installed** spec's
`NavigationItemSchema` at runtime, renders one item of each type in the
tree and the live preview, and asserts that the type badge shows a label
and not a raw key. It checks that every spec type is in the map, not
that the two sets are equal, because the map has `doc` before the pin
does. Run against the pinned spec it covers 9 types. Run against a spec
built from `main` it covers 10.
- `doc` is **not** added to `QUICK_ADD_TYPES`. An empty `doc` item fails
the spec's book-or-doc requirement, and authoring one belongs to
objectui#10188.
- Changeset: `@object-ui/plugin-designer` and `@object-ui/i18n` `patch`.
## Verification (every run below is on head `6f970da0`)
**The gate's own path, reproduced locally.** objectstack `main` was
`6bf7f1c0b441` when this was read. I made a sparse, blobless clone of it
the way the workflow does, ran `pnpm --filter @objectstack/spec build`,
ran `npm pack --ignore-scripts`, and ran `node
scripts/spec-main-shape-gate.mjs inject` into a separate objectui
worktree. The inject step re-pointed zod to 4.6.1, which is the gate's
own behaviour. Then I ran a forced turbo `type-check --continue` in that
worktree, with a private cache dir.
| run | objectui tree | scope | result |
|---|---|---|---|
| RED | `8b1f0661` (origin/main) | `--filter=@object-ui/plugin-designer`
(17 tasks) | `plugin-designer:type-check` fails at
`NavigationDesigner.tsx(82,7)` with **TS2741** "Property 'doc' is
missing". The gate's `report` step exits 1 and attributes the error to
that file and to `6bf7f1c0b441`. |
| GREEN | `6f970da0` (this branch) |
`--filter=...@object-ui/plugin-designer` (40 tasks) | `Tasks: 40
successful, 40 total`, 0 `error TS`. The report step exits 0: "objectui
type-checks against `@objectstack/spec` at that commit." |
The GREEN scope is plugin-designer and **its dependents**:
`plugin-designer`, `app-shell`, `console`, `example-console-starter` and
`example-byo-backend-console` type-check, plus 33 builds, including the
`plugin-designer` and `app-shell` builds that the failure had been
hiding. **Nothing new surfaces once the build is unblocked.** I narrowed
the scope on purpose: a package that does not depend on plugin-designer
cannot be moved by this diff, and the full-graph run is this PR's own
`Spec Main Shape Gate` check.
**Pinned spec (17.4.0), normal path.** `pnpm --filter
@object-ui/plugin-designer --filter @object-ui/i18n type-check` passes.
Both `tsc --noEmit && tsc -p tsconfig.test.json` scripts echoed. `tsc -p
tsconfig.test.json --listFiles` includes the new test file.
**Ablation.** I committed the change first. `ablation-replace.mjs`
deleted the `doc` entry line and verified it on disk (anchor count 1 to
0, blob `dc6cc9b5f055` to `a1ec0cb78efb`). It then restored the file to
HEAD and proved the restore (the blob matches HEAD's and `git diff HEAD`
is empty).
| leg | with the `doc` entry | `doc` entry deleted |
|---|---|---|
| gate path (main spec): plugin-designer type-check | green | **TS2741**
"Property 'doc' is missing" |
| gate path (main spec): guard test | 11 passed | **1 failed**: "draws
the `doc` type…", `TypeError: Cannot read properties of undefined
(reading 'Icon')` |
| pinned spec: plugin-designer type-check | green | **TS2741**, because
the `Record` key now includes `'doc'` |
| pinned spec: plugin-designer type-check with `\| 'doc'` removed from
the key | — | **TS2353** "'doc' does not exist in type" (this shows the
extra union member is needed) |
**Suites, run from the repo root:**
- `pnpm exec vitest run packages/plugin-designer/ packages/i18n/
packages/app-shell/src/__tests__/defaults-maps-mirror-en-pack.test.tsx`:
`Test Files 94 passed (94)`, `Tests 1340 passed (1340)`.
- The three files run by name (`all-locales-key-parity`,
`defaults-maps-mirror-en-pack`, the guard test): `3 passed`, `57 tests
passed`.
**Gates, all exit 0:**
- `check:i18n-keys`, `check:i18n-drift` (1 key added, 0 en values
changed), `check:i18n-dead-keys` (report only; `navTypeDoc` lands in
needs-review like its nine siblings, because the key is reached through
the map and not through a literal `t()` call), `check:control-bytes`,
`check:new-line-citations` (0 new);
- `node scripts/check-changeset-presence.mjs`, `check:changeset-claims`,
`check:pending-changeset-literals`;
- `check:phantom-deps`, `check:unused-deps`, `check:icon-record-names`,
`check:spec-symbols`, `check:test-path-roots`,
`check:designer-field-key-parity`, `check:installed-pin-claims`,
`check:published-tsconfig-exclude`, `check:published-dist`,
`check:vi-mock-inherit`, `check:unreferenced-sources`.
**Lint, narrowed to the files this PR touches:**
1. Population: `pnpm lint` is `turbo run lint`, which runs `eslint .`
per package. `eslint --print-config` resolves a config for each of the
13 changed `.ts`/`.tsx` files, so none of them is ignored.
2. `eslint --no-inline-config --format json` on those 13 files reports 0
errors and 4 warnings. All 4 are in `NavigationDesigner.tsx`. The base
version of that file, linted through stdin, gives the same 4 warnings,
and none of them is on a changed line.
3. `eslint.config.js` does not turn on type-aware linting (no
`parserOptions.project` or `projectService`), and no rule under
`eslint-rules/` reads other files. So this diff cannot change the
verdict on any file it does not touch.
**NOT MEASURED:**
- `check:eager-locale-catalogues`: PREREQUISITE NOT MET, it needs
`apps/console/dist/eager-closure.json`.
- `check:doc-examples`: prerequisite not met, it needs built `dist/` for
about 20 packages. This diff touches no doc example.
- Both are left to CI's build jobs.
## Acceptance notes
- **Out of scope, as the triage recorded:** the product gaps around
`doc` belong to objectui#10188, not this PR. They are the
`NavigationRenderer` and `navSurface` `default:` fallthroughs, the
`AppNavCanvas` `KIND_TONE` fallback, `AppCreationWizard`
`TYPE_BADGE_COLORS`, the hand-written nine-member
`NavigationItemTypeSchema` in `packages/types`, and quick-add or
authoring of `doc` items.
- **Wording now slightly out of date:** the doc comment on
`NavigationItemType` in `packages/types/src/app.ts` still describes
`NAV_TYPE_META` as keyed by exactly `NavigationItemType`. The point it
makes (a new spec member breaks the compile loudly) still holds. The
wording goes back to exact at the pin bump. It is outside this surface,
so I left it.
- **A hazard when reproducing the gate locally, for whoever runs it
next:** turbo 2.10 shares one local cache across linked git worktrees
("using shared worktree cache"). Turbo's hash does not cover
`node_modules`. So a gate reproduction in a linked worktree writes build
outputs compiled against the injected spec into the cache that sibling
worktrees read. The workflow's `TURBO_FORCE` bypasses cache reads but
does not stop the writes. Pass `--cache-dir` pointing at a private
directory. My first attempt did write 6 entries before I stopped it. I
compared each of them with the same package built against the pinned
spec, and all 6 are byte-identical, so nothing wrong is in the shared
cache.
Written by the `domain:ui` seat #1 dev agent, session
`https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNC`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNC)_
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8b1f066 commit 1dbb993
14 files changed
Lines changed: 137 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1405 | 1405 | | |
1406 | 1406 | | |
1407 | 1407 | | |
| 1408 | + | |
1408 | 1409 | | |
1409 | 1410 | | |
1410 | 1411 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1398 | 1398 | | |
1399 | 1399 | | |
1400 | 1400 | | |
| 1401 | + | |
1401 | 1402 | | |
1402 | 1403 | | |
1403 | 1404 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1647 | 1647 | | |
1648 | 1648 | | |
1649 | 1649 | | |
| 1650 | + | |
1650 | 1651 | | |
1651 | 1652 | | |
1652 | 1653 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1402 | 1402 | | |
1403 | 1403 | | |
1404 | 1404 | | |
| 1405 | + | |
1405 | 1406 | | |
1406 | 1407 | | |
1407 | 1408 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1400 | 1400 | | |
1401 | 1401 | | |
1402 | 1402 | | |
| 1403 | + | |
1403 | 1404 | | |
1404 | 1405 | | |
1405 | 1406 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1398 | 1398 | | |
1399 | 1399 | | |
1400 | 1400 | | |
| 1401 | + | |
1401 | 1402 | | |
1402 | 1403 | | |
1403 | 1404 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1398 | 1398 | | |
1399 | 1399 | | |
1400 | 1400 | | |
| 1401 | + | |
1401 | 1402 | | |
1402 | 1403 | | |
1403 | 1404 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1397 | 1397 | | |
1398 | 1398 | | |
1399 | 1399 | | |
| 1400 | + | |
1400 | 1401 | | |
1401 | 1402 | | |
1402 | 1403 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1408 | 1408 | | |
1409 | 1409 | | |
1410 | 1410 | | |
| 1411 | + | |
1411 | 1412 | | |
1412 | 1413 | | |
1413 | 1414 | | |
| |||
0 commit comments