Files
callstack__agent-device/ios-runner/RUNNER_PROTOCOL.md
Michał Pierzchała 3df1e145b4 docs: fix stale platforms/ios paths after the Apple consolidation (#968) (#969)
Post-#968 follow-up: the OS-agnostic Apple runner engine moved from
src/platforms/ios/ to src/platforms/apple/core/, but several docs/config still
pointed at the old locations, misleading agents that grep those paths.

- AGENTS.md: repoint the runner-seam map, the Apple-family sync rule, the
  record/trace seam, the search-roots hint, and the platform-backends list at
  src/platforms/apple/core/...; rename "iOS Runner Seams" -> "Apple Runner Seams".
- .fallowrc.json: drop the two stale ignoreExports entries for the removed
  src/platforms/ios/apps.ts and src/platforms/ios/index.ts (the live
  src/platforms/apple/core/apps.ts entry already covers those test-only exports).
- ios-runner/{README,RUNNER_PROTOCOL}.md: point the TypeScript-client links at
  src/platforms/apple/core/runner/runner-client.ts.

Docs/config only; no behavior change. fallow audit + build/lint stay green, and a
live iOS simulator replay suite (6/6) confirms the consolidated runner works.
2026-07-01 07:24:22 +02:00

2.1 KiB

iOS Runner Protocol

The Apple runner speaks a small internal HTTP+JSON protocol between the TypeScript daemon and the XCUITest host. This protocol is a maintainer document, not part of the public user docs, but it should stay explicit so the TypeScript and Swift sides do not drift.

Transport

  • Endpoint: POST /command
  • Content type: application/json
  • Request body: one JSON command object
  • Response body: one JSON envelope

The daemon probes http://127.0.0.1:<port>/command for simulator and desktop flows, and can use a tunneled device address for physical iOS/tvOS devices before falling back to localhost.

Request Shape

Every request includes a command field. Additional fields depend on the command family.

Examples:

{ "command": "tap", "x": 120, "y": 240 }
{
  "command": "snapshot",
  "interactiveOnly": true,
  "depth": 2,
  "scope": "app",
  "raw": false
}
{ "command": "recordStart", "outPath": "/tmp/demo.mp4", "fps": 30, "maxSize": 720 }
{ "command": "rotate", "orientation": "landscape-left" }

The current command names are defined in:

Response Shape

Successful and failed responses use the same top-level envelope:

{
  "ok": true,
  "data": {
    "message": "ok"
  }
}
{
  "ok": false,
  "error": {
    "code": "UNSUPPORTED_OPERATION",
    "message": "Unable to dismiss the iOS keyboard without a safe native dismiss control"
  }
}

data is command-specific. Common fields include snapshot nodes, text lookup results, gesture timing, visibility metadata, and screenshot or recording output details.

Maintenance Rules

  • Treat the TypeScript and Swift wire models as a single contract.
  • When adding, removing, or renaming a command, update the protocol fixtures/tests in the same change.
  • Keep this file focused on the actual wire shape rather than implementation details of command execution.