fix(resolution): load path aliases through tsconfig extends and base configs (#1534) (#1548)

`loadProjectAliases()` read only the root `tsconfig.json` / `jsconfig.json`
own `compilerOptions`, so an Nx-style monorepo — every alias declared in a
`tsconfig.base.json` — got `null` back and every cross-package import fell
through to name-based matching. Silently: no unresolved-import warning, and
the results still look precise.

Two things were missing, and either one alone leaves a common Nx layout
broken:

Fold the `extends` chain into the effective options before building the
alias map. Relative and `node_modules` package specifiers both resolve,
the nearest config wins (tsc replaces `paths` rather than merging), and a
config already on the current chain is not re-entered, so `a extends b
extends a` terminates instead of recursing forever.

`paths` are anchored at `baseUrl` when one is declared — itself relative
to the config that declared it — and otherwise at the directory of the
config that declared the `paths`, which is what tsc does and what keeps
an inherited `src/*` from being read as root-relative.

Read `tsconfig.base.json` as a last candidate. A root `tsconfig.json` is
still authoritative when it exists and reaches the base through `extends`;
the fallback covers the layouts where that never happens — a solution-style
root config (`references`, no `extends`, no `paths`, which is what nx's own
repository ships) or no root `tsconfig.json` at all. A candidate that
contributes no aliases no longer shadows a later one that does.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Colby McHenry <me@colbymchenry.com>
This commit is contained in:
Max Hsu
2026-08-22 11:55:01 -05:00
committed by GitHub
co-authored by Claude Opus 5 Colby McHenry
parent 9219967e43
commit 474f051d3c
3 changed files with 323 additions and 17 deletions
+2
View File
@@ -21,6 +21,8 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Fixes
- Import aliases defined in a shared TypeScript config are now picked up. Nx-style monorepos keep every `@scope/...` alias in a `tsconfig.base.json` that the root `tsconfig.json` only inherits through `extends`, so CodeGraph found no aliases at all and every cross-package import fell back to matching on name alone — which quietly attaches results to unrelated symbols that happen to share a name, exactly where a monorepo needs `codegraph_impact` and `codegraph_callers` to be right. Chains several configs deep, a config inherited from a package in `node_modules`, and a `baseUrl` declared in an inherited config are all followed now, and a `tsconfig.base.json` is read directly when the root `tsconfig.json` is only a project-references shell or isn't there at all. Re-index after upgrading. (#1534)
- Looking a symbol up by name no longer reads the whole graph. Every search made one full pass over all indexed symbols for each word you typed, and a question that named several symbols made two more passes per name — including for a word that matches nothing, which is the common case. The cost therefore grew with the size of the project, and it was paid again on every message when the prompt hook is enabled. These lookups now go through the name index instead. Results are identical; only the time to get them changes, and it no longer grows with the project.
- Naming a file by its path in a `codegraph_explore` query now works reliably: the path is resolved against the index and that file is guaranteed a place at the top of the answer. Previously the path was broken into fragments — bracketed route segments like SvelteKit's `[id]` made this worst — and pieces like `page` or `runs` matched every sibling file, so the file you actually named could be crowded out of the answer entirely. A path that doesn't match any indexed file is now called out instead of silently ignored.