219 Commits

Author SHA1 Message Date
Michał Pierzchała c3fb690acb 0.7.15 v0.7.15 2026-03-12 12:29:10 +01:00
Michał Pierzchała 3bb5e6c6a8 fix: prevent APK file paths from being used as package names in adb run-as (#204)
resolveAndroidApp treated any input containing a dot as a package name,
which caused APK file paths (e.g. /path/to/app-debug.apk) to flow through
as appId into runtime hints, failing with a misleading "app not debuggable"
diagnosis. Android package names never contain slashes, so exclude paths
with '/' from the dot-based package heuristic.

Also differentiate probe failures in writeAndroidDevPrefs: check
isAndroidRunAsDeniedOutput on the probe result so connectivity/transport
errors are not misattributed to debuggability.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:28:22 +01:00
Michał Pierzchała 3847958067 fix: serve artifact downloads at /upload/{id} to fix proxy 404 (#205)
The artifact download endpoint was at GET /artifacts/{id}, but proxies
in the sandbox → proxy → daemon architecture only forward known paths
(/rpc, /health, /upload). Move downloads to GET /upload/{id} so they
share the already-forwarded /upload path (POST for uploads, GET for
downloads).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:28:11 +01:00
Michał Pierzchała 2522984aa9 0.7.14 v0.7.14 2026-03-11 16:11:08 +01:00
Michał Pierzchała ee7f81b8ab fix: write android runtime hints via stdin (#203) 2026-03-11 16:10:57 +01:00
Michał Pierzchała 55d69f7729 0.7.13 v0.7.13 2026-03-11 14:56:43 +01:00
Michał Pierzchała 3763772734 fix: clarify android runtime hint failures (#202) 2026-03-11 14:56:15 +01:00
Michał Pierzchała f23df4d9c8 docs: add missing command reference entries (#201)
* docs: add missing command reference entries

* docs: clarify wait ref behavior
2026-03-10 12:59:36 +01:00
Michał Pierzchała e2bf4ef7a1 docs: add missing command reference entries (#200) 2026-03-10 12:29:05 +01:00
Michał Pierzchała 63d9f0021c refactor: extract daemon orchestration into dedicated modules (#160) (#198)
Restore src/daemon.ts to thin-router entrypoint by extracting:
- server-lifecycle.ts: lock/info file management, code signature, env parsing
- request-router.ts: request dispatch orchestration across handlers
- transport.ts: socket server, listen helpers, disconnect/abort logic

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 10:27:17 +01:00
Michał Pierzchała 12d54989b3 0.7.12 v0.7.12 2026-03-09 19:50:59 +01:00
Michał Pierzchała 8b36c2a56c feat: support remote runtime hints and artifact retrieval (#199)
* feat: add remote runtime hints and artifact retrieval

* fix: apply session runtime transport hints on open

* fix: secure and time out artifact downloads
2026-03-09 19:50:40 +01:00
Michał Pierzchała 150399ec0c 0.7.11 v0.7.11 2026-03-09 17:35:07 +01:00
Michał Pierzchała a463106eea fix: avoid canceling active HTTP RPC requests (#196) 2026-03-09 17:34:52 +01:00
Michał Pierzchała 51158c56ce 0.7.10 v0.7.10 2026-03-09 16:37:53 +01:00
Michał Pierzchała 4a22da9e4b fix: propagate AbortSignal on cancellation to stop iOS runner promptly (#194)
* fix: propagate AbortSignal on request cancellation to stop iOS runner promptly

When a client disconnects (socket close or HTTP connection drop), in-flight
iOS runner operations now receive an AbortSignal that immediately interrupts
pending HTTP fetches, retry delays, and retry loops—ensuring detached
xcodebuild/runner processes are not driven after the parent workflow is canceled.

Closes #193

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: ensure HTTP disconnect cancellation always propagates

* fix: rethrow canceled runner waits before fallback

* fix: harden cancellation tracking and propagation

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:37:22 +01:00
Michał Pierzchała 780ecbc7a4 feat: support installing local artifacts over remote daemon transport (#192)
* feat: support installing local artifacts over remote daemon transport

When the CLI runs on a different machine than the daemon (via
AGENT_DEVICE_DAEMON_BASE_URL), install/reinstall commands now
transparently upload local app binaries (.apk/.ipa/.aab) and app
bundles (.app dirs) to the daemon before installing. No new flags
required — same CLI ergonomics.

- Add POST /upload endpoint to daemon HTTP server with auth and
  streaming file/tar reception
- Add client-side upload helper with timeout and tar packing for
  .app directories
- Intercept install/reinstall in sendToDaemon for remote daemons,
  upload artifact, rewrite positional path
- Clean up uploaded temp files after install completes (or fails)
  with 5-minute safety-net auto-cleanup for abandoned uploads
- Sanitize artifact filenames to prevent path traversal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden remote artifact upload flow

* refactor: split upload registry from receiver

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:10:31 +01:00
Jonathan Sweet 21b6b61757 test: add unit tests for dispatch-series helper functions (#190)
* test(dispatch-series): add comprehensive unit tests for helper functions

* test(dispatch-series): mock setTimeout instead of measuring elapsed time
2026-03-06 17:06:02 +01:00
Michał Pierzchała 151f36bf34 0.7.9 v0.7.9 2026-03-06 15:40:43 +01:00
Muhammad Mugni Hadi b79bd86017 fix: remove trailing commas in Swift for Xcode <16.3 compatibility (#186)
* fix: remove trailing commas in Swift for Xcode <16.3 compatibility

Remove trailing commas from function/initializer argument lists in the
iOS XCUITest runner Swift source files. SE-0439 trailing commas in
comma-separated lists require Swift 6.1+ (Xcode 16.3+), but the runner
is compiled locally by users who may have older Xcode versions.

Users with Xcode 16.2 (Swift 6.0.3) encounter build failures:
  error: unexpected ',' separator

This causes the runner to never start, surfacing as:
  Error (COMMAND_FAILED): Runner did not accept connection (simctl spawn)

Files fixed (12 trailing commas removed):
- RunnerTests+Snapshot.swift (5)
- RunnerTests+Transport.swift (2)
- RunnerTests+CommandExecution.swift (1)
- RunnerTests+ScreenRecorder.swift (2)
- RunnerTests.swift (2)

Verified: pnpm build:xcuitest passes (TEST BUILD SUCCEEDED).

* ci: guard iOS runner trailing-comma syntax

---------

Co-authored-by: Michał Pierzchała <thymikee@gmail.com>
2026-03-06 15:40:18 +01:00
Michał Pierzchała 3bafc24f05 fix: support explicit remote daemon endpoints (#189)
* fix: support remote daemon base url

* fix: harden remote daemon endpoint handling

* docs: update remote daemon skill guidance
2026-03-06 15:40:06 +01:00
Michał Pierzchała 9ca4e07feb chore: tighten ios screenshot fallback diagnostics 2026-03-06 14:02:58 +01:00
Michał Pierzchała 1d875bacdc fix: harden ios screenshot fallback timeouts 2026-03-06 14:01:00 +01:00
Michał Pierzchała 4df80afbc5 fix: strip pre-PNG garbage from Android screenshots on multi-display devices (#185)
* fix: strip pre-PNG garbage from Android screenshots on multi-display devices

On Android emulators with multiple displays (e.g. Galaxy Z Fold), `adb
exec-out screencap -p` writes a warning to stdout before the PNG data,
producing corrupt files.  Locate the PNG signature in the buffer and
discard everything before it.

https://claude.ai/code/session_01Lfb3WKqXCSqYtCg8dbS8JW

* refactor: simplify PNG stripping and test scripts

- Remove unnecessary ternary; subarray(0) is a no-op
- Replace hex-encoded printf mock scripts with file-based payloads

https://claude.ai/code/session_01Lfb3WKqXCSqYtCg8dbS8JW

* fix: trim Android screenshot output to complete PNG payload

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-04 10:10:47 +01:00
Michał Pierzchała e248c87634 test: lock find click JSON response to exact deterministic key set (#183)
Add strict key-set assertions to find click handler tests to prevent
accidental schema drift in the machine-consumed JSON response.

Closes #182

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 20:28:10 +01:00
Michał Pierzchała 22deb54ddb feat: add --shutdown option to close command for iOS simulator teardown (#176)
* feat: add --shutdown option to close command for iOS simulator teardown (#172)

When --shutdown is passed, close ends the session then runs xcrun simctl
shutdown on the associated simulator. Shutdown result (success, exitCode,
stdout, stderr) is included in the JSON response data.

The option is silently ignored for non-simulator targets (physical iOS
devices, Android). A shutdownSimulator override is injected into
handleSessionCommands for testability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: document close --shutdown option for iOS simulator teardown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: keep close --shutdown successful when simulator shutdown fails

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 20:00:10 +01:00
Michał Pierzchała bb06bafc65 feat: add ensure-simulator command for scoped iOS device sets (#179)
* feat: add ensure-simulator command for scoped iOS device sets (#169)

Adds a new first-class `ensure-simulator` command that ensures an iOS
simulator exists (and optionally boots it) inside a scoped device set,
without requiring custom simctl scripting outside agent-device.

Usage:
  agent-device ensure-simulator --device "iPhone 16" [--runtime <id>] [--boot] [--ios-simulator-device-set <path>]

JSON output includes udid, device, runtime, ios_simulator_device_set,
and whether the simulator was created vs reused.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: document ensure-simulator in commands reference and skill

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 19:39:52 +01:00
Michał Pierzchała 427093d0b0 fix: return deterministic matched-target metadata for find click responses (#178)
* fix: return deterministic matched-target metadata for find click responses (#170)

On success, build the response from the matched snapshot node rather than
passing through whatever the underlying click/press handler returns.
Response now includes: ref, locator, query, and x/y derived from the
matched element's rect — all stable across runs.

Also makes `dispatch` injectable in `handleFindCommands` (matching the
pattern in `handleInteractionCommands`) and adds tests that assert the
deterministic shape and verify that non-deterministic platform runner
data does not bleed into the response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: document find click response shape in selectors and skill references

Add response shape documentation for `find "<query>" click --json` to:
- website/docs/docs/selectors.md (new "Response shape (click)" section)
- skills/agent-device/SKILL.md (guardrail note)
- skills/agent-device/references/snapshot-refs.md (new "find click response" section)

Follows the fix in #178 that made the response deterministic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 19:39:31 +01:00
Michał Pierzchała 8d4c9149a6 fix: retry alert accept/dismiss on transient 'alert not found' errors (#177)
* fix: retry alert accept/dismiss on transient 'alert not found' errors

Adds a 2 s internal retry window for `alert accept` and `alert dismiss`
when the runner returns "alert not found" or "no alert". Errors from
other causes break the loop immediately and are re-thrown unchanged.
Also injects `runnerCommand` as an optional param to enable unit testing
without spawning a real runner.

Closes #171

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: document alert accept/dismiss retry behaviour in skill and permissions reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 19:39:22 +01:00
Michał Pierzchała 43cb8cdb5d fix: enrich DEVICE_NOT_FOUND error for empty scoped iOS simulator sets (#175)
* fix: enrich DEVICE_NOT_FOUND error for empty scoped iOS simulator sets (#168)

When selectDevice finds no candidates and a simulatorSetPath context is
provided for iOS, throw a detailed error including the set path and a
suggested xcrun simctl --set ... create command to provision the first
simulator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: note enriched DEVICE_NOT_FOUND guidance for empty scoped iOS simulator sets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 19:37:58 +01:00
Michał Pierzchała a51f8193f2 feat: include device_udid and ios_simulator_device_set in iOS JSON payloads (#180)
Add device identity fields to open, appstate, and session_list responses
for iOS targets, enabling isolation verification in concurrent multi-session
runs without extra simctl calls.

Closes #173

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 19:36:01 +01:00
Michał Pierzchała 5f941c13f6 refactor: split app-log backend into process/stream/platform modules (#161) (#174)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 18:46:22 +01:00
Michał Pierzchała 5628693aa3 fix: stabilize iOS simulator screenshot capture (#167)
* fix: stabilize iOS simulator screenshot capture

* refactor: extract iOS screenshot module

* fix: fallback to runner for flaky iOS simulator screenshots

* chore: harden simulator runner screenshot path resolution

* refactor: simplify simulator screenshot fallback flow
2026-03-03 18:15:49 +01:00
Michał Pierzchała d269da37e3 refactor: split dispatch into command-family modules (#157) (#164)
Extract resolveTargetDevice, series/jitter helpers, and push payload
parsing into dedicated modules to reduce dispatch.ts from ~706 to ~564 LOC.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 18:11:14 +01:00
Michał Pierzchała c6910823df fix: harden daemon startup retries (#166) 2026-03-03 17:21:43 +01:00
Michał Pierzchała d38ddc6bb0 refactor: split iOS runner-client into focused modules (#163)
Break the 1129-LOC runner-client.ts into cohesive modules:
- runner-errors.ts: error classification, hints, error builders
- runner-xctestrun.ts: xctestrun discovery, build, preparation, build settings
- runner-transport.ts: HTTP transport, endpoint resolution, connection waiting
- runner-session.ts: session lifecycle, process management, device validation
- runner-client.ts: thin orchestration + re-exports (preserves all public API)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:44:11 +01:00
Michał Pierzchała b6b7c6228a refactor: split session replay helpers into focused modules (#153) 2026-03-03 14:41:35 +01:00
Michał Pierzchała 1a3ae62510 refactor: split Android platform module into focused submodules (#162)
Break down the monolithic `src/platforms/android/index.ts` (~1533 LOC) into
focused submodules to improve maintainability and targeted code review.

New submodules:
- `adb.ts` (21 LOC) — shared helpers: adbArgs, ensureAdb, sleep, isClipboardShellUnsupported
- `app-lifecycle.ts` (507 LOC) — app resolve/list/open/close/install/reinstall/appstate + bundletool
- `input-actions.ts` (378 LOC) — press/swipe/longPress/type/fill/scroll/scrollIntoView
- `device-input-state.ts` (184 LOC) — keyboard state/dismiss + clipboard read/write
- `settings.ts` (314 LOC) — appearance/permission/fingerprint/wifi/airplane/location
- `notifications.ts` (61 LOC) — push notification broadcast
- `snapshot.ts` (98 LOC) — snapshot + screenshot + UI hierarchy dump
- `index.ts` (43 LOC) — thin re-export layer preserving all public exports

Closes #154

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:41:10 +01:00
Michał Pierzchała 674a221865 0.7.6 v0.7.6 2026-03-03 14:14:47 +01:00
Michał Pierzchała 9b0a3dee6e feat: add install command with ipa/aab support (#151)
* feat: add install command for in-place app deployment

* chore: document install vs reinstall in quick start and skill

* docs: clarify install format support and limits

* feat: support ipa and aab app installation

* feat: improve install flexibility for ipa and aab

* fix: retry iOS simulator screenshot surface timeouts

* refactor: simplify install resolution and boot handling
2026-03-03 14:14:23 +01:00
Michał Pierzchała 6c78472420 fix: harden iOS relaunch/close lifecycle to reduce simulator flakes (#152)
* fix: harden iOS relaunch and close runner lifecycle

* refactor: dedupe iOS relaunch close flow and tighten tests
2026-03-03 14:00:14 +01:00
Michał Pierzchała 83b757d883 fix: quote dogfood skill YAML description 2026-03-02 09:36:55 +01:00
Michał Pierzchała e44eeab976 0.7.5 v0.7.5 2026-02-28 14:15:07 +01:00
Michał Pierzchała 8c30032ae4 perf: speed up iOS runner build-for-testing (#150)
* perf: speed up runner build-for-testing

* chore: drop redundant active-arch runner override

* test: run iOS simulator integration on CI by default
2026-02-28 14:13:39 +01:00
Michał Pierzchała 9b443c526f refactor: split RunnerTests into focused files (#149)
* refactor: split RunnerTests into focused files

* chore: remove dead interaction label helper
2026-02-28 13:38:59 +01:00
Michał Pierzchała 97f59254bb fix: make snapshot --raw use target app tree on physical iOS (#148)
* fix: use snapshots for raw iOS tree traversal

Fixes #147

* refactor: unify snapshot hittable computation across modes

* refactor: account for cousin occlusion in hittable

* refactor: tighten snapshot occlusion heuristic
2026-02-28 12:55:41 +01:00
Michał Pierzchała 33d918d0f3 chore: cleanup old bundleIDs 2026-02-26 16:48:16 +01:00
Michał Pierzchała e248bf38c0 0.7.4 v0.7.4 2026-02-26 16:40:51 +01:00
Michał Pierzchała 14de55c9b7 fix: support configurable iOS runner bundle IDs (#146) 2026-02-26 16:40:24 +01:00
Michał Pierzchała ed5dd7bc28 0.7.3 v0.7.3 2026-02-26 11:48:55 +01:00