Skip to content

Collapse iOS/macOS dual paths in MCP handlers behind PreviewSessionHandle#159

Open
obj-p wants to merge 2 commits intomainfrom
refactor/preview-session-handle
Open

Collapse iOS/macOS dual paths in MCP handlers behind PreviewSessionHandle#159
obj-p wants to merge 2 commits intomainfrom
refactor/preview-session-handle

Conversation

@obj-p
Copy link
Copy Markdown
Owner

@obj-p obj-p commented May 2, 2026

Summary

  • Introduces PreviewSessionHandle protocol with MacOSPreviewHandle and IOSPreviewHandle adapters, plus a SessionRouter actor that resolves a session ID to whichever backend owns it.
  • Collapses the duplicated iOS/macOS branches in five MCP handlers (`preview_snapshot`, `preview_stop`, `preview_configure`, `preview_switch`, `preview_variants`) plus `configQualityForSession` to single-path dispatch through the router.
  • Encapsulates the macOS-specific `host.loadPreview` after `setTraits` and the 300ms layout-settle pause inside `MacOSPreviewHandle.setTraits` — handlers no longer mention either.

`MCPServer.swift` drops 194 lines (1325 → 1131). Per-handler shrinkage:

  • `handlePreviewVariants`: 195 → 100
  • `handlePreviewSwitch`: 84 → 47
  • `handlePreviewConfigure`: 50 → 28
  • `handlePreviewStop`: 41 → 23
  • `handlePreviewSnapshot`: 51 → 22
  • `configQualityForSession`: 9 → 4

This is step #2 of the architectural-refactor roadmap. The follow-up handler-per-file split (#1) is now a smaller, more reviewable diff because the dual-path collapse halved the file first.

Behavior preserved

  • `preview_stop` returns `"iOS preview session ... closed."` for iOS and `"Preview session ... closed."` for macOS — the platform-prefixed message is asserted by `IOSCLIWorkflowTests`.
  • The 300ms layout-settle remains on the back-to-back `setTraits → snapshot` path used by `preview_variants`. `reconfigure` and `switchPreview` continue to skip the settle.
  • The variants restoration still skips when `isRegistered` is false (concurrent `preview_stop` during the capture loop) — guard logic is now centralized on the handle.

Behavior changes (intentional, minor)

  • The macOS variants restore step now incurs the 300ms layout-settle since `setTraits` encapsulates it. The restore happens once at end-of-loop, so the cost is negligible.
  • `Snapshot.ImageFormat` is selected inside `MacOSPreviewHandle.snapshot` rather than at the call site — same JPEG/PNG semantics, fewer call-site branches.

Test plan

  • `swift build` — clean
  • `swift test --filter PreviewsCoreTests` — 246 tests in 14 suites pass
  • `swift test --filter MacOSMCPTests` — 7 tests pass (including hot-reload, heartbeat, withTimeout-pthread)
  • `swift test --filter IOSMCPTests` — 2 tests pass (full iOS workflow: start, snapshot, elements, tap, swipe, switch)
  • `swift test --filter IOSCLIWorkflowTests` — passes (asserts `"iOS preview session"` in stop stderr)
  • `swift test --filter VariantsCommandTests` — 13 tests pass
  • `swift test --filter ConfigureCommandTests --filter SwitchCommandTests --filter SnapshotCommandTests --filter StopCommandTests --filter RunCommandTests --filter ListCommandTests` — 40 tests across 6 suites pass (incl. iOS `--platform ios` snapshot)
  • `swift test` (full suite, skipping `IOSCLIWorkflowTests / IOSMCPTests / IOSPreviewSessionTests / SimulatorManagerTests`) — 344 tests in 35 suites pass
  • `swift-format lint --strict` on changed files — clean

🤖 Generated with Claude Code

obj-p and others added 2 commits May 2, 2026 15:51
…ndle

Every multi-platform MCP tool handler hand-coded `if let iosSession = ... /
else macOS ...`, with `preview_variants` carrying ~95 nearly-identical lines
per branch and the still-registered guard duplicated at MCPServer.swift:1049
and :1137. Introduce a `PreviewSessionHandle` protocol with iOS and macOS
adapters, plus a `SessionRouter` that resolves a session ID to whichever
backend owns it. Handler dispatch becomes single-path; the macOS-specific
`host.loadPreview` after `setTraits` and the 300ms layout-settle pause
move into `MacOSPreviewHandle.setTraits`.

MCPServer.swift drops 194 lines (1325 → 1131); the new abstractions add
214. Net +20 LOC for the collapse, but `handlePreviewVariants` shrinks
195 → 100, `handlePreviewSwitch` 84 → 47, `handlePreviewConfigure` 50 → 28,
`handlePreviewStop` 41 → 23, `handlePreviewSnapshot` 51 → 22, and
`configQualityForSession` 9 → 4.

Step #2 of the architectural roadmap. Handler-per-file split (#1) is the
follow-up.

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

The previous commit folded the post-loadPreview pause into
MacOSPreviewHandle.setTraits, which meant the variants restore step
(which doesn't snapshot) also paid 300ms per call. That was negligible
in isolation but compounded with CI's slower compile times — the
preview_variants test on build-and-test wedged past its 60s callTool
budget (44s on main → timeout on PR).

Add an explicit `awaitLayoutSettle()` to PreviewSessionHandle. macOS
sleeps 300ms; iOS no-ops. The variants handler calls it between
setTraits and snapshot inside the loop only — restore reverts to
original zero-sleep behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant