refactor(core): apply v1.5-port cleanups deferred from #1306#1316
Conversation
Addresses issue #1309 — five small, mechanical cleanups deferred from the v1.5 runtime port: 1. Collapse BrowserOAuthStorage / NodeOAuthStorage / RemoteOAuthStorage onto a shared OAuthStorageBase. Three ~130-line duplicates become thin adapter wrappers; behavior + public API unchanged. 2. Re-enable erasableSyntaxOnly in tsconfig.app.json by rewriting the seven (plus two the issue missed in sampling/elicitation create- message) parameter-property constructors as explicit field + assign. 3. Route the lone console.error in inspectorClient.ts through this.logger. 4. Replace `${Date.now()}-${Math.random()}` with crypto.randomUUID() at the five local-only ID sites (message tracking + sampling/elicit). 5. Pin the remote-server hono app generic at new Hono<Env>() and drop the streamSSE cast. Root cause of the cast was an unresolved hono subpath: the tsconfig "hono/*" wildcard didn't honor the exports map, so hono/streaming leaked to the root-hoisted hono@4.12.12 while hono itself resolved to clients/web/hono@4.12.18. Replaced the wildcard with an explicit hono/streaming entry in both tsconfig.app and tsconfig.test, removing the package-identity mismatch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@claude review |
|
Claude finished @cliffhall's task in 2m 57s —— View job Claude PR Review
SummaryClean, focused PR. Five independent mechanical cleanups, each easy to verify in isolation. The Approving in spirit (bot can't formally approve). A few small observations and nits below — none block merge. Observations1. 2. const taskId =
typeof crypto !== "undefined" && crypto.randomUUID
? crypto.randomUUID()
: `task-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;Either the guard is genuinely needed (in which case the new sites should match), or — more likely, given the project's runtime targets — the guard is dead code that should be dropped for consistency. A one-line cleanup PR later is fine; flagging so it doesn't get lost. 3. PR description slightly overstates the 4. Field placement nit in Things that look right
|
- Drop the stranded no-op getServerState() read at the top of clearClientInformation in OAuthStorageBase (carried over verbatim from the three originals). - Drop the crypto.randomUUID() guard at the task-ID site so all six in-scope sites are consistent; the fallback branch was dead code on every supported runtime. - Remove the residual `c as Context` cast at the streamSSE call site in core/mcp/remote/node/server.ts — once both hono imports resolve to the same package the route-typed Context flows through to streamSSE with no cast at all. - Move the new `options` / `config` field declarations in RemoteClientTransport up with the rest of the field block, matching the layout used by the other five rewritten classes in this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks for the review. All four observations addressed in 75fab8d. 1. Stranded 2. 3. 4. Field placement. Moved Re-ran |
|
@claude review |
|
Claude finished @cliffhall's task in 1m 1s —— View job Claude PR Re-Review
SummaryAll four observations from the previous review are cleanly addressed in 75fab8d. Each change is minimal and surgical — 4 files, +4/-9 lines total, no collateral edits. CI is green. Ship it. Verification1. Stranded 2. 3. 4. Field placement — fixed. No new issuesNothing introduced by the fixup commit. No new call sites, no drift in style, no stray LGTM. |
Closes #1309.
Five mechanical cleanups deferred from the v1.5 runtime port (#1306). Each is independent; all together drop ~210 lines and re-tighten TS strictness.
Summary
Consolidate
OAuthStorageimplementations.Browser/Node/RemoteOAuthStoragewere three ~130-line copies that differed only in their adapter. Body lives once in a newOAuthStorageBase(core/auth/oauth-storage.ts); each environment file is now a 5-line subclass that wires its adapter and callssuper. Public API (new BrowserOAuthStorage(),new NodeOAuthStorage(path?),new RemoteOAuthStorage(opts)) is unchanged, so all existing call sites and tests work untouched.Re-enable
erasableSyntaxOnly. Rewrote the sevenconstructor(private foo: T)sites enumerated in the issue, plus two extras the issue missed (samplingCreateMessage.ts/elicitationCreateMessage.ts), as explicit field declarations + assignments. The temporaryerasableSyntaxOnly: falseoverride + TODO intsconfig.app.jsonis gone.Logger consistency in
inspectorClient.ts. Swapped the oneconsole.error(roots/list_changed failure path) tothis.logger.error({ error }, "…")to match the rest of the file.crypto.randomUUID()everywhere. The five message-tracking + sampling/elicitation ID sites that used${Date.now()}-${Math.random()}now usecrypto.randomUUID()directly (with semantic prefixes preserved on the sampling/elicit cases).Drop the
streamSSEcast incore/mcp/remote/node/server.ts. Pinned the hono generic atnew Hono<Env>()per the issue. Root cause of thestreamSSE(c as unknown as …)cast turned out to be a tsconfig path-alias bug, not a hono generic mismatch: the"hono/*": ["./node_modules/hono/*"]wildcard did not honor hono's subpath exports map, sohono/streamingfell through to the root-hoistedhono@4.12.12(peerDep of the SDK) whilehonoitself resolved toclients/web/hono@4.12.18. Two physically separate packages → TS rejected the (otherwise identical)Contexttypes. Replacing the wildcard with an explicit"hono/streaming"entry in bothtsconfig.app.jsonandtsconfig.test.jsonmakes both imports resolve to the same package; the cast is no longer needed.Test plan
npm run validatefromclients/web/(format + lint + build + unit + integration coverage)npm run test:storybook(67 stories / 298 play-tests)remote-transport.test.ts(47 tests) still passes after the streamSSE cast removalOut of scope
The acceptance-criteria "out of scope" items from #1309 (
BaseOAuthClientProviderdispatcher refactor, generatedcore/mcp/version.ts, vite alias trimming) remain deferred.🤖 Generated with Claude Code