chore: address Copilot review on #2200

- Complete the bundler external lists against the AGENTS.md invariant rather
  than against today's reachability: chokidar, hono and react to clients/cli,
  chokidar and hono to clients/tui, react to the web runner. Every root-declared
  package core/ imports at runtime is now named in all three, so a new import in
  core/ cannot silently inline one.
- AGENTS.md: split the single over-broad bullet in two. commander, open,
  @hono/node-server, vite and @vitejs/plugin-react are root dependencies reached
  only from client code, so they are not part of the core/ set and need naming
  only in the external list of the client that imports them. Give the
  vitest.shared.mts pins their own rule, stating the react/react-dom exception
  instead of implying every root-owned package is aliased to the root.
- vitest.shared.mts: the umbrella comment now says root-OWNED rather than root
  runtime dependency — express is test-only and lives in the root
  devDependencies — and notes that the list is deliberately not the complete
  root set, since a package that resolves unambiguously needs no pin.
- local-dev skill: document why react/react-dom stay client-pinned, which the
  previous text contradicted.

npm run local:gate and npm run verify:bundle-externals pass.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-31 19:58:22 -04:00
commit f62cfbaeeb

View file

@ -122,7 +122,17 @@ Two consequences that read as bugs and are not:
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.
longer exists, or (for the transitive cases above) at the duplicate the pin was
supposed to rule out.
**`react` and `react-dom` are the exception, and stay pinned per client.** They
are a matched pair — `react-dom` reaches into React internals — and `react-dom`
is still web-declared, so npm resolves it and its React peer together inside
`clients/web/node_modules` (19.2.8 today, against the root's 19.2.7). Pointing
`react` at the root while `react-dom` resolves from the client would pair a
renderer with a React it was not installed against, which is the same split the
pin exists to prevent, arrived at from the other side. `dedupe` still collapses
each install to one copy, which is what actually has to hold.
### Why runtime consumption decides `dependencies`