Description
The fallback path introduced in #130 for physical iOS device screenshots is broken. When xcrun devicectl device screenshot fails (e.g. on Xcode 26.x), the code falls back to:
await runIosRunnerCommand(device, { command: 'screenshot', outPath });
The `outPath` here is the Mac output path (e.g. `/tmp/screenshot.png`). The Swift runner receives this and tries to write directly to that path on the iOS device:
try screenshot.pngRepresentation.write(to: URL(fileURLWithPath: requestedOutPath))
Since `/tmp` is not a writable path in an iOS app sandbox, this always fails with:
Error (COMMAND_FAILED): failed to write screenshot: You don't have permission to save the file "screenshot.png" in the folder "tmp".
Steps to Reproduce
agent-device open MyApp --platform ios # physical device, Xcode 26.x
agent-device screenshot /tmp/output.png
Expected Behavior
Screenshot is saved to /tmp/output.png on the Mac.
Actual Behavior
Error (COMMAND_FAILED): failed to write screenshot: You don't have permission to save the file "output.png" in the folder "tmp".
Fix
The Swift runner should write to `NSTemporaryDirectory()` (which is writable) and return the device-local file path. The TypeScript daemon should then pull the file to the Mac using `xcrun devicectl device copy from` — the same pattern already used by the recording feature.
Environment
Description
The fallback path introduced in #130 for physical iOS device screenshots is broken. When
xcrun devicectl device screenshotfails (e.g. on Xcode 26.x), the code falls back to:The `outPath` here is the Mac output path (e.g. `/tmp/screenshot.png`). The Swift runner receives this and tries to write directly to that path on the iOS device:
Since `/tmp` is not a writable path in an iOS app sandbox, this always fails with:
Steps to Reproduce
agent-device open MyApp --platform ios # physical device, Xcode 26.x agent-device screenshot /tmp/output.pngExpected Behavior
Screenshot is saved to
/tmp/output.pngon the Mac.Actual Behavior
Fix
The Swift runner should write to `NSTemporaryDirectory()` (which is writable) and return the device-local file path. The TypeScript daemon should then pull the file to the Mac using `xcrun devicectl device copy from` — the same pattern already used by the recording feature.
Environment