Skip to main content

Crate smix_runner_wire

Crate smix_runner_wire 

Source
Expand description

§smix-runner-wire

Crates.io docs.rs License

Pure-serde wire request/response types for the SmixRunnerCore HTTP IPC (18 endpoints). Zero HTTP / async / I/O dependencies — pairs with smix-runner-client (the reqwest+tokio client) but stands alone so consumers can drive their own sync/custom transport or serve the same wire contract from a different backend.

§Quickstart

use smix_runner_wire::{IncludeScope, RunnerIncludeOpts, TapMode, TapRequest, TapResult};
use smix_selector::{Pattern, Selector, Modifiers};

let req = TapRequest {
    selector: Selector::Text {
        text: Pattern::text("Login"),
        modifiers: Modifiers::default(),
    },
    mode: TapMode::Resolve,
};
let body = serde_json::to_string(&req).unwrap();
assert!(body.contains("\"mode\":\"resolve\""));

let inc = RunnerIncludeOpts { include: Some(IncludeScope::AllWindows) };
let q = inc.include.unwrap().query_value();
assert_eq!(q, "all-windows");

let example_resp = r#"{
  "stages": { "resolveMs": 12.3, "tapCallMs": 4.5, "totalMs": 17.1,
               "waitExistenceMs": 0.0, "frameReadMs": 0.7 },
  "frame": { "x": 50.0, "y": 100.0, "w": 200.0, "h": 40.0 },
  "appFrame": { "x": 0.0, "y": 0.0, "w": 390.0, "h": 844.0 }
}"#;
let parsed: TapResult = serde_json::from_str(example_resp).unwrap();
assert_eq!(parsed.frame.unwrap().w, 200.0);

§Route surface

18 endpoints. Request / Response types live in this crate; the client method names live in smix-runner-client:

HTTPPathRequest typeResponse type
GET/healthbare 200
GET/tree?include=…RunnerIncludeOpts (query)smix_screen::A11yNode
GET/system-popups?include=…RunnerIncludeOpts (query)Vec<SystemPopup>
POST/tapTapRequestTapResult
POST/tap-at-norm-coordTapAtNormCoordRequest{ok}
POST/findFindRequestFindResponse
POST/fill{selector, text}RunnerKeyboardResult
POST/clear{selector}RunnerKeyboardResult
POST/press-key{key}RunnerKeyboardResult
POST/scroll{selector,RunnerScrollSelector, direction}ScrollResponse
POST/swipe-once{direction}{ok}
POST/foreground{bundleId}{ok}
POST/hide-keyboard{ok}
POST/back{ok}
POST/record/start{ok}
GET/record/poll{events:[RecordedEvent]}
POST/record/stop{events:[RecordedEvent]}

All camelCase on the wire; Rust-side fields use snake_case via #[serde(rename_all = "camelCase")] or explicit #[serde(rename)].

§When to reach for this

Use casePick
Want types only, bring your own HTTP / transportsmix-runner-wire
Want a working async HTTP clientsmix-runner-client (consumes this)
Serving the wire contract from an alternate runner implementationsmix-runner-wire (single source of truth for shapes)
Need JSON Schema export (e.g. for OpenAPI)excluded by design — derive separately on the consumer side if needed

§Scope

  • ✅ Pure serde, no async, no HTTP, no schemars
  • ✅ camelCase wire compatibility with the SmixRunnerCore contract
  • RunnerTransportErrorKind discriminator enum for non-HTTP transports
  • ❌ No client implementation (use smix-runner-client)
  • ❌ No server implementation (runner side is Swift, lives outside this workspace)

§License

Dual-licensed under either:

at your option. smix-runner-wire — pure wire types for the SmixRunnerCore HTTP IPC.

Stone, zero project coupling beyond the smix-screen / smix-selector upstream types it embeds (those are themselves stones).

Pairs with smix-runner-client which provides the reqwest+tokio HTTP client; this crate is just the types so a consumer can:

  • Drive their own HTTP client (sync or async, custom transport)
  • Hand-roll a server side serving the same wire contract
  • Pin the wire-shape contract independently of the client implementation

§Route surface

18 wire endpoints (see the smix-runner-client crate for the corresponding method names):

  • GET /health — bare 200/non-200
  • GET /tree?include=…smix_screen::A11yNode
  • GET /system-popups?include=…Vec<SystemPopup>
  • POST /system-popup-action {popupId, buttonId}SystemPopupActionResponse
  • POST /tapTapResult
  • POST /tap-at-norm-coord {nx, ny} → 200/{ok}
  • POST /find {selector}{exists} or {ok}
  • POST /fill {selector, text}RunnerKeyboardResult
  • POST /clear {selector}RunnerKeyboardResult
  • POST /press-key {key}RunnerKeyboardResult
  • POST /scroll {selector, direction}{matched, swipes}
  • POST /swipe-once {direction}{ok}
  • POST /foreground {bundleId}{ok}
  • POST /hide-keyboard{ok}
  • POST /back{ok}
  • POST /record/start{ok}
  • GET /record/poll{events: [RecordedEvent]}
  • POST /record/stop{events: [RecordedEvent]}

Structs§

DiagnosticDumpResponse
POST /diagnostic/dump response body (v1.0.7 §D5).
FindRequest
POST /find request body.
FindResponse
POST /find response body.
HealthProcessInfo
v1.0.4 — pid + alive flag for a watched process. Additive to HealthResponse.
HealthResponse
Extended GET /health response body (v1.0.2 additive).
HealthTestHostInfo
v1.0.4 — xcodebuild test-host health with restart accounting.
KeyboardStages
Per-stage timing returned by /fill / /clear / /press-key.
RecordEventsResponse
GET /record/poll / POST /record/stop response body.
RecordedEvent
One recorder event captured by /record/start/record/poll flow.
RunnerIncludeOpts
include scope query param shared by /tree / /tap / /fill / /clear / /find / /scroll / /system-popups. URL-only.
RunnerKeyboardResult
POST /fill / POST /clear / POST /press-key response body.
ScrollResponse
POST /scroll response body.
SessionAppLifecycleRequest
v1.0.8 §D1 — request body shared by POST /session/terminate-app and POST /session/launch-app. Both endpoints take just the session id.
SessionAppLifecycleResponse
v1.0.8 §D1 — response for POST /session/terminate-app and POST /session/launch-app. Runner reports wall time for observability; the whole point of splitting terminate + launch from /session/relaunch-app is to let the SDK insert a host-side SimctlClient::clear_app_sandbox call between them, eliminating the “Insight quit unexpectedly” ReportCrash dialog that even v1.0.4 §D12’s in-place simctl wipe still tripped.
SessionCloseAllResponse
POST /session/close-all — v1.0.4 §D5 support for smix runner cycle. Runner-side clears every open session and returns the count that was cleared.
SessionCloseRequest
POST /session/close request body.
SessionCloseResponse
POST /session/close response body.
SessionListResponse
POST /session/list response body (v1.0.5 §D1).
SessionOpenRequest
POST /session/open request body.
SessionOpenResponse
POST /session/open response body.
SessionRelaunchAppRequest
POST /session/relaunch-app request body (v1.0.4 §D14).
SessionRelaunchAppResponse
POST /session/relaunch-app response body.
SessionRenewActivationRequest
POST /session/renew-activation request body.
SessionRenewActivationResponse
POST /session/renew-activation response body.
SessionSummary
v1.0.5 §D1 — one entry in POST /session/list response.
SubprocessRecord
v1.0.7 §D3 — one entry in the subprocess ring buffer.
SystemPopup
One system-popup discovered on the screen (alert / sheet / banner).
SystemPopupActionRequest
POST /system-popup-action request body (v4.2 c2 — G9 act side).
SystemPopupActionResponse
POST /system-popup-action response body.
SystemPopupButton
One button on a SystemPopup.
SystemPopupsResponse
GET /system-popups response body.
TapAtNormCoordRequest
POST /tap-at-norm-coord request body.
TapRequest
POST /tap request body.
TapResult
POST /tap response body.
TapStages
POST /tap per-stage timing in milliseconds.

Enums§

IncludeScope
include scope literal — currently only all-windows (system popups pierce the app frame).
RunnerScrollSelector
Reduced selector shape used by /scroll (text-or-id only; complex selectors are host-side-resolved before reaching the runner).
RunnerTransportErrorKind
Transport-level failure variants exposed by the HTTP client. The concrete reqwest::Error source lives in smix-runner-client; the wire stone exposes only the discriminator + endpoint context so non-HTTP transports can reuse the variants.
SimHealthWireState
v1.0.4 §D7 — Session state exposed to SDK consumers via the X-Sim-Health response header on every runner response.
TapMode
POST /tap mode discriminator.