…orms/apple (#975)
Phase 3 d.1. Makes getInteractor's core -> platforms routing the final shape by
moving the Apple-specific plugin pieces under src/platforms/apple/ while keeping
the generic registry where non-interactor core code can still import it.
Moved to src/platforms/apple/:
- plugin.ts - the applePlugin instance (APPLE_SUPPORTS_BY_DEFAULT closures,
appLog/perf facets, createInteractor/discoverDevices), extracted
from the former core/platform-plugin/register-builtins.ts
- interactor.ts - was core/interactors/apple.ts (createAppleInteractor)
- interactions.ts - was platforms/ios/interactions.ts (the Apple interaction
dispatcher: iOS synthesized gesture / tvOS remote-press /
macOS desktop-scroll); platforms/ios/ is now removed
- __tests__/watchos-sentinel.test.ts - co-located with its subject
Stayed in core/ (layering):
- The generic registry + PlatformPlugin type stay in core/platform-plugin/plugin.ts.
core/capabilities.ts (non-interactor core) imports getPlugin/tryGetPlugin, and R3
forbids core outside core/interactors/ from statically importing platforms/, so the
registry cannot move.
- register-builtins.ts moved to core/interactors/register-builtins.ts (still core/):
the android/linux/web wiring plus the registry-population entry point. As an
interactor-seam module it is the one place R3 permits a static value import of
platforms/, so it pulls in applePlugin and keeps the exhaustiveness assertion.
- apple-os-capabilities.ts stays in core/ (smallest move; the moved Apple closures
reach it via a legal platforms -> core import).
Layering guard passes (R1/R2/R3, 678 files). The applePlugin only reaches leaf code
via lazy dynamic import(), so the new static platforms/apple/plugin.ts import at the
seam does not regress CLI cold-start.
What
Phase 3 step d.1 (part of #972). Relocates the Apple-specific plugin pieces under
src/platforms/apple/, makinggetInteractor'score → platformsrouting the final shape. Closes #975.Moved to
src/platforms/apple/plugin.ts— theapplePlugininstance:APPLE_SUPPORTS_BY_DEFAULT/APPLE_UNSUPPORTED_HINT_BY_DEFAULTcapability closures, theappLog/perffacets, and the lazycreateInteractor/discoverDevices. Extracted from the formercore/platform-plugin/register-builtins.ts.interactor.ts— wascore/interactors/apple.ts(createAppleInteractor).interactions.ts— wasplatforms/ios/interactions.ts, the Apple interaction dispatcher leaf (iOS synthesized gesture, tvOS remote-press, macOS desktop-scroll).src/platforms/ios/is now removed.__tests__/watchos-sentinel.test.ts— co-located with its subject (wascore/interactors/__tests__/apple-watchos-sentinel.test.ts).Stayed in
core/— and why (layering)PlatformPlugintype stay incore/platform-plugin/plugin.ts.core/capabilities.ts(non-interactor core) importsgetPlugin/tryGetPlugin; under R3 (scripts/layering/check.ts)core/outsidecore/interactors/may not statically importplatforms/. Moving the registry would break that, so it stays put — the Apple plugin instance is simply its first relocated consumer.register-builtins.tsmoved tocore/interactors/register-builtins.ts(still incore/). It keeps the android/linux/web wiring, theBUILTIN_PLATFORM_PLUGINSarray, the compile-time exhaustiveness assertion, andregisterBuiltinPlatformPlugins(). The interactor seam (src/core/interactors/) is the one place R3 permits a static value import ofplatforms/, so this is whereapplePluginis legally pulled into the registry. Bothcore/interactors.tsandcore/capabilities.ts(and the daemon app-log/perf paths) import the registration entry point from here.apple-os-capabilities.tsstays incore/platform-plugin/(smallest move; not in the issue's move list). The relocated Apple closures reach it via a legalplatforms → corevalue import.Layering rationale
applePluginreaches all leaf code (XCTest runner, device discovery, the interactor) only through lazyimport(); its static imports are the thinPlatformPlugintype +PUBLIC_COMMANDS+appleOsCapabilities+shouldUseHostMacFastPath. So the new staticplatforms/apple/plugin.tsimport at the interactor seam does not regress CLI cold-start. No leaves were flattened; function names (iosRunnerOverrides,createAppleInteractor, etc.) are unchanged — this is a pure relocation.Verification (binaries directly)
tsc -p tsconfig.json— OKoxlint . --deny-warnings— exit 0oxfmt --write/--check src test— cleannode --experimental-strip-types scripts/layering/check.ts— OK (R1/R2/R3, 678 files) ← the point of this issuerslib build— OKCI=true vitest run --project unit— all green except the knownfillAndroidcontention flake (platforms/android/__tests__/index.test.ts), confirmed passing in isolation; the 8 directly-affected test files pass (135 tests)fallow audit --base origin/main— no new findings (19 changed files)Human-review-only — do not merge.