web: deep-link auto-connect (?serverUrl&transport&autoConnect) + connection-status (#1576)#1670
web: deep-link auto-connect (?serverUrl&transport&autoConnect) + connection-status (#1576)#1670cliffhall wants to merge 2 commits into
Conversation
Closes #1576 Adds `?serverUrl=<url>&transport=http|sse&autoConnect=<token>` URL-driven auto-connect so a driver can reach a connected inspector with one navigate. - `clients/web/src/utils/deepLink.ts`: `parseDeepLink()` (http(s)-only serverUrl; `autoConnect` CSRF-gated on the per-launch API token), `deepLinkParseStatus()`, `deepLinkConfigEquals()`, `DEEP_LINK_SERVER_ID` (stable `deep-link` row so reloads reconnect to the same catalog row). - App.tsx: ensure/connect effects (two-phase upsert-then-connect against the hydrated list), `serversRef` read in `onToggleConnection`, `connectErrorMessage` / `recordConnectError` recording connection-level failures. - InspectorView header: `data-testid="connection-status"` with `data-status`, `data-error-message`, `data-deeplink` so drivers can `waitForSelector` and read failure reasons without scraping toasts. - Docs: deep-link scheme + `data-*` contract in clients/web/README.md. Re-implemented informed by PR #1510 (33fac3f); adapted to the post-#1417 lifted-tab architecture and dropping the non-existent `normalizeServerUrl` import in favor of `URL.href` canonicalization. Coverage gate green (deepLink.ts 97.8/95.1/100/97.4). Part of the #1579 decomposition (Wave 4). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrihGWcrM9JGRyu41nzZYw
|
@claude review |
|
Claude finished @cliffhall's task in 2m 21s —— View job Code Review — deep-link auto-connect + connection-status
Reviewed against 👍 Strengths
🔍 Observations1. void addServer(deepLink.serverId, deepLink.serverConfig).catch(() => {
// 409 = already on disk; hydration will surface it on a later render.
});The comment assumes the only failure is a 409, but this 2. Possible stale-config connect in the if (!deepLinkConfigEquals(existing.config, deepLink.serverConfig)) {
await updateServer(deepLink.serverId, deepLink.serverId, deepLink.serverConfig);
}
if (activeServerId !== deepLink.serverId) {
await onToggleConnection(deepLink.serverId);
}
3.
4. No test exercises the App.tsx two-phase effect. The PR notes App.tsx is outside the coverage Nits
None of these are blocking. #1 is the one I'd most encourage addressing, since it's a silent-failure hole in the exact automation contract this PR is establishing. |
…tale-config connect - The ensure-phase addServer catch now records non-409 failures (read-only catalog, backend 5xx) on data-error-message instead of swallowing every error and leaving the deep link permanently stuck at the guard with no signal (review finding #1). - Split the update and connect phases across renders (new deepLinkUpdateRef): connect only once servers reflects the updated config, so onToggleConnection (which reads serversRef, synced by an earlier passive effect) builds the client from the fresh transport rather than the pre-update config (finding #2 — the exact case deepLinkConfigEquals was added for). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrihGWcrM9JGRyu41nzZYw
|
Thanks for the review — addressed the two substantive findings in
#3 (lone @claude review |
|
Claude finished @cliffhall's task in 1m 31s —— View job Re-review — fixes in
|
|
Superseded by the Wave 4 rollup #1676, which contains this change (reviewed to LGTM here) merged base→tip. Closing in favor of the rollup. |
Closes #1576
Summary
URL-driven auto-connect with a machine-readable status surface, so a driver reaches a connected inspector with one navigate:
clients/web/src/utils/deepLink.ts—parseDeepLink()/deepLinkParseStatus()/deepLinkConfigEquals()/DEEP_LINK_SERVER_ID.serverUrlrestricted tohttp(s)(rejectsjavascript:/data:/file:);autoConnectmust equal the per-launchMCP_INSPECTOR_API_TOKEN(CSRF gate — same exposure as the existing?MCP_INSPECTOR_API_TOKEN=param); stabledeep-linkserver id so reloads reconnect to the same row.serversRefread inonToggleConnection;connectErrorMessagerecords connection-level failures.data-testid="connection-status"withdata-status,data-error-message, anddata-deeplink="parsed|rejected|none"so drivers canwaitForSelectorand read failure reasons without scraping toasts.data-*contract inclients/web/README.md.Notes
Re-implemented informed by PR #1510 (
33fac3f), adapted to the current codebase:App.tsx(Persist per-screen selection and search/filter across tab navigation; clear only on user action or disconnect #1417) andserversRef/onResourceErroralready exist post-Wave-2, so the wiring differs from the reference.normalizeServerUrlhelper that does not exist here;validateServerUrlusesURL.hrefinstead, which canonicalizes host case + trailing slash the same way.The
openApp/appArgs/autoOpenconsumption is the follow-up #1577 (the parser already parses those params; this PR wires only auto-connect + status).Coverage gate green (
npm run test:coverage, EXIT 0;deepLink.ts97.8/95.1/100/97.4). App.tsx is outside the coverageincludeglobs.Part of the #1579 decomposition (Wave 4). Per AGENTS.md the
Closesline won't auto-fire onv2/main; the issue is closed and its board card moved on the Wave 4 rollup merge.🤖 Generated with Claude Code