Merge branch 'v2/main' into v2/chore/2154-use-connection-lifecycle

This commit is contained in:
Cliff Hall 2026-08-27 10:24:40 -04:00 • committed by GitHub
commit 6bd2841afc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 1279 additions and 53 deletions

View file

@ -371,7 +371,7 @@ The CLI's `test` / `test:coverage` **build the binary first** (out-of-process
`e2e.test.ts` spawns it). `validate` is `format:check && lint && typecheck && test`
with no separate `build` step (`pretest` builds). Repo-root `validate:cli`
delegates here; the coverage gate is `npm run coverage` / `coverage:cli` (also in
`npm run ci`), matching AGENTS.md.
`npm run local:gate`), matching AGENTS.md.
Tests run the CLI **in-process** (importing `runCli()`) so `src/` is measured
under coverage, with a thin out-of-process spawn layer for the real binary. See

View file

@ -76,7 +76,7 @@ const preview: Preview = {
},
},
a11y: {
// `'error'` fails the Storybook play-function tests (part of `npm run ci`)
// `'error'` fails the Storybook play-function tests (part of `npm run local:gate`)
// on any axe violation, so the zero-violation state this PR reached is
// enforced going forward rather than being a point-in-time result.
test: "error",

View file

@ -2,7 +2,7 @@
The browser incarnation of the Inspector: a **Vite + React + [Mantine](https://mantine.dev)** single-page app backed by a small **Node (Hono)** server. The SPA is presentational — it renders data and fires callbacks; all MCP state comes from the shared `@inspector/core` hooks. The backend proxies MCP connections, serves the built SPA, and exposes `/api/*`.
This README covers what's specific to the web client. For the repo-wide picture (the `@inspector/core` shared package, the "dumb components" philosophy, the top-level `validate`/`coverage`/`ci` scripts, and publishing), see the [root README](../../README.md).
This README covers what's specific to the web client. For the repo-wide picture (the `@inspector/core` shared package, the "dumb components" philosophy, the top-level `validate`/`coverage`/`local:gate` scripts, and publishing), see the [root README](../../README.md).
## Two halves: `src/` (browser) and `server/` (Node)
@ -319,7 +319,7 @@ npm run build:storybook # static build
npm run test:storybook # run every story's play function in headless Chromium
```
Storybook is first-class here because the components are presentational — each renders against fixture props. **Play functions double as interaction tests** and run headless in real Chromium via `@vitest/browser-playwright` + `@storybook/addon-vitest` (the `storybook` Vitest project). They're part of `npm run ci` (which installs the Chromium binary first) but kept out of the fast `validate` loop since they need the browser.
Storybook is first-class here because the components are presentational — each renders against fixture props. **Play functions double as interaction tests** and run headless in real Chromium via `@vitest/browser-playwright` + `@storybook/addon-vitest` (the `storybook` Vitest project). GitHub CI runs them directly (`npm run test:storybook`); the local pre-push gate runs them through `npm run local:storybook`, which installs the Chromium binary first. Either way they are kept out of the fast `validate` loop, since they need the browser.
## Auth token

View file

@ -552,7 +552,7 @@ describe("AppRenderer", () => {
// pending here. Observed failing exactly once that way, with 0 calls.
//
// The default 1000ms then turned out not to be enough either — it failed
// twice in a row in `npm run ci` (at ~1021ms, still 0 calls) while
// twice in a row in `npm run local:gate` (at ~1021ms, still 0 calls) while
// passing every time this file runs alone, which is the signature of a
// budget that is too tight rather than of a broken observer. Raised
// rather than retried: a `waitFor` that is generous costs nothing on the

View file

@ -108,7 +108,7 @@ async function getTool(client: InspectorClient, name: string): Promise<Tool> {
* legitimate thing to exercise, but `disconnect()` closes the SDK client, which
* rejects every pending request with "Connection closed" — and a floating
* promise makes that an *unhandled* rejection, which vitest counts as a run
* error and fails `npm run ci` even though every test passes (#1947).
* error and fails `npm run local:gate` even though every test passes (#1947).
*
* Attach the handler at call time (not after the assertions) so there is no
* window in which the rejection can escape, then finish through