T-OBF9-ui-layer-prepare-for-consumers
State: closed/done · Impact: medium · Complexity: medium
packages/ts/ui/tsconfig.json extended ./.nuxt/tsconfig.json, a file
nuxt prepare generates. A consuming app’s vitest transforms a file from the
layer, walks up to the nearest tsconfig — that one — and dies resolving the
extends, because on the consumer’s checkout the layer was never prepared.
The layer’s own gate never noticed: ui:check ran nuxi typecheck, which
regenerates .nuxt before invoking vue-tsc. A layer green while a consumer
is red is how this reached main and stayed there.
The file a consumer resolves and the file the layer typechecks itself with had been the same file, serving two incompatible requirements. They are now two files.
| Location | Role |
|---|---|
packages/ts/ui/tsconfig.json | Consumer-facing. Extends ../tsconfig/presets/vue.json by relative path. Resolves on a checkout where this package was never installed. |
packages/ts/ui/tsconfig.nuxt.json | The layer’s own typecheck. Extends the generated ./.nuxt/tsconfig.json. |
packages/ts/ui/package.json | typecheck is nuxt prepare && vue-tsc --noEmit -p tsconfig.nuxt.json. vue-tsc was already a devDependency. |
apps/agentpants/src-nuxt/tests/useDTheme.test.ts | Passes. Had never run green in CI since it landed in #1508; the job died earlier on every run. |
What was measured
Section titled “What was measured”Three things were established by reproducing the failure locally — delete
packages/ts/ui/.nuxt and, where noted, hide packages/ts/ui/node_modules,
which is the state an agentpants runner is actually in.
The recorded cause was wrong. This task previously said CI installs with
--ignore-scripts, so the layer’s postinstall: nuxt prepare never runs.
agentpants-ci.yml runs bun install --frozen-lockfile with no
--ignore-scripts. The postinstall is not what makes the difference.
Preparing the layer on a consumer’s runner is not available. nuxt prepare resolves @nuxt/kit relative to the rootDir it is preparing, so it
needs packages/ts/ui/node_modules, which agentpants’ scoped install does
not create:
ERROR Cannot resolve module "@nuxt/kit" (from: /packages/ts/ui/)This is unchanged by using a pinned binary instead of bunx. The earlier
attempt (381a91289, reverted by 9a648f2d2) was read as a bunx-pulls-
nuxt@latest problem; that was real but secondary. Running
apps/agentpants/src-nuxt/node_modules/.bin/nuxt prepare ../../../packages/ts/ui
resolves the CLI correctly and still fails on kit. Closing this route means
installing a full Nuxt dependency tree on every agentpants CI run.
The layer genuinely needs the generated config. Dropping the
./.nuxt/tsconfig.json extends outright fixes every consumer and produces
33 errors in the layer’s own source, mostly Nuxt auto-imports:
app/composables/useAppearance.ts: Cannot find name 'useState'app/composables/useDTheme.ts: Cannot find name 'useColorMode'nuxt.config.ts: Cannot find name 'defineNuxtConfig'So the generated config has to stay for the layer, and cannot be on the path a consumer walks. Hence the split.
packages/ts/app-frame was checked as a precedent and rejected: it is the
other Nuxt layer these apps consume and never trips this, because it ships
neither a tsconfig nor a typecheck. Its own moon.yml documents that as a
gap, not a pattern.
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
agentpants:frontend-testpasses withpackages/ts/ui/.nuxtandpackages/ts/ui/node_modulesboth absent — 6 test files, 35 tests, includinguseDTheme.test.ts. - AC-2:
agentpants:frontend-typecheckpasses in the same state. - AC-3:
ui:checkstill passes, and still typechecks the layer against Nuxt’s auto-import types. - AC-4: sdf, zoo and pumice stay green and gain no new dependency —
6, 4 and 9 test files respectively, with the layer’s
.nuxtabsent.
Out of scope
Section titled “Out of scope”- The
--ignore-scriptspolicy. It exists because thenuxt preparepostinstall fan-out OOMs the 8 GB runner (see.github/workflows/ci.yml). - Giving
packages/ts/app-framea typecheck of its own. Itsmoon.ymlalready records what that would take.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Surfaced on #1642, a Rust CI
caching PR, which fixed the failures ahead of this one and let
agentpants-ci reach agentpants:frontend-test for the first time.
The consumer-facing config uses a relative path rather than the
@sksizer/tsconfig/vue specifier for the same reason
#1650 moved the root config off a
specifier: an extends specifier resolves from the directory of the file
spelling it, so it lands in the repo-root node_modules, which a scoped
install never creates.