Skip to content

Commit 72cae2b

Browse files
authored
refactor(apple): colocate the XCUITest runner client into packages/platform-apple (#2040) (#2050)
* refactor(apple): colocate the XCUITest runner client into packages/platform-apple (#2040) Moves src/platforms/apple/core/runner/ (34 modules + apple-runner-platform.ts and the 30 runner test suites) into packages/platform-apple/src/runner/ — Apple mechanics live in the Apple package. Host capabilities (exec, diagnostics, retry, process probes, locks, Apple tooling, physical-device control) enter through the package-owned AppleRunnerHost port; the root composition module src/platforms/apple/core/runner-client.ts constructs the client exactly once and re-exposes the bound operations under their historical names. R13 admits the transitional state deliberately: the family exports its root façade plus exactly the enumerated ./runner, ./runner/client, and ./runner/test-host subpaths; the ./runner façade subpath is the recorded #1983 seam for unmigrated root consumers; ./runner/client has one composition root and ./runner/test-host one vitest installer; the runner subtree may own its cache files and sockets while raw process primitives stay banned. When #1983 completes, the subpaths and every subtree exemption are deleted and the family returns to a single implementation-lazy façade export. * docs(adr): model the runner subtree as a durable platform-owned facet Review correction on #2050: the sunset story attributed the runner-consumer migration to #1983, which owns snapshot/presentation vocabulary — not the runner's daemon/root consumers — so that event cannot delete the ./runner subpaths or the subtree exemptions. Reword ADR-0019, R13, and the gate comments: the facet is the intended ownership model, its seam is enumerated and pinned (exact export list, one client composition root, one test-host installer, raw-process ban, eager-closure pins), and the seam narrows only if a real runner-consumer migration retires the direct consumers. The declaration mechanism stays apple-specific until another family needs a mechanics facet. No behavior change; identifiers and comments only.
1 parent 74a70f1 commit 72cae2b

173 files changed

Lines changed: 2103 additions & 1074 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.

.github/actions/setup-apple-runner-build/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ runs:
4444
id: source-hash
4545
run: |
4646
set -euo pipefail
47-
echo "value=${{ hashFiles('apple/runner/**', 'scripts/build-xcuitest-apple.sh', 'scripts/patch-xcuitest-runner-icon.ts', 'scripts/write-xcuitest-cache-metadata.mjs', 'src/platforms/apple/core/apple-runner-platform.ts', 'src/platforms/apple/core/runner/runner-cache-metadata.ts', 'src/platforms/apple/core/runner/runner-icon.ts', 'src/platforms/apple/core/runner/runner-xctestrun.ts', 'src/platforms/apple/core/runner/runner-xctestrun-products.ts', '.github/actions/setup-apple-runner-build/action.yml', 'package.json', 'pnpm-lock.yaml') }}" >> "$GITHUB_OUTPUT"
47+
echo "value=${{ hashFiles('apple/runner/**', 'scripts/build-xcuitest-apple.sh', 'scripts/patch-xcuitest-runner-icon.ts', 'scripts/write-xcuitest-cache-metadata.mjs', 'packages/platform-apple/src/runner/apple-runner-platform.ts', 'packages/platform-apple/src/runner/runner-cache-metadata.ts', 'packages/platform-apple/src/runner/runner-icon.ts', 'packages/platform-apple/src/runner/runner-xctestrun.ts', 'packages/platform-apple/src/runner/runner-xctestrun-products.ts', '.github/actions/setup-apple-runner-build/action.yml', 'package.json', 'pnpm-lock.yaml') }}" >> "$GITHUB_OUTPUT"
4848
shell: bash
4949

5050
- name: Resolve Apple runner build variant

.github/workflows/xctest-nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ jobs:
123123
# `RunnerTests/testCommand` is not a test. It is the runner's server entry point: it
124124
# opens an NWListener and blocks in `XCTWaiter.wait(timeout: 24 * 60 * 60)` until a
125125
# client closes the session, which is exactly how production drives it
126-
# (src/platforms/apple/core/runner/runner-session.ts always passes it as the sole
126+
# (packages/platform-apple/src/runner/runner-session.ts always passes it as the sole
127127
# `-only-testing:`). It compiles unconditionally — the `#if AGENT_DEVICE_RUNNER_UNIT_TESTS`
128128
# block ends well above it — so an unfiltered run reaches it in alphabetical order and
129129
# hangs the job until `timeout-minutes`. Its one escape hatch,

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ cross-language rules change through golden tables under `contracts/fixtures/`.
112112

113113
## Runtime and diagnostics seams
114114

115-
The OS-neutral Apple runner lives under `src/platforms/apple/core/runner/`. For connection errors,
115+
The OS-neutral Apple runner lives under `packages/platform-apple/src/runner/`. For connection errors,
116116
retry policy, or command typing, start at `runner-contract.ts`; transport stays below session/client
117117
behavior, and xctestrun build/cache logic stays outside request execution.
118118

apple/runner/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Current internal runner for iOS, tvOS, and macOS desktop automation.
1515
Protocol and maintenance references:
1616

1717
- Protocol overview: [`RUNNER_PROTOCOL.md`](RUNNER_PROTOCOL.md)
18-
- TypeScript client: [`../../src/platforms/apple/core/runner/runner-client.ts`](../../src/platforms/apple/core/runner/runner-client.ts)
18+
- TypeScript client: [`../../packages/platform-apple/src/runner/runner-client.ts`](../../packages/platform-apple/src/runner/runner-client.ts)
1919
- Swift wire models: [`AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift`](AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift)
2020

2121
## UITest Runner File Map

apple/runner/RUNNER_PROTOCOL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ than silently applied:
6464

6565
The current command names are defined in:
6666

67-
- [`../../src/platforms/apple/core/runner/runner-client.ts`](../../src/platforms/apple/core/runner/runner-client.ts)
67+
- [`../../packages/platform-apple/src/runner/runner-client.ts`](../../packages/platform-apple/src/runner/runner-client.ts)
6868
- [`AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift`](AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift)
6969

7070
## Response Shape

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,21 @@ platform-common package, and it preserves the package façades' implementation-l
129129
Its introduction carries the normal workspace-package compliance surface: `check:affected`
130130
selection, R11/R13 package enumeration, and the composite typecheck project list.
131131

132+
The Apple XCUITest runner client is a durable platform-owned implementation facet colocated
133+
inside `packages/platform-apple` as the `src/runner/` subtree (#2040) — Apple mechanics belong to
134+
the Apple package. R13 models the facet by enumeration rather than by exception sprawl: the family
135+
exports its root façade plus exactly the `./runner`, `./runner/client`, and `./runner/test-host`
136+
subpaths; the `./runner` façade subpath is the seam through which daemon and root consumers reach
137+
runner mechanics directly today; the host-bound `./runner/client` factory has one composition root
138+
and `./runner/test-host` one vitest installer; the facet owns its cache files and usbmux sockets
139+
(the ambient-host rule exempts exactly that subtree), while raw process primitives stay banned —
140+
host authority still enters through one focused injected port (`AppleRunnerHost`: process
141+
execution, diagnostics, retry, probes, locks, foreground Apple tooling, physical-device control)
142+
constructed by exactly one composition root. No current issue owns migrating the runner's direct
143+
consumers behind the composition gateway; if such a migration retires them, the `./runner` seam
144+
narrows with it, but the facet itself is the intended ownership model, not a temporary exception.
145+
The declaration mechanism stays apple-specific until another family needs a mechanics facet.
146+
132147
Canonical family, `AppleOS`, public-leaf, and selector identity remain declared in
133148
`@agent-device/kernel/device`. Platform-module metadata references one canonical family; during
134149
coexistence the legacy plugin registry derives its family identity from the same declaration rather

fallow-baselines/health.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,6 @@
374374
"count": 1
375375
}
376376
},
377-
"src/platforms/apple/core/runner/runner-startup-transport.ts": {
378-
"crap_high": {
379-
"count": 1
380-
}
381-
},
382377
"src/platforms/apple/core/screenshot-status-bar.ts": {
383378
"complexity_moderate": {
384379
"count": 1
@@ -557,6 +552,11 @@
557552
"crap_moderate": {
558553
"count": 1
559554
}
555+
},
556+
"packages/platform-apple/src/runner/runner-startup-transport.ts": {
557+
"crap_high": {
558+
"count": 1
559+
}
560560
}
561561
},
562562
"runtime_coverage_findings": [],

packages/platform-apple/package.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,25 @@
77
"dependencies": {
88
"@agent-device/capture-kit": "workspace:*",
99
"@agent-device/contracts": "workspace:*",
10-
"@agent-device/kernel": "workspace:*"
10+
"@agent-device/kernel": "workspace:*",
11+
"@agent-device/xml": "workspace:*"
1112
},
1213
"exports": {
1314
".": {
1415
"types": "./src/index.ts",
1516
"default": "./src/index.ts"
17+
},
18+
"./runner": {
19+
"types": "./src/runner/index.ts",
20+
"default": "./src/runner/index.ts"
21+
},
22+
"./runner/client": {
23+
"types": "./src/runner/client.ts",
24+
"default": "./src/runner/client.ts"
25+
},
26+
"./runner/test-host": {
27+
"types": "./src/runner/test-host.ts",
28+
"default": "./src/runner/test-host.ts"
1629
}
1730
}
1831
}

src/platforms/apple/core/__tests__/apple-runner-platform.test.ts renamed to packages/platform-apple/src/runner/__tests__/apple-runner-platform.test.ts

File renamed without changes.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { DeviceInfo } from '@agent-device/kernel/device';
2+
3+
// Apple-family device fixtures for runner tests; the package owns its own
4+
// test data rather than reaching into root test-utils.
5+
6+
export const IOS_SIMULATOR: DeviceInfo = {
7+
platform: 'apple',
8+
id: 'sim-1',
9+
name: 'iPhone 17 Pro',
10+
kind: 'simulator',
11+
appleOs: 'ios',
12+
booted: true,
13+
};
14+
15+
export const IOS_DEVICE: DeviceInfo = {
16+
platform: 'apple',
17+
id: 'ios-device-1',
18+
name: 'iPhone',
19+
kind: 'device',
20+
appleOs: 'ios',
21+
booted: true,
22+
};
23+
24+
export const MACOS_DEVICE: DeviceInfo = {
25+
platform: 'apple',
26+
id: 'host-macos-local',
27+
name: 'Mac',
28+
kind: 'device',
29+
target: 'desktop',
30+
appleOs: 'macos',
31+
booted: true,
32+
};
33+
34+
export const TVOS_SIMULATOR: DeviceInfo = {
35+
platform: 'apple',
36+
id: 'tv-sim-1',
37+
name: 'Apple TV',
38+
kind: 'simulator',
39+
target: 'tv',
40+
appleOs: 'tvos',
41+
};

0 commit comments

Comments
 (0)