Review found the CLI entry guard compared import.meta.url against a concatenated file:// URL. That fails whenever import.meta.url encodes something process.argv[1] does not — a repository path containing a space, or any Windows drive path — and it fails silently: the script exits 0 having done nothing, so verify-tsconfig-paths would pass without checking exactly where it is needed. Running a copy from a directory whose name contains a space reproduces it. The guard now uses the comparison the repository's seven other generators already use. Deleting the group wildcards also removed the fallback that resolved a package nobody had aliased, so the generator now asserts coverage: every workspace package with a src directory must be mapped, and --check names any that is not. That assertion immediately found four packages named dsh-<group>-<directory> whose siblings carry hand-written aliases while they did not, so they reached built lib/ output through the workspace symlink. They now carry aliases too, which takes the resolution differences in this branch from seven to eleven. Two comments in tsconfig.base.json still pointed at the deleted wildcards; they now state why those aliases stay hand-written. The package-inventory proposal recorded the wildcard collapse as current, so both notes are cross-linked as partial supersession.
3.4 KiB
Agent Note: Discover package inventories instead of maintaining static lists
Status: proposed
English | 中文
Problem
Package and gate inventories are repeated across TypeScript project references, package docs, CI prose, and Knip overrides. Most restate package layout, manifest data, or aggregate command contents. Each new package therefore creates avoidable synchronization points.
The package hierarchy already removed several of these by hand: scripts/publint-all.ts now derives its list from the packages/<group>/<pkg> layout, and the two tsconfig paths maps collapsed to one @deepseek-ai/dsh-* wildcard — since reverted to one explicit alias per package, generated and gated, because resolving a wildcard's candidates in order dominated source-launch boot (explicit workspace path aliases). What remains is the inventory that cannot be globbed away — chiefly the aggregate configs' (tsconfig.host.json, tsconfig.client.json) project references, which TypeScript requires as explicit arrays (no wildcard form).
Static lists are appropriate when they encode policy; they are needless friction when they duplicate manifest data or layout facts that already exist in package.json, workspace globs, or the package hierarchy.
Proposal
Make the remaining package/gate inventories discoverable. A single canonical source — the packages/<group>/<pkg> hierarchy plus package manifests — should drive the aggregates' references, the module graph, and any other full-package list, with a generate-and-verify step (the existing gen-module-graph / gen-cordis-catalog pattern: a generator writes the artifact, a --check mode in hygiene/doc-sync fails on a stale committed copy). Module graph generation already reads package manifests. doc-sync should be the one command that defines and prints its sub-gates, with docs linking to that command rather than restating a second list.
The hierarchy does not need to encode every fact about a package, but it should encode the broad maintenance policy: core/product packages, integrations, capability seams, and support/test/example packages should not all require a hand-maintained exception list before scripts can tell them apart.
One cataloged item needs no generator at all: folding the e2e entry glob into knip's default stanza deletes the per-package restatements outright.
Acceptance criteria
- Aggregate-config project
referencesare generated from the hierarchy (a generator emits them; a--checkgate fails when the committed copy is stale), rather than hand-maintained. - Adding a package does not require editing a static package list for any gate.
- Docs describe the source of truth rather than repeating generated inventories.
- CI invokes the aggregate commands and lets those commands own their sub-gate lists.
knip.jsoncarries a per-package override only where it encodes real information (an extra entry file, an ignored dependency), never a restatement of the default stanza.
Risks
Discovery scripts can become too clever. The implementation should stay boring: read manifests, filter on explicit fields, print the resolved list, and fail loud. The payoff is removing manual inventory drift, not inventing a build system.