refactor(tsconfig): single root solution graph over host/client aggregates

Root tsconfig.json becomes a pure solution (files:[] + two references);
the former root host aggregate moves verbatim to tsconfig.host.json.
New tsconfig.base.client.json carries the shared client compiler shape
(jsx/DOM lib/types:[]), and tsconfig.client.json plus the 12
packages/client tsconfigs extend it instead of restating the trio.
tsconfig.build.json is deleted: the solution covers the full emit graph,
absorbing the command-goal typecheck/build drift.

Consumers migrate to the single graph: typecheck/build scripts and the
lefthook pre-push hook run bare `tsc -b` (pre-push now covers the client
side); the run-gates build gate needs typecheck so two concurrent tsc -b
runs cannot race the same tsbuildinfo; ts-project.ts and the standalone
doc-typecheck mode seed tsconfig.host.json explicitly (never the root
solution — flattening host+client into one program collides the cordis
Context merges); verify-cordis-config BFS seeds the root solution alone.

Per missions/tsconfig-single-graph-migration.md §2–§3.
This commit is contained in:
imccyu
2026-07-22 23:58:37 +08:00
parent 9cf5a384e9
commit 19e6f7d907
24 changed files with 111 additions and 286 deletions
+6 -5
View File
@@ -152,12 +152,13 @@ function localPackageDirectories(): Map<string, string> {
}
function rootProjectReferences(): Set<string> {
// Typecheck runs two sibling aggregates (root = host program,
// tsconfig.client.json = client program; the two sides merge cordis Context
// under the same keys, so one program cannot see both). Seed both and follow
// any nested aggregate references to collect the covered leaf project set.
// The root solution references the host and client aggregates (the two
// sides merge cordis Context under the same keys, so one program cannot see
// both — but this BFS only collects reference paths, it never forms a
// program). Seed the solution and follow nested aggregate references to
// collect the covered leaf project set.
const collected = new Set<string>()
const queue = [resolve(root, 'tsconfig.json'), resolve(root, 'tsconfig.client.json')]
const queue = [resolve(root, 'tsconfig.json')]
const seen = new Set<string>()
for (let file = queue.pop(); file !== undefined; file = queue.pop()) {
if (seen.has(file)) continue