Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@ After any non-trivial change, at minimum:

## Module layout

Four SwiftPM targets; dependency graph flows in one direction.
Five SwiftPM targets; dependency graph flows in one direction.

| Target | Path | Depends on |
|---|---|---|
| `SimUseCore` | `Sources/SimUseCore/` | Foundation + ArgumentParser |
| `iOSSimBackend` | `Sources/iOSSimBackend/` | SimUseCore + FB* XCFrameworks + AVFoundation |
| `SimUseVideo` | `Sources/SimUseVideo/` | SimUseCore + AVFoundation/ImageIO |
| `iOSSimBackend` | `Sources/iOSSimBackend/` | SimUseCore + SimUseVideo + FB* XCFrameworks + AVFoundation |
| `AndroidBackend` | `Sources/AndroidBackend/` | SimUseCore + ArgumentParser |
| `SimUse` (executable) | `Sources/SimUse/` | SimUseCore + iOSSimBackend + AndroidBackend + FB* |
| `SimUse` (executable) | `Sources/SimUse/` | SimUseCore + SimUseVideo + iOSSimBackend + AndroidBackend + FB* |

`SimUseVideo` holds the platform-neutral host-side video plumbing (H.264 Annex B parsing, passthrough muxing, `AVAssetWriter` encoding, frame utilities) shared by the iOS and Android recording/streaming paths. It must stay FB*-free — anything that needs FBSimulatorControl belongs in `iOSSimBackend` (e.g. the `VideoFrameUtilities.captureScreenshotData` extension), anything adb-shaped in `AndroidBackend`.

### Verb dispatch

Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Internal: the platform-neutral video plumbing (H.264 Annex B parsing, passthrough muxing, `AVAssetWriter` encoding, frame/output-path utilities) moved out of `iOSSimBackend` into a new `SimUseVideo` target, and the generic process-control helpers (`CancellationFlag`, `SignalObserver`, …) into `SimUseCore`. Pure restructuring — no CLI behavior change; unblocks hosting Android video verbs inside `AndroidBackend` (#78 groundwork).
- `gesture --screen-width/--screen-height` on iOS: for **single-finger presets** they now describe a visual-space canvas and default to the auto-detected screen size of the current orientation (previously always 390×844, iPhone 15 portrait — wrong for iPads and every landscape state); 390×844 survives only when the screen size cannot be probed. **Pinch/rotate presets** keep the raw device-native portrait canvas with the fixed 390×844 default.

### Added

- `sim-use android record-video`: the Android recording engine moved out of the top-level forwarder into `AndroidBackend`, giving `record-video` the same three-surface layout as every other cross-platform verb (top-level + `ios` + `android`). Flags and behavior are unchanged; `sim-use record-video` with an Android serial routes to the same implementation.
- `make e2e-matrix` (`scripts/e2e-matrix.sh`): iOS E2E across the supported host environments — Xcode 26.x / Xcode 27.x × Device Hub closed at boot (the classic Simulator.app workflow, legacy `indigo` HID) / Device Hub open at boot (CoreDevice `dtuhid`). One leg runs the full suite (default `x27-hub`, the primary workflow once Xcode 27 ships; `--full <leg>|all|none` to change), the rest run the new smoke tier (`test-runner.sh --smoke`: describe-ui, tap, type, scroll); legs whose Xcode is not installed are skipped. The package builds once on the xcode-select toolchain (`build_products/` is toolchain-locked); each leg swaps only the *runtime* Xcode — `SIM_USE_TEST_DEVELOPER_DIR`, which the test harness injects as `DEVELOPER_DIR` into every process the suites spawn — and boots a device whose iOS runtime matches the leg's Xcode generation (runtimes are system-wide, so "newest available" would cross-contaminate). Every leg is double-gated against silently green-running the wrong combination: dtuhidd process-tree checks before and after the suites, plus a `SIM_USE_DEBUG` probe that must report the matching HID transport-selection predicate. Per-leg logs and a combination-evidence file land in `.build/e2e-matrix/<timestamp>/`. `test-runner.sh` now also accepts arbitrary repeatable `swift test --filter` patterns (previously one suite from a fixed whitelist) and resolves its default simulator by exact device name on the newest *available* runtime (previously a substring match that could pick an unavailable device or an "… Pro Max" sibling).
- `swipe` / `touch --coordinate-space native|ui` (top-level and `ios` subcommands): explicit coordinates keep their device-native portrait default, and `ui` opts them into the visual space `describe-ui` prints — endpoints are orientation-calibrated per command (per batch for batch steps), so outline coordinates stay correct on a rotated device (#66). `touch` accepts `ui` in the atomic `--down --up` form only: a split touch could straddle a rotation and land its two halves in different spaces. A failed calibration degrades to native dispatch and says so via the `advisory` envelope key. On Android the flag is accepted and ignored — on the top-level commands and the `android swipe` / `android touch` direct commands alike (display coordinates already rotate with the UI).
- The agent-eval suite can now pin exactly which sim-use binary a run evaluates: `make eval ARGS="-b <path>"` / `scripts/eval.sh --sim-use <path>` / `run.py --sim-use <path>` (default remains whatever `sim-use` resolves to on PATH). The wrapper and runner print `sim-use under test: <real path> (<version>)` up front and the report header records it, so a run can never silently exercise the wrong binary — and development builds under `.build/` can be evaluated directly. New repo skill `.claude/skills/run-evals/` orchestrates the whole flow for agents and contributors: environment prep (Device Hub closed, fixtures installed), binary selection, cost confirmation, and verdict triage; `e2e/agent-evals/README.md` documents the new prereqs and flags.
Expand Down
21 changes: 20 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ let package = Package(
name: "SimUseCore",
targets: ["SimUseCore"]
),
.library(
name: "SimUseVideo",
targets: ["SimUseVideo"]
),
.library(
name: "AndroidBackend",
targets: ["AndroidBackend"]
Expand All @@ -100,10 +104,23 @@ let package = Package(
// of higher targets.
plugins: ["VersionPlugin"]
),
// Platform-neutral host-side video plumbing (H.264 parsing/muxing/
// encoding, frame utilities) shared by both backends. Must stay
// FB*-free: anything that needs FBSimulatorControl belongs in
// iOSSimBackend, anything adb-shaped in AndroidBackend.
.target(
name: "SimUseVideo",
dependencies: [
"SimUseCore",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
path: "Sources/SimUseVideo"
),
.target(
name: "iOSSimBackend",
dependencies: [
"SimUseCore",
"SimUseVideo",
"FBSimulatorControl",
"FBControlCore",
"XCTestBootstrap",
Expand All @@ -120,6 +137,7 @@ let package = Package(
name: "AndroidBackend",
dependencies: [
"SimUseCore",
"SimUseVideo",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
path: "Sources/AndroidBackend",
Expand All @@ -138,6 +156,7 @@ let package = Package(
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
"SimUseCore",
"SimUseVideo",
"AndroidBackend",
"iOSSimBackend",
"FBSimulatorControl",
Expand Down Expand Up @@ -169,7 +188,7 @@ let package = Package(
),
.testTarget(
name: "SimUseTests",
dependencies: ["SimUse", "iOSSimBackend", "SimUseCore"],
dependencies: ["SimUse", "iOSSimBackend", "SimUseCore", "SimUseVideo"],
path: "Tests",
// `Tests/` is the umbrella path; the sub-target test
// directories below sit under it as separate testTargets.
Expand Down
1 change: 1 addition & 0 deletions Sources/AndroidBackend/Verbs/AndroidCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public struct AndroidCommand: ParsableCommand {
AndroidScrollCommand.self,
AndroidButtonCommand.self,
AndroidScreenshotCommand.self,
AndroidRecordVideoCommand.self,
AndroidTypeCommand.self,
]
)
Expand Down
Loading
Loading