Skip to content

Commit ed26b31

Browse files
authored
refactor: contract Apple platform surface (#2125)
* refactor: contract Apple platform surface * refactor: use Apple plugin seam in tests * test: ratchet snapshot handler size
1 parent a6232e5 commit ed26b31

48 files changed

Lines changed: 179 additions & 612 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.fallowrc.json

Lines changed: 6 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,7 @@
9090
"exports": ["buildAppNotInstalledError"]
9191
},
9292
{
93-
"comment": "The legacy push helper remains a package-root operation reached through a dynamic import; Fallow cannot connect that root wrapper to this source export.",
94-
"file": "packages/platform-apple/src/core/app-device-io.ts",
95-
"exports": ["pushIosNotification"]
96-
},
97-
{
98-
"comment": "The lifecycle package facade is consumed through workspace package exports. Fallow does not follow that package boundary, so keep only the two root lifecycle helpers without visible production edges here.",
99-
"file": "packages/platform-apple/src/app-lifecycle-facade.ts",
100-
"exports": ["openIosApp", "openIosDevice"]
101-
},
102-
{
103-
"comment": "Apple install mechanics are reached through the root lazy façade, while bundle-info consumers use the named install-artifact façade. Fallow cannot connect dynamic import member reads to these source exports; keep this list limited to the actual facade re-exports.",
93+
"comment": "Apple install mechanics are reached through the named install-artifact façade. Fallow cannot connect workspace package exports to these source exports; keep this list limited to the actual facade re-exports.",
10494
"file": "packages/platform-apple/src/core/install-artifact.ts",
10595
"exports": ["prepareIosInstallArtifact", "readIosBundleInfo"]
10696
},
@@ -140,11 +130,6 @@
140130
"runXcrun"
141131
]
142132
},
143-
{
144-
"comment": "The runner-operations package facade is consumed through workspace package exports. Fallow does not follow that package boundary, so keep the two operations without visible production edges here explicitly accounted for.",
145-
"file": "packages/platform-apple/src/runner-operations-facade.ts",
146-
"exports": ["hasCachedAppleRunnerArtifact", "runApplePressSeries"]
147-
},
148133
{
149134
"comment": "The device-aware simctl argument builder is reached through the named lazy simctl façade. Fallow cannot connect the dynamic member read to this source export; keep the suppression limited to that re-export.",
150135
"file": "packages/platform-apple/src/core/simctl.ts",
@@ -153,20 +138,10 @@
153138
{
154139
"comment": "The device-aware simctl argument builder is a named package entrypoint reached through dynamic platform-runtime imports. Fallow cannot connect those member reads to the re-export; keep the suppression limited to this one facade symbol.",
155140
"file": "packages/platform-apple/src/simctl-facade.ts",
156-
"exports": ["buildSimctlArgs", "buildSimctlArgsForDevice"]
157-
},
158-
{
159-
"comment": "The simulator package facade is consumed through workspace package exports. Fallow does not follow that package boundary, so keep the legacy shutdown operation explicitly accounted for.",
160-
"file": "packages/platform-apple/src/simulator-facade.ts",
161-
"exports": ["shutdownSimulator"]
162-
},
163-
{
164-
"comment": "Apple mechanics are reached through the named lazy façade in packages/platform-apple/src/index.ts. Fallow cannot connect dynamic import member reads to this source export; keep this list limited to wrappers present in that façade.",
165-
"file": "packages/platform-apple/src/core/perf-xctrace.ts",
166-
"exports": ["cleanupAppleXctracePerfCapture"]
141+
"exports": ["buildSimctlArgsForDevice"]
167142
},
168143
{
169-
"comment": "Apple runner mechanics are reached through the named lazy façade in packages/platform-apple/src/index.ts. Fallow cannot connect dynamic import member reads to these source exports; keep this list limited to wrappers present in that façade or its cleanup composition.",
144+
"comment": "Apple runner mechanics are reached through the named runner operations façade. Fallow cannot connect workspace package exports to these source exports; keep this list limited to the façade and its cleanup composition.",
170145
"file": "packages/platform-apple/src/core/runner-client.ts",
171146
"exports": [
172147
"notifyIosRunnerAppRelaunched",
@@ -184,104 +159,20 @@
184159
]
185160
},
186161
{
187-
"comment": "The Apple root façade owns the lazy runner-owner mutator; Fallow cannot connect its dynamic import member read to the moved source export.",
162+
"comment": "The named runner-owner façade owns this mutator; Fallow cannot connect the workspace package export to the moved source export.",
188163
"file": "packages/platform-apple/src/core/runner-owner-state.ts",
189164
"exports": ["setRunnerLeaseOwnerStateDir"]
190165
},
191166
{
192-
"comment": "Apple diagnostics are reached through the named lazy façade in packages/platform-apple/src/index.ts. Fallow cannot connect dynamic import member reads to these source exports; keep this list limited to wrappers present in that façade.",
167+
"comment": "Apple diagnostics are reached through the named doctor façade. Fallow cannot connect workspace package exports to these source exports.",
193168
"file": "packages/platform-apple/src/doctor.ts",
194169
"exports": ["appleToolchainCheck", "appleRunnerWarmupCheck"]
195170
},
196171
{
197-
"comment": "macOS helper mechanics are reached through the named lazy façade in packages/platform-apple/src/index.ts. Fallow cannot connect dynamic import member reads to these source exports; keep this list limited to wrappers present in that façade.",
172+
"comment": "macOS helper mechanics are reached through the named macOS façade. Fallow cannot connect workspace package exports to these source exports.",
198173
"file": "packages/platform-apple/src/os/macos/helper.ts",
199174
"exports": ["startMacOsAudioProbeProcess", "resolveFrontmostMacOsApp"]
200175
},
201-
{
202-
"comment": "The Apple package root is a cold-start-preserving named façade: its production consumers load the value wrappers through dynamic imports. Fallow cannot connect those member reads, so this exact list records only the façade exports currently reported as unreachable; static consumers remain visible to the audit.",
203-
"file": "packages/platform-apple/src/index.ts",
204-
"exports": [
205-
"appleToolchainCheck",
206-
"appleRunnerWarmupCheck",
207-
"detectSoleRunningIosSimulatorApp",
208-
"findIosSimulatorInstalledApp",
209-
"invalidateIosAppResolutionCache",
210-
"listIosApps",
211-
"resolveIosApp",
212-
"resolveIosSimulatorDeepLinkBundleId",
213-
"closeIosApp",
214-
"openIosApp",
215-
"openIosDevice",
216-
"screenshotIos",
217-
"pushIosNotification",
218-
"readIosClipboardText",
219-
"writeIosClipboardText",
220-
"runAppleToolCommand",
221-
"runXcrun",
222-
"createLocalAppleToolProvider",
223-
"readApplePlistJson",
224-
"setIosSetting",
225-
"readAppleAlert",
226-
"awaitAppleAlert",
227-
"actOnAppleAlert",
228-
"createAppleInteractor",
229-
"ensureBootedSimulator",
230-
"shutdownSimulator",
231-
"withAppleToolProvider",
232-
"prepareIosInstallArtifact",
233-
"symbolicateCrashArtifact",
234-
"queryAppleRunnerSelector",
235-
"resolveFrontmostMacOsApp",
236-
"runMacOsAlertAction",
237-
"startMacOsAudioProbeProcess",
238-
"captureMacOsSurfaceSnapshot",
239-
"cleanupAppleXctracePerfCapture",
240-
"sampleAppleMemoryPerf",
241-
"captureAppleMemorySnapshot",
242-
"sampleAppleFramePerf",
243-
"prepareAppleTraceRecordRetry",
244-
"resolveAppleExecutable",
245-
"resolveIosDevicePerfTarget",
246-
"readAppleProcessSamples",
247-
"startAppleXctracePerfCapture",
248-
"stopAppleXctracePerfCapture",
249-
"writeAppleXctracePerfReport",
250-
"runApplePressSeries",
251-
"runAppleRunnerCommand",
252-
"notifyIosRunnerAppRelaunched",
253-
"prewarmAppleRunnerCache",
254-
"prewarmIosRunnerSession",
255-
"prepareIosRunner",
256-
"resolveRunnerAppBundleId",
257-
"detachIosSimulatorRunnerSessionsForShutdown",
258-
"getRunnerSessionSnapshot",
259-
"scheduleIosRunnerIdleStop",
260-
"stopIosRunnerSession",
261-
"stopAllIosRunnerSessions",
262-
"cleanupRunnerLeasesForOwner",
263-
"readStaleRunnerLease",
264-
"verifyLeaseRunnerPidIdentity",
265-
"applyXctestRunnerAppIconFromDerivedPath",
266-
"AppleMacOsHelperProvider",
267-
"AppleToolAvailabilityChecker",
268-
"AppleToolCommandExecutor",
269-
"AppleXcrunToolProvider",
270-
"IosPhysicalDeviceBackend",
271-
"IosPhysicalDeviceControl",
272-
"IosPhysicalDeviceTunnel",
273-
"PreparedIosInstallArtifact",
274-
"AppleMemoryPerfSample",
275-
"AppleMemorySnapshotResult",
276-
"AppleProcessSample",
277-
"AppleXctraceCpuProfileReport",
278-
"AppleXctracePerfCapture",
279-
"AppleXctracePerfMode",
280-
"AppleXctracePerfResult",
281-
"MacOsPermissionTarget",
282-
"MacOsSnapshotNode"
283-
]
284-
},
285176
{
286177
"comment": "The legacy Maestro fallback wording remains contracts vocabulary for wire/fixture compatibility, but has no in-repo production consumer. The Apple migration changes this file's documentation path, so keep the existing declaration explicit without treating it as a new W4 export leak.",
287178
"file": "packages/contracts/src/interactor-types.ts",

docs/adr/0019-request-bound-platform-runtime.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ selection, R11/R13 package enumeration, and the composite typecheck project list
180180
> planted red, and the `retired-platforms-zone` rule rejects every production, test, or fixture
181181
> file under the former `src/platforms` path.
182182
183+
The Apple package root is composition-only: it exposes the inventory module, runtime module,
184+
shutdown loader, and platform plugin. Synchronous consumers use named domain facets instead of a
185+
second compatibility surface on the root.
186+
183187
The Apple XCUITest runner client is a durable platform-owned implementation facet colocated
184188
inside `packages/platform-apple` as the `src/runner/` subtree (#2040) — Apple mechanics belong to
185189
the Apple package. R13 models the package by enumeration rather than by exception sprawl: the family
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { closeIosApp, openIosApp, openIosDevice } from './core/app-launch.ts';
1+
export { closeIosApp } from './core/app-launch.ts';

packages/platform-apple/src/index.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
import assert from 'node:assert/strict';
22
import { test } from 'vitest';
33
import { buildAppNotInstalledError } from '@agent-device/platform-apple/app-resolution';
4-
import { createLocalAppleToolProvider } from './index.ts';
5-
import { buildSimctlArgs } from '@agent-device/platform-apple/simctl';
4+
import { createLocalAppleToolProvider } from '@agent-device/platform-apple/tool-provider';
5+
import * as appleRoot from './index.ts';
6+
7+
test('Apple root exposes composition only', () => {
8+
assert.deepEqual(Object.keys(appleRoot).sort(), [
9+
'applePlugin',
10+
'inventoryModule',
11+
'loadShutdownRuntime',
12+
'runtimeModule',
13+
]);
14+
});
615

716
test('lazy Apple tool provider preserves the local semantic operation shape', () => {
817
const provider = createLocalAppleToolProvider();
@@ -16,10 +25,9 @@ test('lazy Apple tool provider preserves the local semantic operation shape', ()
1625
assert.equal(typeof provider.macosHost?.listApps, 'function');
1726
});
1827

19-
test('Apple domain facades preserve synchronous helper contracts', () => {
28+
test('Apple app resolution facade preserves its synchronous helper contract', () => {
2029
const appError = buildAppNotInstalledError('Shoply');
2130

2231
assert.equal(appError.code, 'APP_NOT_INSTALLED');
23-
assert.deepEqual(buildSimctlArgs(['list']), ['simctl', 'list']);
2432
assert.equal(appError instanceof Promise, false);
2533
});

0 commit comments

Comments
 (0)