Commit graph inspector/specification/v2_cli_tui_launcher.md
Author SHA1 Message Date
cliffhall
32a3610737 Merge remote-tracking branch 'origin/v2/main' into 1579-wave-1
# Conflicts:
#	clients/cli/package-lock.json
#	clients/cli/package.json
#	clients/web/src/App.tsx
#	clients/web/src/lib/environmentFactory.test.ts
#	clients/web/src/lib/environmentFactory.ts
#	clients/web/src/lib/remoteOAuthStorage.test.ts
#	clients/web/src/lib/remoteOAuthStorage.ts
#	clients/web/src/test/core/auth/connection-state.test.ts
#	clients/web/src/test/core/auth/providers.test.ts
#	clients/web/src/test/core/auth/storage-browser.test.ts
#	clients/web/src/test/core/auth/storage-remote.test.ts
#	clients/web/src/test/core/mcp/oauthManager.test.ts
#	clients/web/src/test/integration/auth/node/storage.test.ts
#	clients/web/src/test/integration/storage/adapters.test.ts
#	clients/web/src/utils/clearServerOAuthState.test.ts
#	clients/web/src/utils/clearServerOAuthState.ts
#	core/auth/connection-state.ts
#	core/auth/oauth-storage.ts
#	core/auth/providers.ts
#	core/auth/storage.ts
#	core/auth/store.ts
#	core/storage/adapters/remote-storage.ts
2026-07-09 09:41:08 -04:00
Bob Dickinson
3c65bdb4c6 Removed Zustand storage, cleanup up auth storage IO interfaces, implementations, and usage. 2026-07-04 21:56:45 -07:00
cliffhall
cfbdfdf2bd Merge remote-tracking branch 'origin/v2/main' into 1579-wave-1
# Conflicts:
#	AGENTS.md
#	clients/cli/README.md
#	clients/web/src/App.test.tsx
#	clients/web/src/App.tsx
#	clients/web/src/test/core/auth/utils.test.ts
#	core/mcp/node/transport.ts
#	test-servers/src/composable-test-server.ts
2026-07-03 17:39:07 -04:00
cliffhall
d68202a88b docs(spec): add V2 Auth landing page and canonicalize spec top menus (closes #1605)
Add a specification/v2_auth.md landing page summarizing the four auth specs
(EMA / XAA, Hardening, Mid-session, Smoke testing) with a section submenu,
mirroring the V2 UX index pattern.

Add a V2 Auth link (after V2 UX) and a V2 New Spec Impact link to every spec
page's top menu so the top-level nav is uniform, and restructure the four
v2_auth_*.md pages onto the shared two-tier menu (top menu + auth submenu).

Docs only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-02 17:20:06 -04:00
cliffhall
b152f74ccd fix(ci): run CI on Node 22.x and correct undici 8 Node floor (#1563)
undici 8.5.0 requires Node >= 22.19.0 (its declared engines), so CI's
Node 20.x could not load undici's CacheStorage (missing
webidl.util.markAsUncloneable) and the proxy integration tests failed.
Bump the CI setup-node to 22.x to match the repo's Node floor.

Reconcile the declared floor with undici's real requirement: bump root
engines.node to >=22.19.0 and correct the CLI README note (undici 8.5.0
needs >=22.19.0, not >=22.7.5). Also document proxy support in the web
README and clarify that a caller-supplied eventSourceInit.fetch bypasses
the proxy wrapper by design.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-01 19:17:05 -04:00
Cliff Hall
5efe9ddc7b
refactor: self-validating clients, fast validate + separate coverage/smoke (#1504) (#1505)
* refactor(launcher): self-contained validate; split smokes into top-level step (#1504)

Previously `validate:launcher` built cli/tui/web and ran the cross-client
smokes, so the launcher's "validation" depended on every other client
being built — and the launcher had no lint/format/coverage of its own.

- clients/launcher: add a web-style `validate` (format:check && lint &&
  build && test:coverage) with a Node-only eslint flat config, prettier,
  and a per-file coverage gate (parse-launcher-argv.ts covered;
  src/index.ts excluded as binary bootstrap). 100% on the gated file.
- Root `validate:launcher` now just delegates: `cd clients/launcher &&
  npm run validate` — no dependency on the other clients.
- New top-level `smoke` step (smoke:launcher + smoke:cli + smoke:tui +
  smoke:web) with NO build commands; `validate` runs it last. Each
  client's own validation builds its bundle first, so nothing builds
  twice (cli/tui via test:coverage, launcher via its validate;
  smoke:web builds dist on demand).
- clients/tui test:coverage now builds the TUI bundle (mirroring cli) so
  the build-free smoke has it available.
- CI: replace the standalone cli/tui/launcher build step with a
  "Validate launcher" step. Docs updated (AGENTS.md, launcher README).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(cli,tui,root): every client self-validates; smoke separate from validate

Extends the launcher self-validate work to the CLI and TUI, and makes the
top-level `validate` nothing but the per-client validations — smokes are
now a separate top-level target.

- clients/cli, clients/tui: add a web-style `validate` with a Node flat
  eslint config + prettier. CLI lint/format pass as-is. TUI registers
  eslint-plugin-react-hooks for the classic rules only (rules-of-hooks +
  exhaustive-deps, which the source already references); the stricter
  react-hooks@7 rules are not enforced on the interim component surface
  (#1501).
- Avoid double builds:
  - CLI's e2e spawns the built binary, so its `test:coverage` builds first;
    `validate` folds that in (`format:check && lint && test:coverage`, no
    separate `build`).
  - TUI tests don't spawn a bundle, so `validate` keeps an explicit
    `build` (for the smoke) and `test:coverage` is pure.
- Root: `validate` = validate:web && validate:cli && validate:tui &&
  validate:launcher (each delegates to the client's own validate). `smoke`
  is no longer part of `validate` — it's a separate top-level target run
  after a build/validate, with no build commands of its own.
- CI: per-client "Validate X" steps + a single "Run cross-client smokes"
  (npm run smoke). Docs updated (AGENTS.md, cli/tui READMEs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(root): drop redundant test aggregator scripts

Now that every client self-validates and the top-level `validate` chains
the per-client validations, the root `test` / `test:web` / `test:cli` /
`test:tui` / `test:coverage` aggregators are redundant — run
`npm run validate` (all) or `cd clients/<name> && npm run validate` (one).
`test:storybook` stays (it's the one check not part of validate). CI was
already using each client's own scripts, so it's unaffected. Docs updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(web): silence happy-dom infra noise in unit runs

Passing unit runs printed dozens of alarming-but-expected lines that made
green runs look broken — all from happy-dom performing real I/O with no
server behind it:
- `<iframe src="/sandbox.html">` (MCP Apps sandbox) made happy-dom fetch
  and later unload that URL, emitting ~40 `DOMException [NetworkError/
  AbortError]` + `AsyncTaskManager destroyed` lines. Disable child-frame
  navigation in the unit project (the tests only assert on the iframe
  element/attributes, not its document), removing the noise with no
  coverage loss.
- App-level renders read `GET /api/config` via useSandboxUrl /
  useServerListWritable, 404-ing ~76x. Add a benign default `fetch` (empty
  200) in the unit setup; tests that exercise fetch still override it.

Negative tests that assert on errors already suppress their own console
output (e.g. jsonUtils/schemaUtils); CLI, TUI, and the web integration
suite were already clean. Unit suite is now noise-free; 2424 web tests
pass and the coverage gate is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(scripts): make validate fast (test), split coverage into its own target

Each client's `validate` now runs `test` instead of `test:coverage`, so
the everyday pre-push check skips v8 instrumentation (and, for web, the
slower integration project). The per-file coverage gate moves to a
dedicated top-level `coverage` script:

  coverage = coverage:web && coverage:cli && coverage:tui && coverage:launcher
  coverage:<name> = cd clients/<name> && npm run test:coverage

`validate` still builds each client's bundle (cli via its test `pretest`,
the others via an explicit `build`), so `npm run validate && npm run
smoke` works unchanged. CI now runs `validate` (fast checks + builds),
then `coverage` (the gate), then `smoke` — collapsing the old per-client
steps. Docs updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci: drop the coverage gate from CI; keep web integration as its own step

CI no longer runs `npm run coverage` — the per-file coverage gate is now a
local/manual check (`npm run coverage` before pushing). To avoid silently
dropping the web integration suite (it only ran via test:coverage, and
`validate` runs the unit project only), CI gains a standalone
`clients/web` `test:integration` step that exercises the real
stdio/HTTP/OAuth/storage paths without coverage instrumentation.

CI is now: validate (fast) → web integration → smoke → storybook. Docs
updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(smoke): give smoke:launcher its own script like the others

smoke:launcher was the odd one out — an inline chain of three
`node clients/launcher/build/index.js ... --help` commands while smoke:cli
/ smoke:tui / smoke:web each run a `scripts/smoke-*.mjs`. Extract it to
`scripts/smoke-launcher.mjs`, which runs the same `--help` / `--cli --help`
/ `--tui --help` dispatch checks but now also asserts each prints that
mode's usage banner (proving the launcher resolved the right client build)
and verifies the required builds exist up front with a clear error. Prints
a `smoke:launcher OK — ...` summary in the same style as the rest. Docs
updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: reorder package.json scripts for readability

Move frequently-run scripts toward the top and rarely-run-by-hand ones
(pretest hooks, lint/format internals, etc.) toward the end, consistently
across the root and client manifests. Pure reordering — no script names or
values changed, and no other manifest content is touched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: drop references to removed root inspector / test:storybook scripts

The reordering dropped the root `inspector` and `test:storybook`
aggregators (intentional — `inspector` is redundant with `web`, and
storybook is run from clients/web in CI). Update AGENTS.md so it no longer
points at `npm run inspector`, and run `test:storybook` from `clients/web/`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: address PR #1505 review (format glob gap, fetch-baseline comment)

- TUI format/format:check now also cover the client-root source files
  (index.ts, tui.tsx, dev.ts) that live outside src/ — `eslint .` already
  lints them, so they were linted but not format-checked. (cli/launcher
  have no source outside src/; their root .ts are single-quoted configs
  intentionally left out of prettier, matching web.)
- Reword the setup.ts default-fetch comment: it overstated auto-restore
  (the unit project sets no restoreMocks/unstubGlobals), and now also
  flags that the permissive 200 default means a test asserting on a fetch
  FAILURE must install its own rejecting stub.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: remove redundant root install:clients script

`install:clients` ran the same `node scripts/install-clients.mjs` as
`postinstall`, which fires automatically on `npm install` — so the manual
alias was redundant. Drop it and the doc references (AGENTS.md, spec).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ci): skip smoke:tui in CI (Ink needs a real TTY)

This PR made CI run the full `npm run smoke`, which surfaced that
smoke:tui fails in headless CI: the Ink TUI throws "Raw mode is not
supported" on mount (no TTY) and exits before rendering its first frame.
The old CI never ran smoke:tui, so this was latent.

smoke-tui.mjs now self-skips when `process.env.CI` is set — the boot/
render check is inherently local-only (a TUI needs a terminal). The TUI is
still built and unit-tested in CI; `npm run smoke` stays the single
command everywhere (full locally, tui-skipped in CI). Verified
`CI=true npm run smoke` is green (launcher/cli OK, tui SKIPPED, web OK).
Docs + CI comment updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 11:41:33 -04:00
Cliff Hall
e72d4307f3
feat(cli): lift config-file headers/timeouts/OAuth into serverSettings (#1482) (#1500)
* feat(cli): lift config-file headers/timeouts/OAuth into serverSettings (#1482)

The CLI resolved file-sourced servers via resolveServerConfigs(), which
returns bare MCPServerConfig and dropped disk-level headers, timeouts, and
OAuth — CLI connections from a --catalog/--config file silently ignored
them. The TUI already lifted these via mcpConfigToServerEntries().

Extract the TUI's catalog/config -> per-server-settings resolution into a
shared core module (core/mcp/node/servers.ts: loadServerEntries +
selectServerEntry) and route both CLI and TUI through it, so the two share
one file->settings path. --header still overrides the file's headers for
the run while preserving the file's timeouts/OAuth.

- core: add loadServerEntries/selectServerEntry/headersToServerSettings
- tui: tui-servers.ts re-exports the shared core helpers (no logic dup)
- cli: resolve via loadServerEntries + selectServerEntry; drop the
  CLI-only conflict check and bare-config path
- tests: core servers.test.ts (settings lifting, header merge/override,
  stdio overrides, seed/error/conflict, selection); CLI integration tests
  asserting a config header is sent over HTTP and --header overrides it
- docs: CLI README note on file settings being applied

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(core): address #1500 review — dedup overrides, drop dead wrapper, clearer error, spec refresh

- Remove the now-unused resolveLaunchServerConfigs() wrapper (both CLI and
  TUI route through loadServerEntries now); migrate its default-catalog
  launch tests to compose withDefaultCatalogPath + resolveServerConfigs.
- Deduplicate applyStdioOverrides against config.ts applyOverrides: export
  the latter (now trims cwd) and reuse it in servers.ts.
- selectServerEntry's unknown-name error is source-agnostic ("not found"
  not "not found in config file") since entries may be a single ad-hoc
  default, where "config file" would mislead.
- Refresh specification/ docs (v2_cli_tui_launcher.md,
  v2_catalog_launch_config.md): CLI/TUI resolution now via
  loadServerEntries/selectServerEntry; mark gap G1 resolved (#1482);
  withDefaultConfigPath → withDefaultCatalogPath.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(cli): extend smoke:cli to cover #1482 lift→serverSettings

Adds end-to-end smoke coverage for the config-file headers/timeouts/OAuth
lift introduced in #1482:

- unknown --server now errors source-agnostically ("not found")
- multi-server catalog selection via --server (and the omit-it error)
- --header merge does not break the stdio connect path
- HTTP transport: a config-file `headers` object is lifted onto the wire,
  and a CLI --header overrides it (verified against an in-process test
  server's recorded requests via a non-blocking spawn)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 11:33:21 -04:00
Bob Dickinson
2488ca5e38
feat: port CLI, TUI, and launcher from v1.5 into v2 (#1452)
Ports the CLI, TUI, and launcher from v1.5 into v2 behind a single
`mcp-inspector` entrypoint (launcher → web/cli/tui). Includes the
`mcp-inspector --web --dev` launcher fix (Vite alias resolution + prod-server
double-start), the root `postinstall` install cascade with simplified CI, and
spec/AGENTS docs (no-workspaces rationale, Development setup).

Closes #1246.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 20:27:49 -04:00
Bob Dickinson
62d442b073 Revert "First pass at pulling the v1.5 CLI, TUI, and Launcher clients into v2."
This reverts commit 467b01edd6.
2026-06-09 21:56:38 -07:00
Bob Dickinson
467b01edd6 First pass at pulling the v1.5 CLI, TUI, and Launcher clients into v2. 2026-06-09 17:38:00 -07:00