chore: consolidate duplicated runtime dependencies into the root package.json
Every runtime dependency core/ imports is now declared once, in the repo-root package.json, and nowhere else. Deleting the client-side copies does not merely align them: a package installs only into an install root that declares it, so with no second declaration a second copy cannot be created at all — the failure class #1896 was opened for and #1965/#2029 built verify:dep-lockstep to detect. - clients/{web,cli,tui,launcher}: dropped ajv, atomically, chokidar, commander, open, pino, zod, @napi-rs/keyring, hono, @hono/node-server and react, as each applied. clients/cli and clients/launcher now declare no runtime dependencies. - Root hono floor raised ^4.12.18 -> ^4.13.1, keeping the higher of the two ranges that were in the tree rather than silently lowering web's. - tsup external lists: added ajv and zod to all three bundles, plus atomically and open (cli) and atomically (tui). tsup externalizes only what the nearest manifest declares, so a package that moves to the root is inlined unless it is named explicitly. - vitest.shared.mts: repointed the pino, hono, @hono/node-server, atomically, chokidar and @napi-rs/keyring pins from <client>/node_modules to the repo root, joining express, yaml and proper-lockfile. Left behind they would resolve to a directory that no longer exists, or to a transitive copy an unrelated dependency dragged in. react and react-dom stay client-pinned so the pair stays version-matched within an install. - Docs: AGENTS.md dependency placement, the root README and the local-dev skill describe the consolidated layout. verify:dep-lockstep candidate set: 4 -> 2 (hono and pino fell out; only @standard-schema/spec and zod still reach one tsc program from two installs). npm run local:gate and npm run pack:verify both pass. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
463593b265
commit
1f5c32940d
1 changed files with 128 additions and 1760 deletions
|
|
@ -89,7 +89,7 @@ to tell you have hit one.
|
|||
Work the rules in order: which manifest declares it, then `dependencies` vs
|
||||
`devDependencies`, then whether the bundlers must also externalise it.
|
||||
|
||||
### Why the SDK packages are root-only
|
||||
### Why `core/`'s runtime dependencies are root-only
|
||||
|
||||
A per-client declaration installs a **second copy** that drifts from the root's.
|
||||
Not theoretical: it put two versions of `ext-apps` (1.7.4 / 1.7.5) and of the
|
||||
|
|
@ -99,7 +99,30 @@ transitive v1 `@modelcontextprotocol/sdk` (1.29.0 / 1.30.0) in the tree at once
|
|||
|
||||
The same reasoning extends to anything reached only through root-owned code that
|
||||
has no manifest of its own (`test-servers/src`, `core/`) — hence the repo-root
|
||||
alias for those in `vitest.shared.mts`. `express` and `yaml` are the two today.
|
||||
alias for those in `vitest.shared.mts`. That used to be `express` and `yaml`
|
||||
alone; #2195 made it the general case, moving `ajv`, `atomically`, `chokidar`,
|
||||
`commander`, `hono`, `@hono/node-server`, `@napi-rs/keyring`, `open`, `pino`,
|
||||
`react`, `undici` and `zod` to the root as well.
|
||||
|
||||
The point of deleting the client-side copies rather than merely keeping them in
|
||||
step is that **a package installs only into an install root that declares it**.
|
||||
Aligned duplicate declarations still drift the next time someone bumps one of
|
||||
them; no declaration at all cannot. `npm run verify:dep-lockstep` is the detector
|
||||
for the skew, and consolidation is what removes the opportunity.
|
||||
|
||||
Two consequences that read as bugs and are not:
|
||||
|
||||
- **`clients/cli` and `clients/launcher` declare no runtime dependencies.** Their
|
||||
manifests carry `devDependencies` only. Everything they import at runtime is
|
||||
root-declared and resolves by walking up from the client directory.
|
||||
- **A client's `node_modules` still contains some of these names.** They arrive
|
||||
transitively (`chokidar` under `vite`, `react` as a peer of `react-dom` and
|
||||
`ink`). That is why the `vitest.shared.mts` pins matter: an unpinned specifier
|
||||
would resolve the nearest copy, which is the transitive one, not the root's.
|
||||
|
||||
When a package moves to the root, its `vitest.shared.mts` pin has to move with
|
||||
it — a `path.resolve(dirname, …)` pin left behind points at a directory that no
|
||||
longer exists.
|
||||
|
||||
### Why runtime consumption decides `dependencies`
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue