Skip to content

fix(libs): pin the type-tests compiler; document the tsconfig baseUrl blocker - #1066

Merged
blove merged 2 commits into
mainfrom
blove/drop-tsconfig-baseurl
Sep 8, 2026
Merged

fix(libs): pin the type-tests compiler; document the tsconfig baseUrl blocker#1066
blove merged 2 commits into
mainfrom
blove/drop-tsconfig-baseurl

Conversation

@blove

@blove blove commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

What changed

Two things, both downstream of trying to remove baseUrl from tsconfig.base.json.

1. The type-tests targets now run the workspace TypeScript.

They invoked npx tsc, which does not resolve to the workspace compiler here. @dawn-ai/core depends on @typescript/typescript6, which depends on @typescript/old (npm:typescript@6.0.2); that package's tsc bin wins the hoist at node_modules/.bin/tsc. So npx tsc is TypeScript 6.0.2 while every other target compiles with the declared 5.9.3:

$ npx tsc --version
Version 6.0.2
$ node -e "console.log(require('typescript/package.json').version)"
5.9.3

That mismatch is what raised TS5101 on the inherited baseUrl, which #1064 silenced with "ignoreDeprecations": "6.0". The targets now invoke node ./node_modules/typescript/bin/tsc, so they type-check the public API with the compiler the workspace actually declares, and the ignoreDeprecations holding action is gone from all three configs.

The "rootDir": "../.." lines stay — they solve the unrelated problem of type-specs importing sibling libraries through path mappings.

2. baseUrl stays in tsconfig.base.json, with the reason recorded next to it.

Why baseUrl could not be removed

The premise checks out: since TypeScript 5.0 the paths entries resolve against the directory of the tsconfig that declares them, and --traceResolution confirms it against the installed compilers — with baseUrl gone, @threadplane/chat still resolves to libs/chat/src/public-api.ts, now via pathsBasePath rather than baseUrl. No source file relies on baseUrl for bare-specifier resolution either (there are no from 'libs/…'-style imports anywhere in the repo).

What breaks is Nx. @nx/angular:package and @nx/js:tsc call createTmpTsConfig, which writes a generated tsconfig to tmp/<projectRoot>/build/ that re-declares the whole paths map with dependency entries remapped to their dist outputs:

"@threadplane/telemetry/browser": [
  "dist/libs/telemetry/browser",
  "./dist/libs/telemetry/src/browser/public-api",
  "./dist/libs/telemetry/src/browser/public-api.ts"
]

The first entry comes from dep.outputs and is workspace-root-relative, i.e. non-relative. With no baseUrl anywhere in the chain, TypeScript raises TS5090 and discards the entire paths map, and the generated config's directory is the wrong base for the remaining entries regardless. Every library with a workspace library dependency then fails:

error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set.
libs/render/src/lib/render-element.component.ts:24:73 - error TS2307:
  Cannot find module '@threadplane/telemetry/browser'
libs/cockpit-shell/src/lib/workspace-presentation.ts:9:8 - error TS2307:
  Cannot find module '@threadplane/cockpit-registry'

render:build:production (ng-packagr) and cockpit-shell:build (@nx/js:tsc) both fail this way; chat, ag-ui and langgraph builds are then skipped as dependents. createTmpTsConfig does take a useWorkspaceAsBaseUrl flag that would fix it, but the executors call it with the default false and it is not reachable from project.json. Prefixing the base paths values with ./ does not help — Nx's own injected dist/… entry is still non-relative.

So this needs an Nx-side fix (or migrating to the Nx TS-solution setup, which drops paths for project references) before baseUrl can go. The comment in tsconfig.base.json records that so the next attempt starts there.

Other baseUrl declarations, and why they are left alone

  • libs/{cockpit-runtime-bridge,growth,example-layouts,cockpit-registry}/tsconfig.json set "baseUrl": "." (the library directory). Because baseUrl outranks pathsBasePath, these already redirect the inherited base paths into the library folder — @threadplane/design-tokens in example-layouts tries libs/example-layouts/libs/design-tokens/src/index.ts, misses, and only resolves because the npm workspace symlink under node_modules happens to point at the same source. That is a pre-existing latent bug, unchanged by this PR, and removing those lines changes resolution for those builds — worth its own change rather than riding along here.
  • libs/growth-capture, apps/growth-research pair "baseUrl": "." with "paths": {}, so baseUrl is doing real directory-resolution work for those NodeNext projects. Not redundant.
  • apps/website declares its own complete paths (including the Next.js @/* convention) alongside baseUrl. Self-contained and a separate decision.
  • The cockpit/**/{python,angular/e2e} and examples/**/e2e configs either declare baseUrl plus their own paths together, or do not extend tsconfig.base.json at all. Unaffected by this change.

Verification

  • npx nx run-many -t lint,test,build --projects=chat,ag-ui,langgraph,render,a2ui,telemetry,middleware,cockpit-registry,cockpit-shell,scripts --skip-nx-cache — green (0 lint errors; warnings only)
  • chat:type-tests, ag-ui:type-tests, langgraph:type-tests — all green on TypeScript 5.9.3 with no ignoreDeprecations
  • Mutation-checked the pinned compiler: appending const x: number = "s" to libs/ag-ui/src/lib/provide-agent.type-spec.ts fails the target with TS2322, so it is not passing vacuously
  • npx vitest run --root apps/website --reporter=dot — 138 files, 1394 tests passed
  • GROWTH_FORM_POLICY=growth_v1 npx nx build website — green
  • npx nx run-many -t build --projects=examples-chat-angular,cockpit-render-repeat-loops-angular,cockpit-chat-debug-angular — green
  • npx nx run e2e-harness:lint (the one other bare-tsc target) — green; its tsconfig is standalone and declares no baseUrl
  • npx tsc --noEmit -p tsconfig.base.json is not meaningful here: the file has no include/files, so it would sweep every .ts in the workspace. The equivalent editor-facing surfaces are covered by the website build (Next.js) and the library builds.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
threadplane Ready Ready Preview Sep 8, 2026 7:31pm UTC

Request Review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

blove and others added 2 commits September 8, 2026 12:27
The three `type-tests` targets invoked `npx tsc`, which does not resolve to
the workspace compiler. `@dawn-ai/core` pulls in `@typescript/old`
(npm:typescript@6.0.2), whose `tsc` bin wins the hoist at
`node_modules/.bin/tsc`, so those targets type-checked the public API with
TypeScript 6.0.2 while every other target compiles with the declared 5.9.3.
That mismatch is what produced the TS5101 `baseUrl` deprecation error, which
#1064 silenced with `ignoreDeprecations: "6.0"`.

Invoke `node ./node_modules/typescript/bin/tsc` so the targets use the
compiler the workspace declares, and drop the `ignoreDeprecations` holding
action. The `rootDir` lines stay: they solve the unrelated problem of
type-specs importing sibling libraries through path mappings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TypeScript 7 removes `baseUrl`, and since TypeScript 5.0 the `paths` map no
longer needs it. Removing it from `tsconfig.base.json` nonetheless breaks
every library that depends on another library: Nx's buildable-library
executors write a generated tsconfig under `tmp/<projectRoot>/build/` whose
`paths` re-declare dependency entries as workspace-root-relative dist
outputs (`dist/libs/telemetry/browser`). Without a `baseUrl` those
non-relative values raise TS5090 and TypeScript discards the whole `paths`
map, so `render:build` and `cockpit-shell:build` fail to resolve
`@threadplane/telemetry/browser` and `@threadplane/cockpit-registry`.

Leave the option in place and record the blocker next to it so the next
attempt starts from the Nx side rather than re-deriving this.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@blove
blove force-pushed the blove/drop-tsconfig-baseurl branch from a1b71c5 to 1b092e6 Compare September 8, 2026 19:27
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@blove
blove merged commit 577b559 into main Sep 8, 2026
77 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant