Skip to content

Commit 9fa2778

Browse files
committed
refactor: move Android family behind package exports
1 parent ddb415a commit 9fa2778

263 files changed

Lines changed: 1833 additions & 1121 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: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"ignoreExports": [
6363
{
6464
"comment": "Android perf mechanics are selected through the lazy platform host so importing agent-device does not eagerly load adb mechanics. Fallow cannot follow the dynamic property read in src/platform-runtime-perf-host.ts.",
65-
"file": "src/platforms/android/perf.ts",
65+
"file": "packages/platform-android/src/perf.ts",
6666
"exports": ["sampleAndroidMemoryPerf"]
6767
},
6868
{
@@ -170,6 +170,11 @@
170170
"createAppLogLiveHandle"
171171
]
172172
},
173+
{
174+
"comment": "Android mechanics facet: the package exports the complete named implementation seam for root/core/SDK consumers and package-owned tests; Fallow's production graph does not follow workspace subpath imports through the package exports map.",
175+
"file": "packages/platform-android/src/mechanics.ts",
176+
"exports": ["*"]
177+
},
173178
{
174179
"comment": "Deliberately kept off the @agent-device/maestro façade (index.test.ts asserts its absence) and consumed only by the conformance harness under packages/maestro/test/.",
175180
"file": "packages/maestro/src/internal/program-ir-command-parser.ts",
@@ -224,6 +229,13 @@
224229
"rules": {
225230
"unused-types": "off"
226231
}
232+
},
233+
{
234+
"comment": "Android mechanics facet types are named explicitly for the same package-subpath public seam; unused-exports remains governed by the facet entry above.",
235+
"files": ["packages/platform-android/src/mechanics.ts"],
236+
"rules": {
237+
"unused-types": "off"
238+
}
227239
}
228240
],
229241
"production": {

.github/workflows/ios.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ on:
2828
- 'src/**/__tests__/**/*.ts'
2929
- 'packages/*/src/**/*.test.ts'
3030
- 'packages/*/src/**/__tests__/**/*.ts'
31-
- 'src/platforms/android/**'
3231
- 'src/platforms/harmonyos/**'
3332
- 'src/platforms/linux/**'
3433
- 'src/platforms/vega/**'

android/ime-helper/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ security boundary): if present and it doesn't match, the broadcast is dropped an
7979
Switching the active IME is machine-global, not session-scoped. A crashed daemon that switched the
8080
IME and never restored it leaves the device with an invisible keyboard -- on a real device, this
8181
means the user cannot type anywhere until they manually reset their IME in Settings. The TS-side
82-
lifecycle (`src/platforms/android/ime-lifecycle.ts`) persists the previously active IME to disk
82+
lifecycle (`packages/platform-android/src/ime-lifecycle.ts`) persists the previously active IME to disk
8383
before switching, restores it on session close/teardown, and best-effort restores any orphaned
8484
switch left behind by a previous crashed daemon on startup.

docs/adr/0012-interactive-replay.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,10 +407,10 @@ target-binding divergences reported before the device action. This is not genera
407407
> for the wait keep-poll loop (`isUnreadableCaptureContentError`): the non-throwing `sparse-snapshot`
408408
> verdict always retries (it is already a content-quality signal), but a thrown `capture-failed` only
409409
> retries when the underlying error's `androidSnapshotHelperFailureReason` is one of the three literal
410-
> codes `rejectAndroidHelperContentUnavailable` (`platforms/android/snapshot.ts`) attaches to a
410+
> codes `rejectAndroidHelperContentUnavailable` (`packages/platform-android/src/snapshot.ts`) attaches to a
411411
> content-poor/system-window-only rejection — `empty-helper-output`, `system-window-only`,
412412
> `content-poor-app-window` (mirroring `AndroidHelperContentRecoveryDecision['reason']`,
413-
> `platforms/android/snapshot-content-recovery.ts`). This is deliberately narrower than the error's own
413+
> `packages/platform-android/src/snapshot-content-recovery.ts`). This is deliberately narrower than the error's own
414414
> generic `retriable` flag: Android's adb layer separately marks true mechanism failures retriable too
415415
> (`connection_dropped`, `device_offline`, `server_version_mismatch` — an unchanged retry of the SAME adb
416416
> command can succeed there), and a helper artifact permanently missing

docs/adr/0013-unified-gesture-plans.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Platform adapters consume the canonical plan:
7474
- Android's `executeAndroidTouchPlan` adapter seam sends planned touch, including gesture plans plus
7575
the physical movement for scroll and long-press, to provider-native touch injection when
7676
available, otherwise to the bundled instrumentation helper. One-contact endpoint plans lower in
77-
`src/platforms/android/touch-plan.ts` to 16 ms linear transport samples before either injection
77+
`packages/platform-android/src/touch-plan.ts` to 16 ms linear transport samples before either injection
7878
path; two-contact plans retain their exact planned samples. Transport samples are typed as
7979
strictly denser than the canonical endpoint pair, so skipping that lowering is a type error at
8080
the injection seams instead of a silently sparse gesture. A stationary long-press needs no

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,13 @@ process primitives outside the shared host-command port. R13 applies these rules
114114
dynamic, and re-export edges; package-owned tests may import their own public façade. Contracts may
115115
depend on kernel vocabulary but never on concrete platform packages or daemon implementation types.
116116

117-
Transitional exception (#2041): the Android adb/IME transport cluster (`adb-executor`,
118-
`ime-lifecycle`, `ime-helper`) lives in `@agent-device/platform-android` behind four registered
119-
subpaths, with its raw host primitives injected through the package's `adb-host` port by root
120-
composition wiring. Live root runtime, core interactor, SDK, and test-support consumers still import
121-
the old root paths, so R13 names an explicit shim table: each subpath is importable only by its root
122-
re-export shim (plus the host-binding, the helper-install module the binding reaches, and the
123-
cluster's own tests under `src/platforms/android/__tests__/`). Delete the shims and narrow this table
124-
only after those consumers move; the table growing is drift, not precedent.
117+
The Android family mechanics now live entirely in `@agent-device/platform-android`. Its root façade
118+
remains metadata-only and lazy; the package exports exactly two implementation facets: `./mechanics`
119+
for named Android behavior consumed by root/core/SDK code and package-owned tests, and `./adb-host`
120+
for the host port bound only by `src/platform-runtime-android-adb-host.ts`. The old
121+
`src/platforms/android` family tree and root shims are deleted. R13 enumerates these two facets and
122+
rejects any additional Android subpath or daemon production import, so package closure and host
123+
authority stay explicit rather than being restored through compatibility paths.
125124

126125
Durable-capture mechanics shared by more than one implementation live in the private
127126
`@agent-device/capture-kit` workspace package, with the enforced direction

fallow-baselines/health.json

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -336,22 +336,17 @@
336336
"count": 2
337337
}
338338
},
339-
"src/platforms/android/app-parsers.ts": {
339+
"packages/platform-android/src/app-parsers.ts": {
340340
"crap_moderate": {
341341
"count": 1
342342
}
343343
},
344-
"src/platforms/android/manifest.ts": {
344+
"packages/platform-android/src/manifest.ts": {
345345
"crap_moderate": {
346346
"count": 1
347347
}
348348
},
349-
"src/platforms/android/scroll-hints.ts": {
350-
"complexity_moderate": {
351-
"count": 1
352-
}
353-
},
354-
"src/platforms/android/ui-hierarchy.ts": {
349+
"packages/platform-android/src/ui-hierarchy.ts": {
355350
"crap_moderate": {
356351
"count": 2
357352
}
@@ -592,7 +587,7 @@
592587
"src/daemon/daemon-process.ts:high impact",
593588
"src/utils/screenshot-result.ts:high impact",
594589
"src/platforms/web/json-utils.ts:high impact",
595-
"src/platforms/android/settings.ts:complexity",
590+
"packages/platform-android/src/settings.ts:complexity",
596591
"src/utils/text-surface.ts:high impact",
597592
"src/daemon/handlers/session-test-sharding.ts:high impact",
598593
"src/daemon/handlers/session-replay-runtime.ts:complexity",
@@ -612,10 +607,10 @@
612607
"src/replay/test/reporters/format.ts:high impact",
613608
"src/daemon/handlers/session-test-infrastructure.ts:high impact",
614609
"src/daemon/handlers/session-test-artifacts.ts:high impact",
615-
"src/platforms/android/app-parsers.ts:high impact",
610+
"packages/platform-android/src/app-parsers.ts:high impact",
616611
"src/daemon/server/http-server.ts:complexity",
617-
"src/platforms/android/ui-hierarchy.ts:high impact",
618-
"src/platforms/android/sdk.ts:high impact",
612+
"packages/platform-android/src/ui-hierarchy.ts:high impact",
613+
"packages/platform-android/src/sdk.ts:high impact",
619614
"src/daemon/client/daemon-client-lifecycle.ts:complexity",
620615
"src/client/client-companion-tunnel-worker.ts:complexity"
621616
]

packages/contracts/src/android-system-chrome.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { SnapshotNode } from '@agent-device/kernel/snapshot';
33
/**
44
* Android status-bar/navigation-bar chrome identity, shared by the settle-chrome
55
* classifier (`core/snapshot-chrome.ts`) and the helper content classifier
6-
* (`platforms/android/snapshot-content-recovery.ts`). SystemUI also hosts actionable
6+
* (`packages/platform-android/src/snapshot-content-recovery.ts`). SystemUI also hosts actionable
77
* overlays — volume panel, media pickers, the shade itself — so chrome is never a
88
* package-level fact: only the status/nav-bar container's subtree is chrome.
99
*/

packages/contracts/src/snapshot-scope.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { matchesSnapshotScope, normalizeSnapshotScope } from './facades/snapshot
66

77
// Golden scope-policy table (#1797 / #1832 C2): the SAME JSON is asserted against every runtime
88
// that resolves `--scope` — this predicate, the Android platform projection
9-
// (src/platforms/android/__tests__/ui-hierarchy-scope.test.ts), and the Swift runner twin.
9+
// (packages/platform-android/src/__tests__/ui-hierarchy-scope.test.ts), and the Swift runner twin.
1010
// This file proves the PREDICATE + first-document-order-match rule; subtree slicing is proved by
1111
// the runtime legs.
1212

packages/contracts/src/snapshot-viewport-root.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const IOS_EMITTED_TYPES = [
7373
'Element(72)',
7474
] as const;
7575

76-
// src/platforms/android/ui-hierarchy.ts — `type` is the uiautomator `class`
76+
// packages/platform-android/src/ui-hierarchy.ts — `type` is the uiautomator `class`
7777
// attribute verbatim, a fully-qualified Java class name.
7878
const ANDROID_EMITTED_TYPES = [
7979
'android.view.View',

0 commit comments

Comments
 (0)