diff --git a/docs/development/architecture.md b/docs/development/architecture.md index ad335a8..ec2b5e3 100644 --- a/docs/development/architecture.md +++ b/docs/development/architecture.md @@ -14,7 +14,7 @@ flowchart TB R --> T["Trace writer\nJSONL + PNG"] end - SC["Maestro sidecar (JVM)"] + SC["Native sidecar (JVM)"] DC["Device / Emulator"] CH["Chrome (CDP)"] RD[("runs/")] @@ -32,7 +32,7 @@ flowchart TB **sanderling (Go).** The top-level binary. Bundles the spec with esbuild, evaluates it in goja, runs the main loop, dispatches actions through the `DeviceDriver` interface, writes the trace. -**Maestro sidecar (JVM).** A Kotlin process that wraps `maestro-client` and exposes a gRPC surface matching the `DeviceDriver` interface. Handles UI input, screenshots, the system accessibility tree, and OS-level alerts. Native platforms only. +**Native sidecar (JVM).** A Kotlin process that exposes a gRPC surface matching the `DeviceDriver` interface. Handles UI input, screenshots, the system accessibility tree, and OS-level alerts. Native platforms only. **Chrome (CDP).** For web targets, the Go binary drives Chrome directly over the Chrome DevTools Protocol. No sidecar is involved. @@ -40,7 +40,7 @@ flowchart TB | Channel | Platform | Transport | Purpose | |---|---|---|---| -| Go to Maestro sidecar | Native | gRPC (localhost TCP) | UI input, screenshots, system alerts | +| Go to native sidecar | Native | gRPC (localhost TCP) | UI input, screenshots, system alerts | | Go to Chrome | Web | Chrome DevTools Protocol | UI input, screenshots, DOM hierarchy, console logs | On native, the transport split exists because only real UI events need to cross process and OS-API boundaries. Introspection is cheap, frequent, and lives on a fast local socket directly to the app. On web, CDP handles both. @@ -63,7 +63,7 @@ fetch state ─► evaluate properties ─► pick action ─► dispatch 2. The runner fetches the UI hierarchy and logs from the sidecar. 3. The runner feeds state into goja. Extractors re-read; properties re-evaluate; the action generator returns a weighted tree. 4. The runner writes the trace entry for this step. -5. The runner picks an action by weight and dispatches it through the driver (gRPC to sidecar -> Maestro -> UIAutomator or XCTest). +5. The runner picks an action by weight and dispatches it through the driver (gRPC to sidecar -> UIAutomator or XCTest). 6. Loop. **Web (Chrome):** diff --git a/docs/development/decisions.md b/docs/development/decisions.md index 2a83171..454b9de 100644 --- a/docs/development/decisions.md +++ b/docs/development/decisions.md @@ -20,7 +20,7 @@ Go's `internal/` directory restriction prevents any code outside this module fro ### `internal/driver/` is an interface + subdirectory implementations -The `driver.go` file defines the `DeviceDriver` interface. Concrete implementations live in subdirectories: `sidecar/` (Maestro gRPC), `chrome/` (CDP), `mock/` (tests). This pattern keeps the runner and verifier decoupled from any specific platform. +The `driver.go` file defines the `DeviceDriver` interface. Concrete implementations live in subdirectories: `sidecar/` (gRPC to the native sidecar), `chrome/` (CDP), `mock/` (tests). This pattern keeps the runner and verifier decoupled from any specific platform. ### `internal/verifier/marshal.go` moves to `internal/inspect/` diff --git a/docs/development/design-principles.md b/docs/development/design-principles.md index f401f0b..9ca4209 100644 --- a/docs/development/design-principles.md +++ b/docs/development/design-principles.md @@ -6,14 +6,14 @@ title: Design principles ## 1. The app owns introspection; the driver owns input -On native platforms, the in-app SDK knows the state: view hierarchy, coverage, logs, exceptions, custom extractors. Maestro causes the state to change through taps, swipes, typed text, and deep links. The Go runner decides what to do. +On native platforms, the in-app SDK knows the state: view hierarchy, coverage, logs, exceptions, custom extractors. The driver causes the state to change through taps, swipes, typed text, and deep links. The Go runner decides what to do. -Splitting these responsibilities is what makes the system work across iOS and Android with one spec surface. Neither Maestro nor the SDK alone is sufficient. +Splitting these responsibilities is what makes the system work across iOS and Android with one spec surface. Neither the driver nor the SDK alone is sufficient. -- Maestro can read a coarse accessibility tree, but not the real `UIView` or `View` hierarchy, not coverage, not in-process logs. -- The SDK can see everything inside the app, but cannot dispatch UI events the way the OS would. Touch injection through Maestro goes through XCTest or UIAutomator, which the OS treats as real input. +- The driver can read a coarse accessibility tree, but not the real `UIView` or `View` hierarchy, not coverage, not in-process logs. +- The SDK can see everything inside the app, but cannot dispatch UI events the way the OS would. Touch injection goes through the OS UI-test pipeline (XCTest on iOS, UIAutomator on Android), which the OS treats as real input. -On web, Chrome DevTools Protocol handles both input and introspection. No in-app SDK is needed. +On web, the driver speaks the Chrome DevTools Protocol and handles both input and introspection. No in-app SDK is needed. ## 2. One TypeScript surface across platforms @@ -23,13 +23,13 @@ Corollary: if a concept only exists on one platform, it does not belong in the s ## 3. The driver is an interface -`DeviceDriver` has two production implementations: `sidecar` (Maestro gRPC, for native) and `chrome` (CDP, for web), plus a `mock` for tests. The runner never knows which is wired in. Adding a new platform means adding a new implementation; nothing else changes. +`DeviceDriver` has two production implementations: `sidecar` (gRPC to the native sidecar) and `chrome` (CDP, for web), plus a `mock` for tests. The runner never knows which is wired in. Adding a new platform means adding a new implementation; nothing else changes. -## 4. Hot loops bypass Maestro (native) +## 4. Hot loops bypass the sidecar (native) -On native, per-step introspection (hierarchy dump, coverage read, pause and resume) goes over a local Unix socket directly to the SDK. Only physical UI events go through Maestro's gRPC. +On native, per-step introspection (hierarchy dump, coverage read, pause and resume) goes over a local Unix socket directly to the SDK. Only physical UI events go through the sidecar's gRPC surface. -A 30-minute run is about 10,000 steps. Every step has at least one hierarchy dump and one coverage read. If those went through Maestro, the JVM sidecar would be the bottleneck. Instead the hot path is a 2 ms round-trip to an in-process Swift or Kotlin SDK. +A 30-minute run is about 10,000 steps. Every step has at least one hierarchy dump and one coverage read. If those went through the JVM sidecar, the JVM hop would be the bottleneck. Instead the hot path is a 2 ms round-trip to an in-process Swift or Kotlin SDK. On web, CDP is fast enough that a separate introspection channel is not needed.