Skip to content

Changelog

[v0.0.53] - 2026-08-11

Fixed

  • bug(android): preserve Android emulator launch diagnostics on early exit (#5209) (android, ci)

[v0.0.52] - 2026-08-10

Other

  • fix(android): support unit-suffixed AVD RAM settings (#5194)

[v0.0.51] - 2026-08-09

Added

  • feat(dx): add a fail-fast validate-loop pre-push command (loop) (#5149)
  • perf(build): cache typecheck as a turbo task + fix diff-based check:host-shell-boundary caching (#5124)
  • perf(lint): parallel boundary-check runner + prefilters + close local/CI parity (#5121)
  • perfSnapshot windowing refinements: prime first gfxinfo sample + jank boundary interval (#5110) (android, performance)
  • Define and prove macOS host contract for managed iOS simulator continuity (#5104) (ios, release engineering, testing)
  • Benchmark observe perfSnapshot overhead + window sizing under fast heavy-screen navigation (#5077) (performance, testing)
  • Android SDK: on-device FrameMetrics/JankStats feed for observe perfSnapshot (replace host dumpsys) (#5076) (android, performance)
  • Observe: co-scope layoutWarnings with the returned hierarchy under –observe-region/focus/overview (#5074)
  • feat(android): capture and control outbound WebSocket frames (#5066) (android, blocked)
  • feat(android): add transport-neutral network capture API (#5068) (android, blocked)
  • feat(android): add UI observation and control hooks (#5067) (android, a11y, blocked)
  • feat(android): add application-provided storage driver hooks (#5065) (android, blocked, database)
  • feat(android): add lifecycle and runtime context hooks to the SDK (#5064) (android, blocked)
  • feat(android): expose SDK capability discovery and policy control (#5063) (android, devxp)
  • Add deterministic fault injection across iOS transports (#5062) (ios)
  • Add complete UIKit and SwiftUI navigation lifecycle coverage (#5060) (ios)
  • Define a first-class iOS observation and control bridge (#5059) (ios)
  • Add a supported WKWebView observation and control bridge (#5058) (ios)
  • Expand iOS network capture beyond URLProtocol (#5057) (ios)
  • Desktop lock-state feed: iOS keyguard detection + a lighter dedicated lock query (#5056) (desktop)
  • Desktop workspace: locale + more emulator controls (deferred from #4690/#4694) (#5055) (desktop)
  • perf(test): add test:fast (bun test –parallel) for a ~9x-faster local test loop (#5033)
  • nav (app,build) Phase 1: provenance schema — build-key + per-node/edge observation records (#4984) (database)
  • Desktop: LayoutFacet needs a reconnect lifecycle (injectable timer/stream seam) (#4868) (desktop)
  • Desktop Logs tail-follow: clear follow intent on upward scroll start (not just settle) (#4849) (desktop)
  • Desktop Logs filter: iOS level bucketing is ambiguous across SDK vs OSLogReader sources (needs per-row source tag) (#4847) (desktop)
  • Desktop workspace: per-device facet infrastructure (ObservationStreamClient interface + deviceId-scoped daemon resources) (#4715) (desktop)
  • Desktop workspace: enable Storage facet for iOS panes (fix key-value mutation routing) (#4708) (ios, desktop)
  • Desktop workspace: telemetry-event selection + detail in the Logs facet (#4705) (desktop)
  • Desktop workspace: execute emulator-control intents against the real device (rotate/screenshot/snapshot/unlock) (#4694) (desktop)
  • feat(ios): network — simulate network errors (http500/timeout/connectionRefused/dnsFailure/tlsFailure) (#2499) (ios)

Changed

  • chore(dx): self-heal node_modules in fresh worktrees before local validation (#5051)
  • chore(build): remove the no-op iOS-assets build step from build.ts (#5039)
  • chore: align package.json Bun pin to 1.3.9 to match CI (#5026)
  • CtrlProxy: exclude a11y screenshot rate-limits from the 3-strike ‘unsupported’ counter (#4997) (android)
  • Re-cut the Android CtrlProxy APK + bump checksum so ctrlproxy_rate_limited ships (follow-up to #4927/#4995) (#4996) (android)

Fixed

  • Android database policy allows writable PRAGMAs after revocation (#5184)
  • Android database policy bypass for custom DatabaseDriver SQL (#5183)
  • Android database policy allows mutating SQL with RETURNING (#5182)
  • Android sqlQuery rejects read-only SELECTs as MutationNotAllowed — operator-precedence bug in DatabaseInspectorProvider guard (exposed by #5166) (#5180)
  • sqlQuery broken on Android API 35: inspector ContentProviders are exported=false, content call denied (opaque “Database error (UNKNOWN)”) (#5165)
  • Android crayon primitive: sample each seam once + clamp segmentsPerEdge (parity with #5119) (#5122)
  • PerformanceMonitor: Android CPU% is cumulative/uptime-averaged, not interval-based (#5107) (android, performance)
  • Investigate and prevent Bun 1.3.9 Windows segmentation faults in CI (#5079) (ci, dependencies, javascript)
  • Prepare Release 0.0.50 failed: bump-versions docs sync tripped the versioned-tree allow-list (#5008) (ci)
  • Android CtrlProxy: a11y screenshots rate-limit into ADB fallover during animations (misclassified as ctrlproxy_failed) (#4927) (android, performance)

Security

  • Expand and harden iOS storage inspection (#5061) (enhancement, ios, database)

Other

  • Android database policy permits parenthesized writable PRAGMAs (#5186)
  • Android database policy rejects read-only SQL with leading comments (#5185)
  • test(shared): property-test MetricsUtils median/mode/weighted-average invariants (#5178) (testing)
  • test(webrtc): property-test trickle-ICE serialize/parse round-trip (#5176) (testing)
  • test(utils): property-test combineApkDigests line-order invariance (#5174) (testing)
  • test(daemon): property-test roundHalfAwayFromZero tie-boundary invariants (#5171) (testing)
  • iOS Playground registers no inspectable database — iOS sqlQuery/db-inspection has no e2e coverage (Android has sessions.db) (#5167)
  • test(server): property-test normalizeAppFileRelativePath path-traversal guard (#5145) (testing)
  • feat(playground/ios): hand-drawn crayon outline primitive + apply to bordered surfaces (#5116)
  • Desktop workspace: thread device kind (isVirtual) into DeviceColumn to gate iOS-physical Locale/Power (#5112) (desktop)
  • Desktop emulator controls: surface tool-level success:false from DaemonEmulatorControlExecutor (#5111) (desktop)
  • feat(playground/ios): mirror crayon design tokens + Shantell Sans (iOS foundation) (#5081)
  • chore(ios): remove phantom ios/AccessibilityService and ios/AXeAutomation references from build tooling (#5080) (ios)
  • feat(playground/android): icon-derived crayon design tokens + Shantell Sans + hand-drawn shapes (#5048)
  • feat(video-server): emit periodic VIDEO_STATS line (fps/bytes/dropped) for stream-health observability (#5043) (android)
  • fix(video-server): request a recovery IDR when FrameHandoff drops a frame (avoid up to 5s of corruption) (#5042) (android)
  • refactor(video-server): share one SAFE_TOKEN regex between VideoHandshake and VideoSessionArguments (#5041) (android)
  • build(video-server): pass –release to d8Dex to strip debug dex info from the pushed jar (#5040) (android)
  • build(android): fix junit-runner cross-project layout access + signing convention (#5030)
  • build(android): enable Gradle Isolated Projects for local builds (#5031)
  • build(android): de-cross-project group/version + maven-publish/centralManifest (#5029)
  • build(android): detekt + test/coverage conventions; add maxParallelForks (#5028)
  • build(android): scaffold build-logic + extract Kotlin-compile convention (#5027)
  • perf(ios): pin local simulator builds to arm64 + disable index store to ~halve local iOS build time (#5024) (ios, performance)

[v0.0.50] - 2026-08-03

Other

  • Keep release-versioned documentation synchronized during prepare-release (#5006)
  • bug(sqlite): recover partially applied video-recordings owner-session migration (#5004)

[v0.0.49] - 2026-08-03

Added

  • macOS DMG: staple the notarization ticket to AutoMobile.app, not only the DMG (offline first-launch) (#4955) (release engineering)
  • iOS WebRTC: in-helper encode for the physical-device capture path (AVFoundation 420v) (#4790) (ios, performance, webrtc)
  • iOS WebRTC: consume in-helper encoded H.264 in IosH264Source (no ffmpeg on the encoded path) (#4789) (ios, performance, webrtc)
  • iOS screen-capture helper: 420v capture + VTCompressionSession H.264 encode behind –encode h264 (#4788) (ios, performance, webrtc)
  • iOS WebRTC wire protocol: encoded H.264 record kind + helper capability handshake (#4787) (ios, performance, webrtc)
  • video-stream protocol: attest display rotation end-to-end (populate LiveVideoFrame.rotation) (#4786) (android, video, webrtc)
  • video-server: recreate capture/encoder on device rotation (fix mid-stream distortion) (#4785) (android, video, webrtc)
  • perf(android-video): move H.264 encoder off Constrained Baseline to Main/High profile (#4756) (android, performance, video, webrtc)
  • eventOnly fresh-focus: harden getDeviceTimestampMs degraded modes (lenient %3N parse / second truncation / host-timer fallback) (#4720)
  • Client Screen Control: input forwarding (parent) (#1099) (android, ios)

Changed

  • Upgrade execution-boundary lint guards from regex to AST-based detection (#4830)

Fixed

  • Android: resolve custom AVD registry paths before RAM validation (#4993) (android)
  • Android: keep transient offline emulator states within readiness deadline (#4992) (android)
  • XCTestRunner Simulator Tests red on every PR since #4934: daemon reads new secure derived-data path while CI builds CtrlProxy iOS into /tmp/automobile-ctrl-proxy (#4966) (ios, ci)
  • bug(ios): tolerate bootstatus error 405 when the requested simulator is already Booted (#4958) (ios)
  • iOS codesign warn-gate log line ends with stray undefined (IOSCtrlProxyBuilder) (#4954) (ios)
  • main red: WebRTC Publisher Integration (MediaMTX) broken by #4877 (H.264 encoder → Main profile) (#4882) (webrtc)
  • release: verify published GitHub Release assets against the checksum registry (digest-based audit) (#4685) (ci, release engineering)
  • 0.0.46 published with assets that mismatch the pinned checksums: client hard-fails runner provisioning (#4672) (ci, release engineering)

Security

  • [security] Low-severity capture hardening: audio over-read, INFO path logging, resource-path confinement, overflow arithmetic (#4765) (ios, video)
  • [security] Verify captured window belongs to the iOS Simulator at capture time (windowID reuse/TOCTOU) (#4763) (bug, ios)
  • [security] Video recording retention: add TTL, cap in-progress size, document secure-delete (#4762) (enhancement, video)
  • [security] Close iOS helper download integrity bypasses (cached-fallback verify, http:// base URL, device-runner hash) (#4761) (bug, ios, release engineering)
  • [security] Add codesign/notarization gate before launching the downloaded iOS helper (#4760) (enhancement, ios, release engineering)

Other

  • Test: inject AVD config fakes into mocked emulator launch tests (#4994) (android, testing)
  • Make managed-device sessions and recovery explicit (#4979)
  • Emulator boot failures collapse into a generic 120s timeout — add detectors for mprotect/HVF, stuck-offline, tiny-RAM AVDs, and outdated cmdline-tools (#4974)
  • Desktop WebRTC client: send sessionUuid so it works with #4751 stream-socket auth (on by default) (#4924) (android, webrtc)
  • daemon: propagate on-demand navigation-graph export failures through the stream (currently swallowed to null) (#4918)
  • Re-cut the screen-capture-helper release asset to ship merged Swift fixes (#4764, #4768, #4737) (#4902) (ios, release engineering)
  • research(android): reduce the Maven Central Dokka Javadoc artifact payload (#4852) (android, release engineering, research)
  • research(release): publish only Maven modules affected by a tagged release (#4850) (release engineering, research)
  • release: trigger on tag pushes only, not every branch creation (#4697) (ci, release engineering)
  • Ship the prebuilt iOS screen-capture helper as a GitHub release asset: macOS build/sign/notarize job + checksum bake (#4402) (ios, release engineering)
  • iOS: honor AUTOMOBILE_VERSION when the XCTestRunner autostarts the daemon (Swift startDaemon) (#2813) (ios, release engineering)

[v0.0.48] - 2026-08-01

Added

  • Chart daily release download counts (GitHub assets + npm) on a docs dashboard (#4890) (devxp)
  • chore(release): add a Maven Central publication manifest and usage budget preflight (#4853) (release engineering)
  • chore(ios): screen-capture streaming hardening follow-ups (#4772) (ios, webrtc)
  • Recover from on-device encoder crashes: bounded server relaunch + mid-stream screenrecord fallback (#4742) (android, webrtc)
  • perf(android-video): use VBR instead of CBR for bursty screen content (#4740) (android, performance, video)
  • perf(android-video): frame rate is preset-locked to 60fps and not plumbed end-to-end (#4739) (android, performance, video, webrtc)
  • iOS capture: replace fixed 500ms Thread.sleep in helper device startup with bounded polling (#4737) (ios, performance)
  • iOS WebRTC: stop copying a full frame per frame for lastHelperFrame (quick win) (#4735) (ios, performance, webrtc)

Changed

  • Centralize tar extraction behind a safe archive-extraction boundary (#4065) (devxp, testing)

Fixed

  • Enforce video-server reconnect-window expiry independently of the encode loop (blocked-write starvation) (#4784) (android, webrtc)
  • Reconcile hygiene for video-server leases: wall-clock fallback, unparseable/.tmp sweep, serial-vs-reboot ordering (#4783) (android, webrtc)
  • fix(ios): deterministic teardown and bounded recovery on mid-stream capture failure (#4768) (ios, webrtc)
  • Sweep orphaned adb forward entries left behind by video-server self-expiry (#4753) (android, webrtc)

Security

  • [security] Move iOS helper extraction/launch off world-writable /tmp and re-verify hash before launch (TOCTOU) (#4759) (bug, ios, release engineering)
  • [security] Session-scope the recording archive and recording/test-recording sockets (#4752) (bug, video)
  • [security] Authenticate and session-scope the video-stream and WebRTC-stream sockets (#4751) (bug, ios, webrtc)
  • [security] Harden filesystem permissions on ~/.auto-mobile, sockets, and video recordings (0o700/0o600) (#4750) (bug, ios, video)
  • Add on-device JAR hash: verify integrity before app_process launch + skip redundant push (#4733) (enhancement, android, performance, video, webrtc)
  • [security] Whitelist video-server command-channel bytes (#4732) (enhancement, android, video)
  • [security] Harden video-session lease file: restrictive perms + no cleartext token at rest (#4731) (enhancement, android, video)
  • [security] Authenticate video-server client before evicting the current one (pre-auth hijack/DoS) (#4730) (bug, android, video)
  • [security] Decouple session token from socket name and require a token handshake (#4729) (enhancement, android, video)
  • [security] Video-server LocalSocket is unauthenticated — any local app can read the screen stream (#4728) (bug, android, video)

Other

  • desktop: wire branded app icon into installers + Dock/notifications (#4920)
  • Automatic recovery when a booted Android emulator dies mid-session (#4914)
  • Desktop Navigation (Phase C): offline browse with no active device (#4911)
  • Daemon: list apps that have a persisted navigation graph (#4910)
  • Desktop Navigation (Phase C): wire as an app-sourced per-pane facet (#4909)
  • Android: installApp / uninstallApp invalidate only resource cache, so listApps can return stale packages (#4897)
  • Run the WebRTC MediaMTX publisher integration on WebRTC-touching PRs (not merge-only) (#4884) (ci, testing, webrtc)
  • Desktop picker: boot a shut-down device on click (remove the ‘Boot to observe (soon)’ dead-end) (#4879)
  • research(release): eliminate unnecessary Maven Central signature checksum artifacts (#4851) (release engineering, research)
  • perf(android-video): relax the 2s GOP and rely on on-demand IDR (#4757) (android, performance, video, webrtc)
  • ci: lint bash embedded in .claude/commands and skills markdown (#4118) (ci, devxp, testing)

[v0.0.47] - 2026-07-29

Fixed

  • release: screen-capture-helper asset name/format 404s for the client (#4688) (release engineering)
  • release: mint-side checksum steps pipe sha256sum without pipefail (fail open) (#4684) (ci, release engineering)
  • release: checksum bake never refreshes apkSha256/ipaSha256 for an already-registered version (#4683) (release engineering)

Other

  • Desktop workspace: emulator controls on each device pane (rotate · screenshot · snapshot + contextual Unlock) (#4690)
  • Desktop workspace: full-screen device picker with filter rail (state/platform/os/form-factor/architecture) + fuzzy search + multi-select observe (#4676)
  • feat(mcp): render observe output as an MCP App (inline screenshot + view hierarchy) (#4669)
  • spike: MCP 2026-07-28 SDK v2 migration + stateless-core impact assessment (#4666)
  • Desktop: replace ThreePaneShell root with WorkspaceShell scaffolding (device-column model + empty state) (#4663)

[v0.0.46] - 2026-07-24

Added

  • feat(observe): wire settleObserve + waitForCondition into MCP tools + waitFor DSL (#4398)
  • feat(observe): Wait-For-Condition + Settle-Loop Observe primitives (#4389) (performance)
  • feat(observe): Interactable Skeleton Projection — actionable-only observe output (#4388) (performance)
  • feat(observe): add deferred waitFor settled, absence, and openLink integration (#3490)

Changed

  • Remove dead utils/interfaces barrel + @deprecated re-export shims (#3504) (dead-code)

Fixed

  • fix(database): DatabaseInspectorProvider failure replies should carry a structured envelope, not raw Bundle.toString values (#4216)

Other

  • iOS WebRTC device-capture lane flakes on macos26 (headless Chrome): add diagnostics + launch retry (#4409)
  • Skip iOS CtrlProxy prefetch when Xcode prerequisites (xcrun/xcodebuild) are unavailable (#4407)
  • Skip Android CtrlProxy APK prefetch when Android prerequisites are unavailable (#4404)
  • Ship a prebuilt iOS screen-capture helper with npm releases (#4392)
  • Android WebRTC stream can starve late viewers on a static screen (#4383)
  • test(webrtc): assert iOS WHEP PLI recovery to a fresh IDR on the hosted device lane (#4376)
  • perf(webrtc): collect CI egress/decoded-fps samples and set a p50/p95 baseline for the iOS bitrate default (#4375)
  • sdkmanager boundary detector: residual bounded false-negatives (class field, callback param, member-assigned fn) (#4368)
  • fix(action): inputText unlocks a secure keyguard but reports setText failure; tapOn cannot fit the lock-screen budget (#4360)
  • fix(observe): parseTasks histRoots picks a Hist #0 row that rootOfTask says is not the task root (#4359)
  • test(webrtc): iOS device capture lane fails in a teardown hook after a fully successful capture (#4354)
  • test(release): release.test.ts pins RELEASE_CHECKSUM_REGISTRY[0] by version, so every version bump reds main (#4353)
  • build(turbo): test task inputs omit android/**, so Kotlin-reading guards can be cached away (#4351)
  • perf(webrtc): measure and cap iOS native-resolution encoder load and egress bitrate (#4349)
  • perf(webrtc): bound iOS WebRTC keyframe recovery under a delivery shortfall (#4348)
  • perf(webrtc): tighten MediaMTX track-gather timeout from device metrics (#4345)
  • memory-leak stress test flakes on windows-latest: 200-iteration loop has no explicit timeout (#4342)
  • sdkmanager boundary guard: interprocedural gap, Bun.$ coverage, and fast-validate registration (#4341)
  • fix(observe): GetBackStack infers isTaskRoot from the Hist index instead of dumpsys rootOfTask (#4340)

[v0.0.45] - 2026-07-24

Added

  • ci(webrtc): exercise the MediaMTX publisher integration test on webrtc PRs and always on merge (#4328) (video)
  • spike(webrtc): evaluate collapsing custom H264 RTP packetization / PLI onto werift built-ins (feasibility unproven) (#4299) (video)
  • refactor(webrtc): retire the hand-rolled coordination server in favor of MediaMTX (#4291) (video)
  • test(webrtc): MediaMTX-backed publisher→WHEP integration test (#4290) (video)
  • feat(webrtc): adopt MediaMTX as the supported WHIP/WHEP fanout (docs + config) (#4289) (video)
  • ci(observability): reproducible CI failure-rate and step-duration measurement (#4122) (ci, devxp, testing)
  • refactor(ios): align product boot with boot-simulator.sh — self-verify, bounded retry, runtime resolution (#4094) (ios, devxp, testing)
  • feat(device): gate simulator/emulator auto-creation behind a CLI flag + env var (default off) (#4093) (android, ios, devxp)
  • feat(desktop): render the live device stream from video-stream.sock (needs a decoder decision) (#3995) (android, video)
  • feat(db): quarantine a corrupt auto-mobile.db and reopen fresh in-process instead of failing for the daemon’s lifetime (#3988) (database)
  • feat(db): retry transient startup-migration failures instead of query-deading the DB for the process lifetime (#3987) (database)
  • feat(db): classify SQLite corruption with a bounded integrity probe at cold start (#3986) (database)
  • feat(desktop): receive daemon push notifications (list_changed) — needs a persistent control-socket connection (#3978) (android)
  • feat(ios): WebRTC audio capture — bring iOS to parity with the Android PCMU path (#3972) (ios, video)
  • feat(a11y): opt-in screen-reader navigation fidelity mode (swipe cursor traversal) (#3937) (android, ios, a11y)
  • feat(a11y): make direct activation the default screen-reader interaction path (Android + iOS) (#3936) (android, ios, a11y)
  • feat(voiceover): support VoiceOver Rotor navigation (#3934) (ios, a11y)
  • feat(desktop): wire remaining device-facing daemon sockets — appearance control and video recording (#3932) (android, video)
  • feat(desktop): wire device snapshot capture/restore via the daemon device-snapshot socket (#3931) (android)
  • feat(desktop): consume the daemon WebRTC live-video stream (upgrade device view from screenshot polling) (#3928) (android, video)
  • video-server jar: async resolution wiring in webrtcStreamManager (#3836) (android)
  • video-server jar: gated background startup prefetch (#3835) (android)
  • video-server jar: resolution precedence, fail-modes & env flags (#3834) (android)
  • video-server jar: VideoServerJarProvider (download + verify + persistent cache) (#3831) (android)
  • video-server jar: add videoJarSha256 to release checksum registry + resolvers (#3830) (release engineering)
  • WebRTC: protocol enhancements — trickle ICE and audio (#3778) (video)
  • Desktop: model observation diff metadata in the hierarchy tree (#3758) (android)
  • Desktop: surface screenshot stream metadata in the layout inspector (#3757) (android)
  • Desktop: focus-aware observation stream cadence (#3756) (android)
  • feature-flags.md: –ui-perf-mode is on-by-default, not an enable flag (#3583) (documentation, doc-audit)
  • iOS multiFingerSwipe: mirror the #2910 private-symbol availability split (and public fallback where feasible) (#2952) (ios)
  • Screen Streaming: Audio capture and playback (#1097) (android, ios)

Changed

  • ci: 30 of 40 pull_request jobs have no timeout-minutes, so any hang costs the 6-hour default (#4155) (ci, devxp)
  • flaky(test): eight more test files assert on a monkey-patched shared logger singleton (#4149) (flaky test, testing)
  • ci(ios): collapse the now-adjacent duplicate simulator shutdown steps (#4116) (ios, ci)
  • test(ios): re-anchor 26.5-leg step extraction off the teardown step (#4115) (ios, ci, testing)
  • ci(ios): remove no-op Xcode re-selection steps from the 26.5 leg after the 26.2 drop (#4114) (ios, ci)
  • test(ios): exact-equality workflow assertions break on legitimate edits — convert to property matchers (#4102) (ios, devxp, testing)
  • ci(ios): !cancelled() on XCTestRunner steps runs the 26.5 block after a failure — spurious double failures + wasted minutes (#4082) (ios, ci)
  • ci(ios): XcodeGen re-orders CtrlProxy.xcodeproj targets nondeterministically — drift check fails despite pinned version (#4080) (ios, ci)
  • ci: gates promoted to blocking without clearing existing main violations — reds unrelated/docs PRs (SwiftLint, Detekt, simctl-ratchet) (#4079) (ci, devxp)
  • devxp(ci): turbo test output swallows bun’s expected/received diff — CI-only failures show just “(fail) ” (#4077) (ci, devxp, testing)
  • Centralize daemon launcher discovery and spawning (#4067) (devxp, testing)
  • Centralize Git revision probing behind GitMetadataClient (#4066) (devxp, testing)
  • Centralize iOS CtrlProxy host process inspection and signaling (#4063) (ios, devxp, testing)
  • Centralize security CLI execution behind SecurityClient (#4061) (ios, devxp, testing)
  • Centralize codesign execution behind AppBundleMetadataClient (#4060) (ios, devxp, testing)
  • Centralize plutil execution behind a PlistClient (#4059) (ios, devxp, testing)
  • Centralize pymobiledevice3 execution for physical-device configuration (#4058) (ios, devxp, testing)
  • Centralize sqlite3 CLI execution for simulator TCC access (#4056) (ios, devxp, testing)
  • Centralize FFmpeg execution behind a media-process client (#4055) (devxp, testing, video)
  • Centralize xcodebuild execution behind XcodebuildClient (#4054) (ios, devxp, testing)
  • Centralize avdmanager execution behind an AvdManagerClient (#4051) (android, devxp, testing)
  • Centralize sdkmanager execution behind an SdkManagerClient (#4052) (android, devxp, testing)
  • Centralize Android emulator execution behind AndroidEmulatorClient (#4050) (android, devxp, testing)
  • Centralize xcrun simctl execution behind SimCtlClient (#4049) (ios, devxp, testing)
  • Centralize ADB process execution and make user targeting explicit (#4048) (android, devxp, testing)
  • chore(desktop): one canonical Json for daemon clients — the encodeDefaults footgun has now bitten four times (#4018) (android)
  • chore: remove vestigial BUN_JSC_useWasmOSR guard and rename DEFAULT_JPEG_QUALITY (#4009)
  • Dead Code Detection: Threshold Exceeded (#4007) (automated, dead-code)
  • fix(tooling): typecheck fails and lint dirties release.ts on a clean checkout of main (#4000)
  • lint: burn down the stage-1 declarative ratchet baseline and tighten thresholds (#3957 follow-up) (#3966) (devxp)
  • chore(desktop): MCP client hygiene — validate negotiated protocolVersion, fix stale clientInfo identity, drop deprecated env fallbacks (#3929) (android)
  • chore(desktop): remove dead daemon-client paths superseded by newer designs (storage socket, HTTP discovery, perf poll/push) (#3927) (android, dead-code)
  • chore(talkback): finish or remove nav leftovers — unused intermediateCheckpoints, ignored tap/doubleTap (#3920) (a11y)
  • chore(talkback): remove or wire up dead, divergent AccessibilityFocusTracker (#3919) (a11y)
  • video-server jar: docs for release delivery & env flags (#3837)
  • Dead Code Detection: Threshold Exceeded (#3816) (automated, dead-code)
  • Hide injected deviceId from advertised tool schemas on device-targeted tools (#3768) (performance)
  • refactor: tighten over-broad / vacuous catch handlers (fileLock over-catch, WebpBinaryResolver no-op rethrow) (#3623)
  • chore: comment & naming nits from 0.0.40→0.0.44 review (orphaned JSDoc, duplicated rationale, misleading predicate, alias accessors) (#3621)
  • refactor: remove dead/redundant guard branches surfaced by 0.0.40→0.0.44 review (#3619) (dead-code)
  • [tracking] Design-doc accuracy audit — drift, unsubstantiated claims, and untested ‘Tested’ chips (#3565) (documentation, doc-audit)
  • Remove dead video-capture scaffolding: unused NoopVideoCaptureBackend + never-read outputStream field (#3564) (video, dead-code)
  • Catch-convention sweep left a generic, sometimes-inaccurate boilerplate comment across 32 files (#3563)
  • fix(screenshot): extractHashFromFilename name/JSDoc/behavior disagree (returns timestamp, doc says null) (#3562) (documentation)
  • refactor(server): deviceImageResources implements the handler twice behind two DI mechanisms (#3561) (dead-code)
  • Device-action tests can never fail (both-branches-pass / self-caught sentinel / construct-then-toBeDefined) (#3509) (testing)
  • perf: DefaultNavigationToolCallRecorder.record rebuilds an array + linear .includes per tool call (#3434) (performance)
  • perf: several selection helpers full-sort an array only to take the single min/max element (#3432) (performance)
  • [tracking] Autonomous issue burn-down campaign — lanes, waves, status (#3235)
  • chore(db): verify dbWriteBarrier cold-start end-to-end when an in-process DB reopen path is introduced (#2912 follow-up) (#2960) (database)

Fixed

  • chore(ci): ratchet down the stale typecheck and shell-sete baseline entries (#4248)
  • ci(android): boot-emulator.sh runs outside the emulator-runner action, so listAvds cannot find the SDK (#4237)
  • ci: main is red on the typecheck gate (telemetryPushSocketServer TS2339), blocking every PR (#4209)
  • fix(vision): result cache is per-call in production, so it never hits and every vision fallback is paid for (#4207)
  • investigate(observe): GetBackStack dumpsys parser returns zero activities against real output (#4197)
  • fix(ios): SimCtlClient drops empty argument values and mangles escapes, turning “defaults write” into “read” (#4196)
  • fix(daemon): video-stream.sock is started but absent from both socket registries, so it is never unlinked (#4195)
  • fix(screen-stream): corrupt frame header re-parses payload as headers, emitting ~1000 malformed callbacks (#4194)
  • fix(ios): CtrlProxyHierarchy.invalidateCache() is an observable no-op (#4193)
  • fix(android): disableViaSettings does not invalidate the accessibility detector cache (#4192)
  • fix(database): SQLite error type and message silently truncated at whitespace and comma (#4191)
  • fix(navigation): “star”/”rate” substring match misclassifies “Get Started” and “Restart” as rating dialogs (#4190)
  • fix(vision): order-sensitive cache key causes duplicate paid analyzer calls (#4189)
  • fix(server): prototype-inherited keys corrupt query-param and union-schema lookup maps (#4187)
  • fix(performance): CPU-only violations render an empty “Top contributors” diagnostic (weight 0.5 vs filter > 0.5) (#4167)
  • fix(action): OpenURL dispatches the untrimmed URL despite trimming for validation and logs (#4166)
  • fix(ios): DeviceDetection misclassifies physical iOS device UDIDs as Android (#4165)
  • fix(observe): filterSingleNode fails open at the root when all children are filtered out (#4164)
  • Installer: ffmpeg install is unbounded and discards output (45-min Installer Minimal outlier) (#4162)
  • fix(release): runnerSha256 hashes the XCTRunner stub, not the runner code (#4153) (ios)
  • ci(ios): swift-test.sh reports a package as passing when it executed zero tests (#4143) (ios, ci, testing)
  • flaky(test): GetDumpsysWindow asserts on a monkey-patched shared logger and races other tests (#4134) (flaky test, testing)
  • ci: automerge lands PRs with failing iOS jobs — Swift Packages and the iOS rollups are not required contexts (#4101) (ci, devxp)
  • flaky(test): videoRecording tool segmentation resolves real file-backed DB (#3067 guard) and hangs — budget bump masked it (#4081) (flaky test, testing, database)
  • flaky(ios): simctl recordVideo never emits “Recording started” — video start times out with empty stderr (#4076) (flaky test, ios, ci, testing, video)
  • fix(ios): tapOn cannot resolve SpringBoard-owned alert elements that observe returns (#4014) (ios)
  • fix(ios): VoiceOver toggle reports success while VoiceOver is not running (#4012) (ios, a11y)
  • ci(ios): CtrlProxy XcodeGen drift check fails on every PR — committed pbxproj target order is not reproducible in CI (#3975) (ios, ci)
  • Auto-cancel a hung/failed device boot by killing the start handle on readiness failure (#3952) (ios)
  • Command timeouts orphan the underlying child process (simctl/emulator/xcodebuild) — no kill on timeout (#3938) (ios)
  • fix(a11y): force-accessibility-mode feature flag is dropped on tapOn/swipeOn detection (Android + iOS) (#3925) (android, ios, a11y)
  • fix(talkback): detection + focus robustness — “null” substring misclassification and masked focus-confirm failure (#3922) (android, a11y)
  • fix(a11y): screen-reader toggle reports success optimistically — TalkBackToggle and VoiceOverToggle (#3921) (android, ios, a11y)
  • fix(talkback): activation double-taps the element’s stored bounds (or 0,0), not the focused node (#3918) (android, a11y)
  • fix(talkback): focus path calculator assumes null cursor == index 0 → navigates the wrong direction (#3917) (android, a11y)
  • fix(talkback): TalkBack swipe/scroll silently degrades to coordinate mode — null passed as AdbExecutor to detectMethod (#3915) (android, a11y)
  • Incoherent registry[0] (v0.0.44) checksums break latest integrity verification + nightly overwrites tagged release entries (#3839) (ios, ci, release engineering)
  • fix(control-proxy): WebSocket maxFrameSize=Long.MAX_VALUE allows OOM from one hostile frame (twin of iOS #3626) (#3711) (android)
  • fix(control-proxy): PerfProvider shares one entry stack across threads — cross-thread mis-nesting (twin of iOS #3635) (#3709) (android)
  • fix(sdk): RecompositionTracker.entries grows unbounded (no eviction) — twin of iOS #3624 (#3708) (android, performance)
  • fix(scripts): verify-artifact-sha256.sh robustness — empty-checksum guard bypass + sha256sum portability (#3658) (release engineering)
  • fix(scripts): changelog script uses bare ‘python’ (fails on ubuntu-latest release-prep) (#3657) (release engineering, python:uv)
  • fix(scripts): deploy_website.sh clean-clone step is a no-op; deploys dirty working tree (#3656) (release engineering)
  • fix(scripts): latent Android/local shell bugs — pgrep substring PID, mapfile, dead idle check (#3654) (android, chore)
  • fix(scripts): macOS/BSD portability & cosmetic cleanups in validation/tooling scripts (#3653) (devxp, chore)
  • fix(scripts): iOS shell script polish — cosmetic/latent bugs in ios/* helpers (#3652) (ios, chore)
  • fix(scripts): start-emulator-wtf-session.sh unbound array on real path (dry-run guarded, real run not) (#3651) (android)
  • fix(scripts): all_fast_validate_checks.sh unbound-variable on empty array under bash < 4.4 (#3650) (devxp)
  • fix(scripts): swiftformat/swiftlint install_manual returns 0 on failed download (#3649) (devxp)
  • fix(scripts): launch_app_perf_test.sh log_debug writes to stderr instead of the log file (#3648) (android)
  • fix(scripts): launch_app_perf_test.sh aborts entire run on one adb failure (set -e); retry logic dead (#3647) (android, performance)
  • fix(scripts): await_idle.sh rotation regex uses GNU sed ‘+’ which is literal on BSD/macOS sed (#3646) (android)
  • fix(scripts): ios/setup-ios-simulator.sh silently ignores documented ‘–min-ios VERSION’ space form (#3645) (documentation, ios)
  • fix(scripts): ios/start-simulator.sh uses GNU ‘timeout’ (absent on stock macOS) -> false boot failure (#3644) (ios)
  • fix(scripts): apply_shfmt.sh ignores shfmt exit status; unparseable files silently skipped (#3643) (devxp)
  • fix(scripts): xml/validate_xml.sh tool-presence guard is always false (#3642) (devxp)
  • fix(scripts): hadolint installer accepts 404 as binary (curl missing –fail; Darwin-arm64 asset does not exist) (#3641) (devxp)
  • fix(scripts): daemon-lifecycle.sh passes green when daemon start/health fail (no set -e) (#3640) (ci, devxp)
  • fix(scripts): run-ts-coverage.sh WriteFailed guard matches ‘10 fail’ as ‘0 fail’ (#3639) (ci, devxp)
  • fix(scripts): uninstall.sh jq-less JSON path reverts its own edit (no-jq machines cannot uninstall) (#3638) (devxp)
  • fix(scripts): validate-ios.sh silently drops failed Swift builds under pipefail (#3637) (ios, devxp)
  • iOS runner: PerfProvider singleton shared across server-queue + poll thread — timing tree mis-nests (#3635) (ios)
  • iOS SDK: AutoMobileCrashes writes previousExceptionHandler outside the lock it reads under (#3633) (ios)
  • iOS SDK: SdkEventBroadcaster.ctrlProxyUrl unsynchronized — data race with flush thread (DEBUG) (#3632) (ios)
  • iOS XCTestRunner: exportTimingData/printSummary read timingData without lock (parallel-testing race) (#3629) (ios)
  • iOS SDK: UserDefaults typeOf checks Int before Bool/Double — NSNumber values misclassified in telemetry (#3628) (ios)
  • iOS screen-capture: FrameProtocol.decodeHeader misaligned load(as:) is UB — use loadUnaligned (#3627) (ios)
  • iOS runner: WebSocket frame length Int(UInt64) conversion traps on payload length ≥ 2^63 (#3626) (ios)
  • iOS XCTestRunner: unbounded strcpy into sockaddr_un.sun_path — stack overflow on long socket path (#3625) (ios)
  • iOS SDK: ViewBodyTracker.entries grows unbounded — memory leak with per-instance ids (#3624) (ios, performance)
  • iOS SDK: hang watchdog re-reports one hang every poll interval with wrong duration (no latch) (#3622) (ios)
  • Xcode extension: ExecutePlanCommand casts String contentUTI to URL — command always fails (#3620) (ios)
  • iOS XCTestRunner: TestTimingCache uses Dictionary(uniqueKeysWithValues:) — duplicate daemon key crashes the test run (#3618) (ios)
  • fix: ChildProcessTracker leaks SIGKILL timer when exitPromise rejects (clearTimeout not in finally) (#3617) (video)
  • iOS runner: get_table_data offset Int(Double) conversion traps on large/non-finite offset (#3616) (ios)
  • fix(daemon): input/tap coordinate validation uses Number.isNaN, accepts ±Infinity (drifts from input/swipe) (#3615)
  • iOS runner: ElementLocator shared state unsynchronized across server-queue and main-thread callers (#3614) (ios)
  • fix(sdk): RecompositionTracker.toJson reads mutable counters without synchronization (#3613) (android)
  • fix(db): repair-datetime migration reads pragma_table_info via bound param, can silently skip poisoned columns (#3612) (database)
  • iOS runner: WebSocketServer.connections data race — mutated on server queue, iterated on main during broadcasts (#3611) (ios)
  • fix(desktop-core): getPathFromParentMap infinite-loops on cyclic parent map (#3610)
  • fix(desktop-core): empty catch blocks swallow start-device and file-save failures silently (#3609)
  • fix(control-proxy): HierarchyDebouncer early-return skips Error emit on extraction failure (#3608) (android)
  • fix(junit-runner): tools/list result!! yields misleading null error on empty result (#3607) (android)
  • fix(junit-runner): WaitForTool busy-spins the daemon (and swallows error) when observe throws (#3606) (android, ai)
  • fix(sdk): throwing custom EventPersistence permanently kills the periodic flush timer (#3605) (android)
  • fix(control-proxy): NavigationEventAccumulator non-atomic sequence counter + check-then-act trim (#3604) (android)
  • fix(desktop-core): screenshot action uses GlobalScope, leaking coroutine + MCP client (#3603)
  • fix(desktop-core): runProcess deadlocks / spuriously fails on command output exceeding pipe buffer (#3602)
  • fix(sdk): SharedPreferencesDriverImpl change maps are non-thread-safe despite multi-thread listener (#3601) (android)
  • fix(control-proxy): StorageSubscriptionManager mutates HashMaps across IO/Main threads without synchronization (#3600) (android)
  • fix(sdk): network-mock BroadcastReceiver leaks and double-registers across init/shutdown (#3599) (android)
  • fix(junit-runner): daemon disconnect surfaces as opaque ExecutionException, not DaemonUnavailableException; pending request leaks (#3598) (android)
  • fix(sdk): broadcast interceptor drops 5 of 7 monitored broadcasts (IntentFilter data scheme) (#3597) (android)
  • fix(junit-runner): AI recovery reads wrong system property, MCP server URL always null (re: #541) (#3596) (android, ai)
  • Error-fallback view hierarchies drop required updatedAt behind an ‘as unknown as’ cast (#3595)
  • Swallowed catches with no trace violate error-handling convention (iOS SDK-events, Idle) (#3594) (ios)
  • Emulator-exit eviction is fire-and-forget with no rejection handler (#3593)
  • isMutationQuery misclassifies comment-/whitespace-prefixed mutations → stale DB subscribers (#3591) (database)
  • ci(On Merge): ‘Update README Test Count Badges’ push race — ‘Failed to push after 3 attempts’ (#3590) (ci)
  • Unhandled EPIPE on ffmpeg stdin can crash daemon on mid-recording encoder death (#3588) (video)
  • ci(On Merge): Deploy Documentation fails on every merge — Git LFS fetch error at checkout (#3589) (ci)
  • swipeOn system-inset math over-subtracts on right/bottom edges (under-scroll, inverted bounds) (#3587)
  • Idempotent snapshot/recording upsert overwrites created_at on conflict (#3498) (database)
  • Daemon has no unhandledRejection/uncaughtException backstop — an escaped throw in an un-awaited callback (e.g. emulator child-process handlers) crashes the whole daemon (#3408)

Other

  • perf(webrtc): optimize iOS WebRTC capture scaling and frame rate (#4344)
  • test(webrtc): measure device capture-to-browser stage latency (#4343)
  • Follow-ups from #4325 post-merge review: sdkmanager boundary guard gaps and cleanups (#4338)
  • Daemon leaks auto-mobile-prefetch-* temp directories (unbounded disk growth) (#4334)
  • GetBackStack parser is not CRLF-tolerant (empty back stack on CRLF adb output) (#4333) (testing)
  • test(observe): capture real dumpsys activity activities per supported API level (24–36) and validate GetBackStack (#4329) (testing)
  • test(webrtc): add conditionally-gated device capture → WHEP coverage (#4308) (android, ios, video)
  • Android: recover from a secure keyguard (PIN entry / prompt the user) (#4282)
  • Android: distinct fresh-boot error when keyguard blocks accessibility-service binding (#4281)
  • Android: actions should refuse (not report success) when deviceLock.locked is true (#4280)
  • Extract parseArgs from src/index.ts for unit testability (#4277)
  • iOS CtrlProxy override: accept a derived-data directory on BUNDLE_PATH (or migrate remaining readers to the canonical helper) (#4275)
  • screen-stream wire format has no sync marker, so resync can only infer frame boundaries (#4270)
  • fix(screen-stream): resync can still fabricate a frame with chosen dimensions from payload bytes (#4264)
  • GetBackStack: legacy inline TaskRecord refs read as headers; modern A= tasks lack packageName/rootActivity (#4263)
  • fix(installer): sudo password prompt is invisible and unreachable under the install bound, and the watchdog returns before the group is dead (#4262)
  • CtrlProxy hierarchy: fresh-wait ignores elapsed budget (Android) and stale fallback returns a pre-await snapshot (iOS) (#4261)
  • verify-emulator-sdk-resolution.sh fails open: unexpected probe failures report a green SDK guard (#4260)
  • docs(ios): manual-test SKILL.md conflates cached artifacts with a running CtrlProxy runner (#4259)
  • typecheck baseline: union tokenizer corrupts string-literal members containing escaped quotes (#4257)
  • refactor(utils): consolidate the five private shell-quoting helpers onto src/utils/shellQuote.ts (#4255)
  • –cli drops –embedded-sdk and –network-mockable when starting/reusing the daemon, so SDK- and network-gated tools are unreachable (#4247)
  • DeviceSessionManager.verifyAndroidDevice matches device.name against a parameter named deviceId (latent; works only because Android sets name === deviceId) (#4244)
  • setUIState hangs to the 30s request timeout on an unmatched selector, and reports “Unknown field type: unknown” when it matches a label (#4242)
  • –cli JSON.parse coercion makes numeric-looking strings unpassable: inputText –text 12345 and sendSms –phoneNumber 5551234567 both fail (#4241)
  • keyboard open/close always report success:false with inverted state — 100ms post-action delay samples before the IME animation completes (#4238)
  • deviceSnapshot restore silently restores nothing by default: 244-package pm clear exhausts the request timeout before restoreSettings runs (#4236)
  • Android: no structured signal that the device is asleep/locked — observe and tapOn silently succeed against the lock screen, and a PIN lock leaves agents stuck (#4235)
  • fix(ios): migrate the remaining SimCtlClient internal commands off the string path to argv (#4234)
  • setActiveDevice error prints “Available devices: [object Object]” (joins BootedDevice objects instead of their ids) (#4227)
  • test(observe): capture real dumpsys fixtures and teach parseTasks the modern Task{…} header (#4223)
  • AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_PATH: local-runner override is silently ignored (wants an .ipa, is documented as a directory, and never fails when unusable) (#4221)
  • fix(daemon): input/pressButton accepts “enter” but no platform can handle it (#4214)
  • fix(action): openLink interpolates the URL into a shell string — quote-breaking URLs are mangled or inject (#4213)
  • ci(ios): boot-simulator.sh empty-array expansion breaks under bash 3.2, redding BATS Shell Tests (macos-latest) on main (#4212)
  • ci: typecheck gate red on clean main — union member reordering defeats the baseline signature (#4211)
  • fix(daemon): main is red — failure backfill selects no session_id, so typecheck gate fails and crash events lose sessionId (#4208)
  • test(lint): 10 inert assertions in AdbClient-listUsers + ratchet rule banning bare expect() with no matcher (#4198) (testing)
  • test(fakes): FakeTimer auto-advance fires out of order and TimerContract cannot detect it (blocks ~30 findings, 225 files) (#4188) (testing)
  • CI: editing the iOS integration job’s own YAML does not trigger that job (#4137) (ios, ci)
  • CI: experiment — background Reminders XCTest prebuild across daemon/CtrlProxy warm-up (#4131) (ios, ci, performance)
  • CI: remaining parallel-steps smalls — jq, deploy-docs setups, cache fan-outs, hadolint (#4130) (ci, performance)
  • CI: release/prepare-release parallel-steps batch — npm CLI, docker prune, ripgrep, artifact fan-outs (#4129) (ci, performance)
  • CI: nightly parallel-steps batch — xcpretty overlap, XcodeGen sweep, redundant Setup Bun (#4128) (ios, ci, performance)
  • CI: parallelize tool installs in build-ctrl-proxy-ios-ipa (3 callers) (#4127) (ios, ci, performance)
  • CI: background BATS install across the Bun setup in bats-tests (pull_request + merge) (#4126) (ci, performance)
  • CI: background fast-validation apt/bats install across JDK + npm-package setup (#4125) (ci, performance)
  • CI: hoist ffmpeg install out of the videoRecording test step (parallel-steps) (#4124) (ios, ci, performance)
  • refactor(scripts): extract PR review-thread collection to scripts/ci with BATS coverage (#4120) (ci, devxp, testing)
  • refactor(scripts): extract PR failing-job log retrieval to scripts/ci with BATS coverage (#4119) (ci, devxp, testing)
  • ci(ios): harden boot-simulator.sh against GitHub Actions flake (retry, inter-leg reclamation, diagnostics) (#4095) (flaky test, ios, ci, testing)
  • ci: log-artifact upload ENOTFOUND reds an otherwise-green Windows job — make upload non-fatal (#4083) (ci, env)
  • ci(ios): XCTestRunner Simulator Tests can blow its 45-min cap — unbounded sim-boot step, ~99min of step budgets, no matrix (#4078) (ios, ci, testing)
  • iOS accessibility –voiceover true reports applied:false for a successful enable (confirm re-detects before launchctl kickstart completes) (#4045)
  • accessibility –talkback reports “not installed” for an installed-but-disabled TalkBack (dumpsys detection can’t see it) (#4042)
  • Android CtrlProxy unreachable: PortManager dials ws://localhost (IPv6-first) but adb forward binds IPv4-only (#4039)
  • detekt type resolution is incomplete: 377 compiler errors silently degrade potential-bugs (#4030)
  • docs(ios): ctrl-proxy-ios.md incorrectly claims synthesized multi-touch reaches VoiceOver (#4013) (documentation, ios, a11y)
  • fix(ios): VoiceOverSwipeExecutor silently degrades to a single-finger swipe and reports success (#3993) (ios)
  • Deferred: two residual drift gaps around the correlated-error core (only on 4th consumer / first suffix drift) (#3992) (android)
  • test(ios): source-scan guard that GesturePerformer actually consumes the symbolsUnavailable flag (pinch + multiFingerSwipe) (#3985) (ios)
  • ci(tools): swiftlint/swiftformat version pins are dead code on macOS — brew install bypasses them (#3982)
  • Duplicate artifact name junit-runner-heap-dumps in two jobs of the same workflow run (#3976)
  • feat(a11y): fidelity assertions — surface reachability / traversal-order / focus-trap results (#3963) (android, a11y)
  • Flaky test (recurrence of #3877): videoRecordingToolSegmented “bare (by-device) stop” still times out on macOS CI (#3943) (flaky test, testing, video)
  • docs(a11y): talkback-voiceover.md is stale — marked “Design Only” but detection/tap/swipe are implemented (#3926) (documentation, a11y)
  • flaky(ios): videoRecording start-stop integration — simulator recording produces empty (0-byte) .mov, finalize fails (#3910) (flaky test, ios, ci, video)
  • flaky(test): ExecutionTracker abort-signal-reason race — reason undefined despite cancelled count (#3909) (flaky test, ci, testing)
  • Enable long iOS recordings: raise the 300s manager cap for iOS (auto-stop enforces maxDuration) — no segmentation needed (#3906)
  • Segmented videoRecording: emit segments into one shared directory (+ manifest) instead of per-recording subdirs (#3905)
  • Flaky test: videoRecordingToolSegmented ‘bare (by-device) stop’ times out via real-DB guard on macOS CI (#3877)
  • ci: workflow-YAML assertion tests (RemindersPlanContentTests) don’t run on .github/** PRs — workflow refactors break nightly undetected (#3862) (ios, ci)
  • CI: ‘Run Tests with Coverage’ hides failing test names — coverage table buries bun’s (fail) lines past the tail window (#3861) (ci, devxp, testing)
  • WebRTC stream socket fails before WHIP publish due to reflect-metadata runtime error (#3857)
  • elementId matching misses Compose testTag nodes when queried with the fully-qualified pkg:id/name form (#3852)
  • flaky(iOS/nightly): RemindersLaunchPlanTests cold-bring-up timeout — 6-night streak; #3827 retry fix pending nightly validation (#3851) (flaky test, ios, ci, testing)
  • Daemon silently loses all its startup flags mid-session when a bare CLI client connects (#3846)
  • AUTOMOBILE_LOG_LEVEL is parsed and unit-tested but never actually applied to the running process (#3845)
  • Add a –no-occlusion runtime flag to disable the observe occlusion-filtering pass (#3844)
  • Segmented video recording only covers executePlan — the raw videoRecording tool still hits the 180s screenrecord cap (#3843)
  • video-server jar: extend checksum tooling + nightly bump for videoJarSha256 (#3833) (ci, release engineering)
  • video-server jar: build & attach automobile-video.jar to GitHub releases (#3832) (android, ci, release engineering)
  • CI: extract iOS simulator bring-up into a composite action (DRY the boot/daemon/warm ritual) (#3782) (ios, ci, devxp)
  • CI: background iOS simulator boot during CtrlProxy build (boot/build overlap) (#3781) (ios, ci, performance)
  • CI: parallelize independent iOS tool installs in ios-xctest-runner-simulator-tests (#3780) (ios, ci, performance)
  • CI: spike — validate GitHub Actions parallel-steps (background/wait/parallel) behavior before adoption (#3779) (ci, performance, research)
  • WebRTC: iOS live streaming support (no live H.264 elementary stream via simctl) (#3777)
  • WebRTC: replace ~175s screenrecord segment rotation with a persistent on-device encoder (#3776)
  • WebRTC: verify on-device Android screenrecord H.264 capture end-to-end (#3775)
  • Record desktop screenshot baselines and expand coverage (#3752) (ci, testing)
  • feat(playground): integrate Compose HotSwan hot reload into the Android playground app (#3744)
  • feat(desktop-app): wire in JetBrains Compose Hot Reload for the desktop dashboard (#3743)
  • fix(sdk): SdkEventBuffer persists then immediately deletes every batch — I/O churn (twin of iOS #3636) (#3710) (android, performance)
  • iOS SDK: release builds persist-then-immediately-delete every event batch (needless disk I/O) (#3636) (ios, performance)
  • iOS runner: HierarchyMerger.buildLookup inserts 625 entries per SDK node (scalability) (#3634) (ios, performance)
  • Add latest Xcode (26.6) to nightly toolchain sweep matrix (#3630)
  • flaky(iOS): RemindersLaunchPlanTests still times out on Xcode 26.2 despite warm-up — single-attempt approach not holding (#3592) (flaky test, ios, ci, testing)
  • multi-agent-filesystem-contract.md: (doc accurate) add 0o700-mode test + verify #2453 citation (#3586) (documentation, testing, doc-audit)
  • loading-awareness.md: (doc accurate) minor clarity note + loading-detector hint test (#3585) (documentation, android, doc-audit)
  • biometrics.md: (doc accurate) validate API 29 + add emu-finger enrollment test coverage (#3584) (documentation, android, doc-audit)
  • actions-diff-observe-signoff.md: refresh stale post-#3228 byte/token table + view-id note (#3582) (documentation, doc-audit)
  • autocomplete-audit.md: SdkEventBroadcaster miscategorized (LIBRARY_GROUP, not internal) + class count off by one (#3581) (documentation, doc-audit)
  • simctl.md: ‘two-step’ vs 3-command terminate + DND flag framing + isIosSimulatorUdid untested (#3580) (documentation, ios, doc-audit)
  • storage/migrations.md: resolution diagram is wrong + recovery/copy branches untested (#3579) (documentation, database, doc-audit)
  • Serialize gh-pages deploy: add job-scoped concurrency to deploy-docs (#3578)
  • snapshots.md: iOS ‘does not include system settings’ is wrong + archive resource untested (#3577) (documentation, doc-audit)
  • resources.md: claims the listDevices tool was removed, but it’s still registered (#3576) (documentation, doc-audit)
  • tapOn-pre-tap-stability.md: implies always-on but the guard is opt-in + lists nonexistent selector names (#3575) (documentation, android, doc-audit)
  • nav/fingerprinting.md: unsubstantiated 100%/6-strategies/11-observations stats + vestigial 5th tier (#3574) (documentation, research, doc-audit)
  • context-thresholds.md: threshold values and baselines are ~6 months stale (tools at 99%, doc says 74%) (#3573) (documentation, doc-audit)
  • critical-section.md: exact error-message bodies + daemon-only registration are untested (#3572) (documentation, testing, doc-audit)
  • vision-fallback.md: doc says tapOn-only but it’s wired into 4 tools + orchestrator untested (#3571) (documentation, testing, ai, doc-audit)
  • sdk-event-pipeline.md: crash/ANR/hang marked ‘Tested’ but untested + DropReason enum understated (#3570) (documentation, testing, doc-audit)
  • cross-platform-parity.md: AutoMobileSDK.trackEvent doesn’t exist + accessor name/type drift (#3569) (documentation, doc-audit)
  • image-backend.md: AUTOMOBILE_IMAGE_BACKEND override is documented but unimplemented + signature drift (#3568) (documentation, doc-audit)
  • multi-device.md: documents a non-existent ‘barrier’ tool and an inverted device-required rule (#3567) (documentation, doc-audit)
  • test-plan-validation.md: CI validation job is missing + schema tool-name allowlist not enforced (#3566) (documentation, ci, doc-audit)
  • Run PRAGMA optimize periodically, not only on connection close (#3497) (performance, database)
  • perf(db): testExecutionRepository.cleanupRetention runs a per-insert offset-probe (#3440) (performance, database)
  • perf(db): failureAnalyticsRepository.getTimelineData buckets and counts in JS (#3439) (performance, database)
  • perf(db): toolCallRepository.listToolNamesBetween dedups in JS instead of SQL (#3438) (performance, database)
  • perf(db): failureEventRepository.getFailureCounts fetches full rows just to read .length (#3437) (performance, database)
  • perf(db): failureAnalyticsRepository.cleanupRetention — per-failure offset-probe + NOT IN(DISTINCT) orphan scan (#3436) (performance, database)
  • perf(db): performanceAuditRepository.cleanupRetention runs an offset-probe on every insert (#3435) (performance, database)
  • perf: findSimilarScreenshots full-sorts all files to take the newest 10 (#3433) (performance)
  • perf: optimizedBatchCompareScreenshots stitches results with O(n^2) linear .find() scans (#3430) (performance)
  • perf: WcagAudit.hasNearbyLabel rebuilds the textViews filter for every input element (O(inputs*elements)) (#3429) (performance, a11y)
  • perf: PredictiveUIState does O(interactables*edges) matching with per-iteration re-normalization (#3428) (performance)
  • perf: matchTemplate compiles a fresh RegExp for every registered template on every resource read (#3427) (performance)
  • perf: ExploreValidateMode recomputes SHA-256 edge keys over all pending edges (O(E^2)) (#3425) (performance)
  • Deferred: extract shared correlated-error-on-throw core between ResultBroadcaster and AsyncActionRunner (only on 3rd consumer / first drift) (#3086) (android)
  • [tracking] DB layer concurrency, migration & performance hardening (#2803) (database)

[v0.0.44] - 2026-07-11

Other

  • junit-runner >= 0.0.36 forces kotlin-stdlib 2.4.0 on consumers, locking out projects on older Kotlin (#3558)
  • Daemon remains healthy after observation-stream socket disappears (#3556)
  • DevicePool should validate iOS simulator liveness before assigning idle pooled UDIDs (#3553)
  • Evict Android Emulator From Pool When Process Exits or ADB Disappears (#3552)
  • CI: resolve Homebrew tap-trust warning in iOS IPA build (#3548) (ci)
  • CI: bump gradle-task-run actions off deprecated Node.js 20 (#3547) (ci)

[v0.0.43] - 2026-07-10

Other

  • Invalid observe outputSchema breaks strict MCP tools/list clients (#3542)
  • observe returns malformed/truncated JSON on occlusion-heavy screens (regression in current main) (#3539)

[v0.0.42] - 2026-07-10

Added

  • docs/observe: contentDescription waitFor predicate silently ignores textMatch (#3514) (documentation)
  • perf: getToolDefinitions() re-runs Zod->JSON-Schema conversion for every tool on every tools/list (#3426) (performance)
  • perf: ObserveElementsBuilder makes 4 full tree traversals per observe, 2 identical (#3419) (performance)
  • perf: filterOffscreenNodes does 2x full-tree JSON.stringify for a debug-only log (#3418) (performance)
  • Audit + concurrency stress-test in-process RMW get-or-create paths (#3405) (database)
  • Design and implement daemon input/key endpoint (#3370) (android, ios)
  • Add typed client helpers for daemon input API (#3345) (android)
  • Document daemon input API consumer examples (#3344)
  • Implement daemon text and key input endpoints (#3343) (android, ios)
  • Implement daemon input/pressButton endpoint (#3342) (android, ios)
  • Implement daemon input/swipe endpoint (#3341) (android, ios)
  • Implement daemon input/tap endpoint (#3340) (android, ios)
  • Define daemon Unix socket input API contract (#3339)
  • actions-diff-observe: choose diff strictness by action class (#3319) (ios, performance)
  • actions-diff-observe iOS: improve stable node identity beyond positional paths (#3318) (ios, performance)
  • iOS observe output: collapse XCTest/UIKit structural noise before action diffs (#3317) (ios, performance)
  • actions-diff-observe: report why a diff was skipped or emitted (#3316) (devxp, performance)
  • actions-diff-observe iOS: gate same-screen diffs on screenIdentity (#3315) (ios, performance)
  • actions-diff-observe iOS: derive fallback screenIdentity from accessibility hierarchy (#3314) (ios, performance, a11y)
  • Capture-layer stable node identity to shrink scroll diffs (opaque id-less rows) (#3228)
  • Forward + broadcast tools/list_changed & resources/list_changed across proxy and multi-session daemon (follow-up to #2963) (#3223)
  • Thread StructuredToolResponse through the tool registry (remove the asToolEnvelope unchecked cast) (#3222)
  • Dead observe screenshot cache chain: setLastScreenshot never fires, lastScreenshot never read (#3221)
  • Extend SessionCacheData escape-hatch guard to forbid setter-bypass slot writes in production code (follow-up to #2973) (#3219)
  • Follow-up #2962: consider structured log fields for the structuredContent-omission trace (#3216)
  • Follow-up #2962: directly test INFO-level suppression of the structuredContent-omission debug trace (#3215)
  • Complete or remove the incomplete declare-module “zod” stub forcing schema code into the typecheck baseline (#3207)
  • elementBoundsSchema advertises integer bounds but iOS coordinates are fractional points (#3206)
  • iOS storage telemetry value fidelity: lossy “(value)” stringification for Data/Date/array/dictionary (#3194) (ios)
  • iOS UserDefaults change telemetry has no production trigger (startListening never called) + standard-suite NSGlobalDomain noise (#3193) (ios)
  • feat(video): name recording files/folders by caller-supplied outputName (not just recordingId UUID) (#3145) (video)
  • Surface Compose toggle state (checked/selected/stateDescription) in the extracted view hierarchy (#3139)
  • feat(ios): return a physical-aware failure for getAppPermissions on physical iOS devices (#3135) (ios)
  • feat(ios): support the all privacy keyword for physical-device permission reset (#3133) (ios)
  • Explore structural-id content identity for in-place edits + optional pre-move key in diff (follow-up to #3053 part 1) (#3088)
  • Mark navigation/setup internal tool calls no-diff (DefaultUIStateSetup, NavigateTo) — baseline pollution under –actions-diff-observe (#3087)
  • actions-diff-observe: add a byte-size regression guard for element-field diffs (follow-up to #3059) (#3064)
  • feat(ios): unify device app-listing (ListInstalledApps devicectl parity) for terminate/uninstall wasInstalled (#3057) (ios)
  • feat(ios): explicit iOS<=16 ‘requires iOS 17+’ error for physical terminateApp/launchApp (#3056) (ios)
  • fix(ios): tolerate already-exited PID on devicectl device terminate (avoid false success:false) (#3054) (ios)
  • actions-diff-observe: positional node key cascades on scroll/insert; explore stable node identity + internal-consumer diff exposure (#3053)
  • actions-diff-observe: diff omits top-level focusedElement / accessibilityFocusedElement / awaitedElement changes (#3052)
  • actions-diff-observe: sign off the diff format on real-device output (#3026 acceptance) (#3051)
  • Dormant output-reduction flags: –actions-diff-observe and –actions-no-observe are plumbed but have no consumer (#3026)
  • observe tool has no outputSchema — advertise ObserveResult (incl. compact bounds tuple) on the wire (#3025)
  • Follow-up to #2997: generate golden tables from JSON + parser string-literal robustness (#3021)
  • Harden pinch-geometry parity: single-source golden vectors instead of hand-duplicated tables (follow-up to #2979) (#2997) (ios)
  • observeResultCompact follow-ups: actionsDiffObserve composition test + wire-schema tuple doc (#2990) (performance)
  • Add executable guard for iOS pinch geometry (parity with Android computePinchPoints) (#2979) (ios)
  • observeResultCompact: resolve mixed bounds representation (node tuples vs. object elements/root/window bounds) (#2978) (performance)
  • Promote well-known customData keys (keep-awake, device-label) to typed SessionCacheData slots (follow-up to #2917) (#2973)
  • Type or remove the dormant lastActionTime session-cache write (follow-up to #2917) (#2972)
  • Emit tools/list_changed when output-reduction flags toggle at runtime (follow-up to #2759) (#2963)
  • Output reduction: debug-log intentional structuredContent omission (follow-up to #2759) (#2962)
  • Wire observeResultCompact flag into sanitizeObserveResult (flag plumbed but dormant) (#2951) (performance)
  • Durable typed-envelope: re-type the ToolHandler boundary so envelope payload dead-reads are a compile error (#2932)
  • SessionCacheData typed lastHierarchy/lastScreenshot slots are dormant decoys; real data lives in customData with a different type (#2917)
  • pinchOn rotationDegrees: document or fix start-horizontal/end-rotated axis convention (Android + iOS) (#2911) (ios)
  • iOS pinchOn: add public pinch(withScale:velocity:) fallback when private XCTest event-synth symbols are unavailable (#2910) (ios)
  • Typed accessor / typed envelope to eliminate the envelope-vs-structuredContent dead-read bug class (#2907)
  • Wire toolResultsNoStructuredContent flag into finalizeToolResponse (flag plumbed but dormant) (#2899) (performance)
  • Latent bug: swipeOn scroll-position update reads response?.found off the MCP envelope (always undefined) (#2897)
  • feat(ios): terminateApp physical-device support (currently a silent success no-op) (#2882) (ios)
  • Output reduction: extend observe perf-strip to top-level perfTiming/gfxMetrics (#2878) (performance)
  • Automatically recover from an incomplete bunx extraction (consume the EX_TEMPFAIL / exit-code 75 signal) (#2865) (devxp)
  • iOS DND: replace version gate with behavior-based (write→independent readback) detection (#2861) (ios)
  • Output reduction 7: strip embedded observation (–actions-no-observe) (#2762) (performance)
  • Output reduction 6: observe diff for non-observe tools (–actions-diff-observe) (#2761) (performance)
  • Output reduction 5: compact/TOON observe encoding (–observe-result-compact) (#2760) (performance)
  • Output reduction 4: gate structuredContent duplication (drop for no-schema tools) (#2759) (performance)
  • Output reduction 3: finalizeToolResponse hook + lastHierarchy cache repair (#2758) (performance)
  • Output reduction 2: sanitizeObserveResult (perf-strip + node-trim + elements-drop) (#2757) (performance)
  • Output reduction 1: config plumbing for output-reduction flags (CLI + env) (#2756) (performance)
  • feat(ios): setAppPermissions — reset privacy permissions on physical iOS devices via the CtrlProxy XCUITest runner (#2491) (ios, research)
  • feat(ios): openLink — open URLs/deep links on physical iOS devices via devicectl (#2490) (ios)
  • feat(ios): listApps — enumerate installed apps on physical devices via devicectl (#2489) (ios)
  • feat(ios): terminateApp — physical-device termination via devicectl (#2488) (ios)
  • feat(ios): launchApp — physical-device launch/terminate via devicectl (#2487) (ios)
  • feat(ios): pinchOn — coordinate-based pinch/zoom via XCUITest CtrlProxy runner (#2482) (ios)

Changed

  • chore(observe): remove dead camelCase element-attribute fallbacks in waitFor matcher (#3513) (dead-code)
  • Consolidate near-duplicate ThresholdManager and MemoryThresholdManager into a generic threshold manager (#3448) (performance)
  • Consolidate identical deviceSnapshot/videoRecording config socket servers into a generic ConfigSocketServer (#3447)
  • Consolidate 3 byte-identical config repositories into a generic KeyedJsonConfigRepository (#3446) (database)
  • Dead Code Detection: Threshold Exceeded (#3257) (automated, dead-code)
  • refactor(ios): extract IOSCtrlProxyManager port health and host-control collaborators (#3218) (ios)
  • Follow-up to #2885: SessionManager barrier comment, in-process reopen reset, and trackExisting direction re-eval (#3154) (database)
  • test(db): databaseLazyPath + dbWriteBarrierResetOnClose flake (timeout) on windows-latest CI (file-backed sqlite) (#3030) (database)
  • chore(db): fileLock hardening follow-ups from PR #2995 (release incarnation-awareness + positional-format contract) (#3006) (database)
  • Remove pre-existing dead Image facade methods (transform/disableCache) (#2970) (javascript, dead-code)
  • chore(db): in-process same-path reopen can steal an in-flight migration’s own-PID lock (reclaimOwnPid) (#2947) (database)
  • chore(db): consolidate migration-state module globals into a single MigrationState + reset() (#2944) (database)
  • test(db): reset-test files bleed process.env across the suite → intermittent databaseReset.test.ts flake (#2942)
  • db: guard migration-lifecycle against a startMigrations run that settles after closeDatabase() reset (#2940) (database)
  • Trim unused ImageUtils/Image surface left over from the sharp→jimp migration (#2938) (javascript, dead-code)
  • refactor(db): consolidate closeDatabase() reset checklist behind a single resetDbLifecycleState() (#2935) (database)
  • docs(db): two inaccurate comments left by #2905 (test ‘fully true’ over-claim + null-swap safety rationale omits use-time throw) (#2934) (documentation, database)
  • chore(db): dbWriteBarrier reset is identity-swap — construction-captured consumers keep the drained barrier across a same-process reopen (#2912) (database)
  • refactor(db): encapsulate migration-lifecycle module globals into a single resettable state object (#2900) (database)
  • chore(db): no generation fence — an in-flight migration completing after closeDatabase() can stomp the next generation’s migrationsError (#2898) (database)
  • chore(db): dbWriteBarrier drain latch does not cold-start on a same-process DB reopen (#2896) (database)
  • chore(db): logged swallow for retention-cleanup catch blocks in event repositories (CLAUDE.md convention) (#2894)
  • chore(db): consume err.cause.code for a BUSY/constraint-aware SQLite retry (follow-up to #2793) (#2874) (database)
  • refactor(ios): finish control-proxy typed-model cleanups (dead CommandError cases, enum-derived responseType, WebSocketServer test) (#2859) (ios, dead-code)
  • test(ios): add control-proxy wire-parity drift tripwire + fix request_voiceover_action mismatch (#2857) (ios, testing)
  • refactor(ios): migrate control-proxy off the flat WebSocketRequest bag to a typed command model (#2846) (ios, dead-code)
  • refactor(scripts): extract scripts/lib/file-selection.sh to de-duplicate validate/apply git file-selection (#2823) (devxp)
  • refactor(scripts): extract scripts/lib/tool-install.sh to de-duplicate installer boilerplate (#2822) (devxp)
  • refactor(desktop-core): decompose 4898-line AutoMobileContent.kt into per-concern sibling files (#2820) (android)
  • chore(desktop-core): delete dead unified/ socket-client package (~1498 LOC, zero references) (#2819) (android, dead-code)
  • refactor(control-proxy): extract dispatchGestureWithResult helper; de-duplicate 5 gesture callback/perf blocks in CtrlProxy.kt (#2817) (android)
  • perf(db): batch getFailureGroups/getSampleOccurrences N+1 queries into grouped IN(…) lookups (#2810) (performance)
  • refactor(server): decompose registerDeviceAware handler pipeline + replace boolean-trap signature with options bag (#2804)
  • chore(db): closeDatabase() leaves migration flags set, so a same-process reopen would skip migration gating (#2796) (database)
  • chore(db): harden bunSqliteDialect — nested-txn deadlock guard, preserve SqliteError cause/stack, word-boundary RETURNING detection (#2793) (database)
  • refactor(plan): extract executeStep to de-duplicate PlanExecutor step pipeline; replace createCombinedSignal with AbortSignal.any (#2783)
  • refactor(ios): extract ProcessSupervisor to de-duplicate xctest/iproxy supervisor stacks in IOSCtrlProxyManager (#2770) (ios)
  • chore(android-cmdline-tools): remove dead installAndroidTools, dedupe AvdManager interface, fix [object Object] AVD error (#2769) (android, dead-code)
  • refactor(video): extract shared ChildProcessTracker; de-duplicate exit-tracking across ffmpeg/platform backends (#2767) (video)
  • ci: enable tsc type-checking in CI (unblock tsc, triage 548 hidden type errors, then gate) (#2766) (ci)
  • refactor(observe/android): consolidate scattered telemetry/crash ingestion in AndroidCtrlProxyClient behind SdkEventIngestor (#2764) (android)
  • refactor(observe/ios): extract wire-decode module + IosSdkEventIngestor from 2147-line IOSCtrlProxyClient (#2763) (ios)
  • refactor(observe): standardize AdbClientFactory injection, remove factory-vs-executor sniff across 11 observe classes (#2754) (android)
  • refactor(models): introduce BaseActionResult to collapse ~65 duplicated action Result types (#2753)
  • refactor(android): finish WebSocketServer typed-handler migration in control-proxy (retire LegacyWebSocketRequest) (#2752) (android, dead-code)

Fixed

  • observe: occludedByViewId never populates — occluder’s stable view-id is dropped in the Android runner occlusion pass (#3536) (android)
  • AppLifecycleMonitor.isPackageRunning swallows ADB errors → emits phantom “terminate” lifecycle events (#3515)
  • fix(observe): fail fast on iOS activityName-only waitFor instead of silent timeout (#3512) (ios)
  • Silent error-swallowing catch blocks violate the CLAUDE.md convention; add a lint backstop (#3508) (maintenance)
  • NavigateTo: missing await on shouldUseBackButton leaves smart back-button nav dead in production (#3445)
  • PK-keyed inserts crash on duplicate/concurrent create (deviceSnapshot, videoRecording) (#3404) (database)
  • testExecutionRepository.recordExecution: wrap multi-insert in a transaction (atomicity) (#3403) (database)
  • Daemon health check never probes the DB (post-startup liveness gap) (#3402) (database)
  • startDevice (Android cold-boot) returns wrong deviceId + false isReady when another emulator is already running (#3393) (android)
  • postNotification (Android) targets stale getCachedActiveWindow() and ignores explicit appId → delivers to wrong package (#3392) (android)
  • Daemon shutdown mid-startup-migration doesn’t await in-flight migrations before closeDatabase() (#3044)
  • JimpCliBackend wiring + drop jimp/wasm-webp + Windows smoke (closes #2974) (#3012) (performance, javascript)
  • Windows CI: databaseLazyPath + dbWriteBarrierResetOnClose file-DB tests still flake (EBUSY/livelock) despite #2916/#2923 (#2992)
  • jimp image tests fail locally (bun/macos-arm64) while passing in CI (#2971) (javascript)
  • test(nav): isolate NavigationGraphManager.test.ts singleton-backed blocks to fix cold-first-run flakiness (#2969)
  • fix(db): transactionalize promoteSuggestion + recordHierarchyNavigation graph writes (siblings of #2791) (#2968) (database)
  • Flaky CI: windows-latest file-backed SQLite close/reopen tests (EBUSY/livelock) intermittently fail (#2916) (database)
  • Flaky CI: DefaultProcessExecutor “exec captures stdout” times out (30s) on macos-latest; spawns real subprocess (#2914)
  • iOS runner: widen gesture request coordinate fields to Double (Int decode + roundCoordinates:false is a latent robustness gap) (#2909) (ios)
  • fix(db): migration columns store literal “datetime(‘now’)” instead of a timestamp (48 columns, 24 migrations) (#2895) (database)
  • fix(db): route NavigationGraphManager shutdown write through the DB-write barrier without perturbing nav/hierarchy ordering (follow-up to #2792) (#2885) (maintenance, database)
  • fix(db): wrap FailureAnalyticsRepository.recordFailure in a single transaction (close count-ahead-of-occurrence window) (#2877) (database)
  • fix(cli): direct-mode DB guard transiently over-refuses during daemon startup (publish dbPath before DB open) (#2871) (database)
  • fix(daemon): daemon process detection is POSIX-only (ps), breaking singleton enforcement + forcing direct-mode guard fail-open on Windows (#2870)
  • fix: 6 remaining TS2304 out-of-scope identifiers (2 latent runtime ReferenceErrors in Capture/RestoreSnapshot) (#2866)
  • fix(cli): refuse –no-proxy/–direct when a live daemon already owns auto-mobile.db (#2795) (database)
  • fix(db): guard runMigrations with a cross-process lock so two DB openers can’t trip a spurious startup failure (#2794) (database)
  • fix(db): drain in-flight DB writes before closeDatabase() so shutdown cannot strand on Kysely ConnectionMutex (#2792) (maintenance, database)
  • fix(db): make NavigationGraphManager.recordNavigationEvent graph write transactional (#2791) (database)
  • fix(db): non-transactional get-or-create / read-modify-write races across coverage, navigation, prediction, and appearance repositories (#2790) (database)
  • fix(db): add UNIQUE index on failure_groups.signature and make recordFailure an atomic upsert (#2789) (database)
  • fix(db): reset failed migrationsPromise and surface a cached startup error synchronously so a floating rejection can’t kill the daemon (#2786) (database)
  • fix(db): destructive migration auto-recovery (default-on) can DROP every table on a populated database (#2785) (database)
  • fix(daemon): make startup DB/migration failure fatal so the daemon doesn’t run query-dead while reporting healthy (#2784) (database)
  • fix(talkback): FocusNavigationExecutor.navigateToElement throws ReferenceError on zero-swipe path (accessibilityService out of scope) (#2765) (android, a11y)
  • fix(ios): setDeviceState binary Do Not Disturb does not verify on iOS 18.6 simulator (notifyutil read-back unchanged) (#2545) (ios)

Other

  • chore: retire historical catch logging lint allowlist (#3532)
  • tapOn: no way to target the Nth of several matching elements (repeated controls with no unique text) (#3524)
  • tapOn –sibling can’t reach a row’s action control when the row’s label is nested (#3522)
  • Expose occluding node view-id in observe hierarchy (#3519)
  • macOS development installer CI misses runtime dependencies (#3500)
  • Use app-scoped Android locale changes when targeting an app (#3492)
  • Avoid import-time failure for malformed asset mirror config (#3491)
  • Remove host-control Docker remote device support (#3485)
  • feat(output-artifacts): extend artifact mode to non-observation heavy outputs (#3481)
  • feat(output-artifacts): add startup config and per-call directory validation (#3482)
  • feat(output-artifacts): artifact all agent-facing observation payloads (#3480)
  • feat(output-artifacts): define artifact writer and response metadata contract (#3483)
  • Reduce keyed JSON config wrappers to one repository (#3463)
  • perf: fold observe element collection into a single traversal (#3456)
  • Tools Use File Output Mode (#3455)
  • perf: SharpBackend materializes a full Buffer between every pipeline operation (#3431) (performance)
  • perf: TestCoverageAnalyzer recomputes entry points + multi-source BFS per gap (~O(gaps*V*E)) (#3424) (performance)
  • perf: findPath BFS uses array-scan adjacency, Array.shift() queue, and path-array copies (#3423) (performance)
  • perf: Explore main loop calls full exportGraph() every iteration just to count nodes (#3422) (performance)
  • perf: findPath enriches ALL edges with 4 DB queries each before running BFS (#3421) (performance, database)
  • perf: cleanupIosXCTestHierarchy re-walks each subtree at every ancestor level (O(n*depth)) (#3420) (ios, performance)
  • Extend daemon recovery for DB health probe failures (#3416)
  • Fix unguarded DB RMW follow-ups from concurrency audit (#3415)
  • Periodic PRAGMA optimize / ANALYZE for query-planner stats (#3407) (performance, database)
  • Set cheap unset SQLite pragmas (cache_size, mmap_size, temp_store) (#3406) (performance, database)
  • Track Android cold-boot emulator deviceId without relying on AVD name resolution (#3399)
  • Expose optional screenshot stream performance metadata (#3389)
  • Add screenshot format and fallback metadata to observation stream (#3385)
  • Support subscriber-controlled iOS hierarchy polling cadence (#3381)
  • Support subscriber-controlled Android hierarchy throttling (#3380)
  • Add hierarchyIntervalMs to observation stream subscriptions (#3379)
  • startDevice reports a device as booted before the OS has finished booting (#3334)
  • Add configurable live observation cadence for stream subscribers (#3333)
  • Flaky: stripToolResultWireBoundary.test.ts DEBUG-gate trace fails under full-suite ordering (#2962 test) (#3256) (flaky test, testing)
  • Investigate dead replayTools / ReplayToolsService surface (#3209)
  • Add focused ToolRegistry pipeline collaborator coverage (#3208)
  • fix(db): resolve #3176 migration typecheck errors and ratchet baseline down (#3204)
  • refactor(doctor): fold ios.ts local createExecResult clone into canonical createExecResult (#3200)
  • typecheck gate hardening: signature-swap blind spot, base-drift UX, exact TS pin, test/** scope (#3196)
  • typecheck burndown: resolve TS2300 CtrlProxyHierarchy + TS2305 missing-export clusters (ratchet #3172 AC#3) (#3195)
  • control-proxy: tighten LaunchCancellationScanner to flag conditional rethrows in broad catches (#3192) (android)
  • control-proxy: generalize CancellationException-swallow scan beyond the curated suspend-fn list (#3191) (android)
  • Follow up: clear hierarchy request owners after uncorrelated observe completions (#3190)
  • ci(image): investigate intermittent Ubuntu Bun image runtime smoke null-reference failure (#3189)
  • Follow up physical iOS all reset for every XCUIProtectedResource (#3188)
  • test-infra: decide keep-vs-retire the unit-test DB guard’s opt-in fallback (flag + preload + #3117 tripwire) after arm-by-default (#3140 follow-up) (#3185)
  • perf(db): cap structured-JSON large-text columns at the telemetry backfill boundary (os/layout/failure) (#3182) (performance, database)
  • Track control-proxy lintDebug failures (#3181)
  • perf(telemetry): capture & emit prior UserDefaults value from iOS CtrlProxy runner (follow-up to #3000) (#3174) (performance)
  • Normalize storage_events.value_type vocabulary across iOS/Android (#3173) (database)
  • Add a scoped tsc –noEmit typecheck gate for src/ (fail on new errors) (#3172)
  • iOS SDK storage_changed never captures real key/value/type (KVO emits nil/”unknown”) (#3171) (database)
  • test(db): use bounded temp DB cleanup in synchronous pragma readback test (#3160) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3158) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3157) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3156) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3155) (database)
  • follow-up(ios): finish DeviceAppManager variable cleanup in IOSCtrlProxyManager (#3150) (ios)
  • Reduce MCP output token cost for agentic runs (inert –actions-no-observe, element subtree bloat, pretty-printed JSON) (#3141)
  • test-infra: make the unit-test DB guard arm-by-default (opt-out) instead of preload-opt-in (#3083 follow-up) (#3140)
  • perf(db): shared batched telemetry ingestion path (buffer + multi-row INSERT + shared EventRetentionPolicy) (#3138) (performance, database)
  • chore(db): converge telemetry-event retention onto the canonical offset(N-1)+id-tiebreak idiom (#3137) (database)
  • chore(db): extract a shared cleanupIfNeeded retention helper for the six event repos (#3136) (database)
  • test(ios): unit-test the physical-reset permission→XCUIProtectedResource mapping table (#3134) (ios, testing)
  • Android CtrlProxy: add behavioral test for EXTRACT_HIERARCHY error-frame emission (#3089 follow-up) (#3131) (android)
  • Android CtrlProxy: commandReceiver outer catch swallows CancellationException (#3130) (android)
  • Guard-test the ‘side-effects outside fn’ convention for runBothReposInTransaction (follow-up to #3075) (#3129)
  • Make ServiceScopeGuard correlation structural for raw serviceScope.launch (follow-up to #3104) (#3128) (android)
  • Add fallback-to-back-button test for DefaultUIStateSetup.dismissTopModal bottom-sheet branch (#3125)
  • refactor(ios): reduce launchApp / launchWithPayloadUrl drift in DeviceAppInspector (#3123) (ios)
  • refactor(ios): DeviceAppInspector name no longer reflects its scope (install/launch/terminate/open-URL) (#3122) (ios)
  • ci(ios): ‘Daemon failed to start within 10000ms’ flake in XCTestRunner — 10s readiness budget too small on cold macOS runners (#3110) (ios)
  • ci(ios): XCTestRunner videoRecording step fails deterministically — unit-test DB guard (#3082) trips the integration test (#3109) (ios)
  • Optional: ToolRegistry.callInternal(name, args) seam to remove the residual mark-then-call footgun (#3108)
  • Revisit structural-id content-identity adoption (limitation 1) with real-device data; optional pre-move fromKey (#3107)
  • DefaultUIStateSetup.dismissTopModal calls getTool(“swipe”) — never registered, so bottom-sheet swipe-dismiss is dead code (#3106)
  • Enforce/close the raw serviceScope.launch fire-and-forget silent-hang gap (AsyncActionRunner adoption) (#3104) (android)
  • refactor: ActionableError sweep for OpenURL / DeviceAppInspector / DeviceCtlClient result-error family (#3102)
  • refactor(ios): fold DeviceCtlClient open-URL primitive into DeviceAppInspector (dedup devicectl wrapper) (#3099) (ios)
  • Flaky: IOSCtrlProxyManager “externally managed test-without-building runner” test times out at ~5s on macOS CI (#3098)
  • observe/android: consider short-circuiting verifyServiceReady retries on a deterministic runner handler failure (#3097) (android)
  • Android CtrlProxy: correlate the ADB-broadcast fallback hierarchy request (sync_ uuid) into the wait (#3089) (android)
  • Enforce broadcast-helper guard adoption (ResultBroadcaster/AsyncActionRunner) so #3045/#3023 can’t silently regress (#3085) (android)
  • test-infra: fire-and-forget TelemetryRecorder guard-throw surfaces as an unhandled rejection, not a deterministic test failure (#3084)
  • test-infra: unit-test DB guard fails open if the bun test preload is skipped (#3083)
  • Follow-ups from withFileBackedDb harness (#3046/PR #3078): enforcement + generic cleanup + optional hooks binder (#3081)
  • docs: document the AUTOMOBILE_DB_* env-var family (follow-up from #3065/#3071) (#3079)
  • fix(ios): surface devicectl stderr diagnostic (not just “Command failed”) on physical terminate failure (#3077) (ios)
  • refactor(ios): extract a shared “process already gone” terminate-error matcher (simctl + devicectl) (#3076) (ios)
  • Extract shared two-repo runInTransaction helper for NavigationGraphManager (follow-up to #2980) (#3075)
  • test: pin the sdkNavigationAppIds skip mechanism in the SDK-screen-name preservation test (#3068)
  • test-infra: guard against unit tests resolving the real file-backed getDatabase() (#3067)
  • Guard against production AUTOMOBILE_DB_PATH=:memory: (migrated-but-empty app connection footgun) (#3065)
  • test(observe): “getLatestHierarchy > should preserve SDK screen names when hierarchy updates follow navigation events” fails on main (#3063)
  • observe/android: let requestHierarchySync surface the runner error text instead of collapsing to null (#3062) (android)
  • Android CtrlProxy: correlate request_hierarchy_if_stale (stale_ id) error frames into the hierarchy wait (#3061) (android)
  • Tech-debt: consider a protected SharedGestureDelegate.coord() so Android-only gesture overrides reuse the shared rounding (#3049) (android)
  • Test coverage: two-finger swipe concurrency + error-frame (type:”error”) resolution path (#3048) (android)
  • Move dbWriteBarrierResetOnClose barrier test to a :memory: sentinel DB (eliminate the file-handle flake class) (#3047)
  • Silent-hang when a broadcast helper’s own broadcast() throws (pre-existing, #3023-adjacent) (#3045) (android)
  • Shared withFileBackedDb test harness to enforce the DB-lifecycle flake-avoidance pattern (#3046)
  • Enforce “new async actions get correlated-error-on-throw for free” structurally (#3023 follow-up) (#3043) (android)
  • Add production-wiring guard test for CtrlProxy async launch sites (#3023 follow-up) (#3042) (android)
  • Cleanup: minor follow-ups from ImageBackend consumer migration (#3009 / PR #3036) (#3041) (javascript)
  • test(ios): cover TerminateApp observed-interaction path + fix perf.end() tree ownership (#3037) (ios)
  • Android CtrlProxy error-envelope: hierarchy handler failures still hang the awaiter (type:”error” not routed into waitForFreshData) (#3032) (android)
  • Harden: plan retry can exceed the 10-min CI step cap if an attempt hits the outer 300s callTool timeout (#3029) (ios)
  • iOS observe cold-bring-up waitFor timeout: fix root cause behind the Reminders launch/add retries (#3028) (ios)
  • Refactor: hoist RemindersIntegrationBase retry into a shared defaultRetryCount hook (#3027) (ios)
  • Android CtrlProxy: async action failures inside launched coroutines still hang the awaiter (#3023) (android)
  • Android CtrlProxy error-envelope: iOS parity (rewriteUnknownCommandError, out-of-range legibility, targeted send) (#3022) (android)
  • Android CtrlProxy: decode failures send no wire error frame (silent drop) — mirror iOS #2986 field-attributed decode errors (#3017) (android)
  • Minimal Bun repro for sharp 0.35.x-under-Bun abort (non-blocking upstream) (#3014) (dependencies)
  • doctor image-backend check + cache-portability contract docs (#3013) (devxp, javascript)
  • cwebp/dwebp provisioning: bundle libwebp binaries + CliWebpCodec (#3011) (devxp, javascript)
  • SharpBackend + pin sharp 0.34.5/@img + dependabot ignores + build externals (macOS/Linux) (#3010) (performance, dependencies, javascript)
  • Migrate pixel consumers (PerceptualHasher/ScreenshotComparator/ContrastChecker/image-utils) to ImageBackend (#3009) (javascript)
  • Image backend seam: ImageBackend interface + declarative ImageTransformer + FakeImageBackend (#3008) (devxp, javascript)
  • ktfmt: make version-pin comparison robust to 2-part vs 3-part version strings (follow-up to #2993) (#3004)
  • ktfmt: make merge.yml full-tree ktfmt a branch-protection required check (follow-up to #2966) (#3003)
  • fix(ios): recordStorageEvent call passes undeclared ‘operation’ and omits required valueType/changeType (masked by Bun no-typecheck) (#3001) (database)
  • perf(telemetry): emit prior storage value from CtrlProxy runners to skip recordStorageEvent lookup (#3000) (performance, database)
  • Flaky: XCTestRunner Simulator ‘RemindersLaunchPlanTests’ observe waitFor timeout reds non-required CI (#2998) (ios)
  • Tech debt: extract shared bind-both-repos transaction helper in NavigationGraphManager when a 4th caller lands (Devin §4) (#2994)
  • iOS parity: guard non-finite pinch rotationDegrees in CtrlProxy CommandHandler (mirror Android #2964 / PR #2984) (#2991) (testing)
  • Android two-finger swipe result correlation is orphaned — resolves only via 5s timeout (handleTwoFingerSwipeResult has no caller) (#2988) (android)
  • iOS runner: extend decode-error legibility to typeMismatch/valueNotFound (field-attributed) — #2965 option 2 (#2986) (ios)
  • Android CtrlProxy runner swallows decode/handler failures — no error envelope sent to client (#2985) (android)
  • Make NavigationGraphManager.promoteSuggestion atomic (partial-write on mid-sequence throw) (#2981)
  • Harden recordHierarchyNavigation: guard + transactionalize the coverage-repo enlistment (follow-up to #2968) (#2980)
  • validate_ktfmt.sh: add set -euo pipefail + explicit process-substitution error handling (#2967)
  • ktfmt: enforce the pinned formatter version so version drift can’t silently land on red main (#2966)
  • iOS runner: opaque decode-boundary error for out-of-range numeric literals (1e309) — surface an actionable message (#2965) (ios)
  • Android runner: reject non-finite gesture coordinates (isFinite guard) — mirror iOS #2928, load-bearing on the kotlinx wire (#2964) (android, testing)
  • refactor(ios): merge redundant CtrlProxyVoiceOverActionResult into CtrlProxyActionResult (#2956) (ios)
  • test(ios): make control-proxy wire-parity scan structural (AST) + import-graph-derived, not regex/adjacency-based (#2955) (ios, testing)
  • test(ios): field-name wire-parity backstop for control-proxy (JSON snapshot fixtures) (#2954) (ios, testing)
  • Release: re-cut iOS CtrlProxy runner + update checksum registry to deliver the #2910 pinch fallback (#2953) (ios)
  • test(db): tripwire so a non-Windows bun:sqlite handle-leak can’t hide behind removeTempDbDir’s silent give-up (#2949) (database)
  • test(db): consolidate remaining sync best-effort temp-dir cleanup (backupDatabaseFile) into a removeTempDbDirSync helper (#2948) (database)
  • refactor(utils): consolidate DefaultProcessExecutor / DefaultHostCommandExecutor duplication + unify exec-seam type export (#2945)
  • refactor(db): extract a single EVENT_TABLES constant to de-duplicate the telemetry event-table list (follow-up to #2918) (#2943) (performance)
  • Add real-pixel regression tests for the jimp image pipeline (#2939) (testing, javascript)
  • chore(db): upgraded-DB parity for updated_at defaults (repair migration + relax type) (#2937) (database)
  • iOS runner: reject non-finite gesture coordinates (isFinite guard) at the decode/handler boundary (#2928) (ios)
  • Android runner: widen gesture request coordinate fields to Double (symmetric to iOS #2909) (#2927) (android)
  • chore(db): reconcile updated_at columns declared notNull with no default (asymmetric with created_at) (#2913) (database)
  • perf(db): add a CI drift guard for the telemetry event tables’ index inventory (follow-up to #2893) (#2908) (performance)
  • Follow up Codex skill metadata location for .agents wrapper (#2901)
  • perf(db): drop now-redundant single-column device indexes on telemetry event tables (follow-up to #2788) (#2893) (performance)
  • test(ios): hermetic LaunchApp-level coverage for clearAppData on a physical device (#2884) (ios)
  • Testing: regenerate #2755 observe baseline from a raw capture to exercise node-trim on real data (#2879) (performance, testing)
  • docs(db): document migration corrupted-recovery flow + AUTOMOBILE_MIGRATION_RECOVERY (=true vs =1) semantics (#2869) (documentation, database)
  • fix(db): duplicate date-prefixed migration filenames make Kysely ordering fragile (#2868) (database)
  • Guard MIGRATION_RUNTIME_DEPENDENCIES against drift from migration runtime imports (#2867) (devxp)
  • notifyutil: verify whether the -1 registration is actually required for notify_set_state (helper + comments may overstate it) (#2864) (ios, devxp)
  • optional plan-step primitive: parallel-track observability + log-export round-trip (#2863) (testing)
  • ci(ios): XCTestRunner Simulator Tests builds stale committed CtrlProxy.xcodeproj (no xcodegen regen) (#2858) (ios, ci)
  • Reminders add-reminder plan is pinned to CI’s iOS Reminders labels (Done/New Reminder, English) (#2855) (flaky test, ios, testing)
  • iOS CtrlProxy runner lifecycle: extract teardown/identity primitive + pre-existing kill-scoping fixes (#2847)
  • feat(observe): richer waitFor predicates + activeWindow conditions + stability gate (#2845)
  • Daemon startup DB migration hard-fails when bunx extraction is missing a transitive dep (e.g. kysely) (#2833)
  • nightly: PR title/body don’t reflect a runner-only SHA256 change (#2816)
  • Supply-chain hardening for hermetic pinning: acceptedPreinstalled mismatch + mirror URL validation (#2815)
  • iOS: bake a version constant into the XCTestRunner SPM package (#2814)
  • Enforce the version pin across a reused/shared daemon (PID-file stamp + client mismatch fail) (#2812)
  • Flaky: RemindersAddPlanTests.testAddReminderPlan (UI ‘Done’ tap race at plan step 5) (#2811) (flaky test, ios, testing)
  • Versioning: resolve (or formally accept) the -SNAPSHOT coordinate divergence for local Gradle builds (#2807)
  • Release integrity: store iOS runner SHA256 per registry entry (not a global scalar) (#2806)
  • perf(db): WAL hygiene — set journal_size_limit and checkpoint(TRUNCATE) on close (#2802) (performance, database)
  • perf(db): truncate request/response bodies in the getNetworkEvents list projection (#2801) (performance, database)
  • perf(db): batch N+1 query fan-out in getFailureGroups and getTestRuns (dashboard read paths) (#2800) (performance, database)
  • perf(db): amortize per-insert retention COUNT(*) in event repositories (#2799) (performance, database)
  • perf(db): add covering index for recordStorageEvent previous-value lookup (#2798) (performance, database)
  • perf(db): add a bounded prepared-statement cache to the Bun SQLite dialect (#2797) (performance, database)
  • perf(db): add composite (device_id, timestamp) indexes to telemetry event tables to eliminate ORDER BY filesorts (#2788) (performance, database)
  • perf(db): set PRAGMA synchronous = NORMAL under WAL to stop per-commit fsync on the telemetry write stream (#2787) (performance, database)
  • Output reduction 0: measurement harness (fixture + byte-breakdown script) (#2755) (devxp, performance, testing)
  • Provide hermetic single-version CI pinning for all clients (daemon + ctrlproxy APK/IPA + junit-runner + XCTestRunner) (#2746)
  • Shared per-uid daemon socket is unguarded for non-TS clients (JUnit/XCTest) — add server-side version/build-identity handshake (#2744)
  • Release integrity: iOS runner-binary checksum never wired (verification disabled) + no version-equality release gate (#2745)
  • Multiple checkouts share one per-uid daemon socket → wrong-build daemon serves frontend (version skew, opaque “Unknown tool” -32603) (#2732)
  • Evaluate Compose interop hidden-region text heuristic with real-world data (#2634)
  • feat(ios): invoke custom accessibility actions via tapOn (#2265)
  • No loading-awareness when refreshing element position before tap (#1949)

[v0.0.41] - 2026-07-07

Added

  • Implement daemon text and key input endpoints (#3343) (android, ios)
  • Implement daemon input/pressButton endpoint (#3342) (android, ios)
  • Implement daemon input/swipe endpoint (#3341) (android, ios)
  • Implement daemon input/tap endpoint (#3340) (android, ios)
  • Define daemon Unix socket input API contract (#3339)
  • actions-diff-observe iOS: improve stable node identity beyond positional paths (#3318) (ios, performance)
  • iOS observe output: collapse XCTest/UIKit structural noise before action diffs (#3317) (ios, performance)
  • actions-diff-observe: report why a diff was skipped or emitted (#3316) (devxp, performance)
  • actions-diff-observe iOS: gate same-screen diffs on screenIdentity (#3315) (ios, performance)
  • actions-diff-observe iOS: derive fallback screenIdentity from accessibility hierarchy (#3314) (ios, performance, a11y)
  • Capture-layer stable node identity to shrink scroll diffs (opaque id-less rows) (#3228)
  • Forward + broadcast tools/list_changed & resources/list_changed across proxy and multi-session daemon (follow-up to #2963) (#3223)
  • Thread StructuredToolResponse through the tool registry (remove the asToolEnvelope unchecked cast) (#3222)
  • Dead observe screenshot cache chain: setLastScreenshot never fires, lastScreenshot never read (#3221)
  • Extend SessionCacheData escape-hatch guard to forbid setter-bypass slot writes in production code (follow-up to #2973) (#3219)
  • Follow-up #2962: consider structured log fields for the structuredContent-omission trace (#3216)
  • Follow-up #2962: directly test INFO-level suppression of the structuredContent-omission debug trace (#3215)
  • Complete or remove the incomplete declare-module “zod” stub forcing schema code into the typecheck baseline (#3207)
  • elementBoundsSchema advertises integer bounds but iOS coordinates are fractional points (#3206)
  • iOS storage telemetry value fidelity: lossy “(value)” stringification for Data/Date/array/dictionary (#3194) (ios)
  • iOS UserDefaults change telemetry has no production trigger (startListening never called) + standard-suite NSGlobalDomain noise (#3193) (ios)
  • feat(video): name recording files/folders by caller-supplied outputName (not just recordingId UUID) (#3145) (video)
  • Surface Compose toggle state (checked/selected/stateDescription) in the extracted view hierarchy (#3139)
  • feat(ios): return a physical-aware failure for getAppPermissions on physical iOS devices (#3135) (ios)
  • feat(ios): support the all privacy keyword for physical-device permission reset (#3133) (ios)
  • Explore structural-id content identity for in-place edits + optional pre-move key in diff (follow-up to #3053 part 1) (#3088)
  • Mark navigation/setup internal tool calls no-diff (DefaultUIStateSetup, NavigateTo) — baseline pollution under –actions-diff-observe (#3087)
  • actions-diff-observe: add a byte-size regression guard for element-field diffs (follow-up to #3059) (#3064)
  • feat(ios): unify device app-listing (ListInstalledApps devicectl parity) for terminate/uninstall wasInstalled (#3057) (ios)
  • feat(ios): explicit iOS<=16 ‘requires iOS 17+’ error for physical terminateApp/launchApp (#3056) (ios)
  • fix(ios): tolerate already-exited PID on devicectl device terminate (avoid false success:false) (#3054) (ios)
  • actions-diff-observe: positional node key cascades on scroll/insert; explore stable node identity + internal-consumer diff exposure (#3053)
  • actions-diff-observe: diff omits top-level focusedElement / accessibilityFocusedElement / awaitedElement changes (#3052)
  • actions-diff-observe: sign off the diff format on real-device output (#3026 acceptance) (#3051)
  • Dormant output-reduction flags: –actions-diff-observe and –actions-no-observe are plumbed but have no consumer (#3026)
  • observe tool has no outputSchema — advertise ObserveResult (incl. compact bounds tuple) on the wire (#3025)
  • Follow-up to #2997: generate golden tables from JSON + parser string-literal robustness (#3021)
  • Harden pinch-geometry parity: single-source golden vectors instead of hand-duplicated tables (follow-up to #2979) (#2997) (ios)
  • observeResultCompact follow-ups: actionsDiffObserve composition test + wire-schema tuple doc (#2990) (performance)
  • Add executable guard for iOS pinch geometry (parity with Android computePinchPoints) (#2979) (ios)
  • observeResultCompact: resolve mixed bounds representation (node tuples vs. object elements/root/window bounds) (#2978) (performance)
  • Promote well-known customData keys (keep-awake, device-label) to typed SessionCacheData slots (follow-up to #2917) (#2973)
  • Type or remove the dormant lastActionTime session-cache write (follow-up to #2917) (#2972)
  • Emit tools/list_changed when output-reduction flags toggle at runtime (follow-up to #2759) (#2963)
  • Output reduction: debug-log intentional structuredContent omission (follow-up to #2759) (#2962)
  • Wire observeResultCompact flag into sanitizeObserveResult (flag plumbed but dormant) (#2951) (performance)
  • Durable typed-envelope: re-type the ToolHandler boundary so envelope payload dead-reads are a compile error (#2932)
  • SessionCacheData typed lastHierarchy/lastScreenshot slots are dormant decoys; real data lives in customData with a different type (#2917)
  • pinchOn rotationDegrees: document or fix start-horizontal/end-rotated axis convention (Android + iOS) (#2911) (ios)
  • iOS pinchOn: add public pinch(withScale:velocity:) fallback when private XCTest event-synth symbols are unavailable (#2910) (ios)
  • Typed accessor / typed envelope to eliminate the envelope-vs-structuredContent dead-read bug class (#2907)
  • Wire toolResultsNoStructuredContent flag into finalizeToolResponse (flag plumbed but dormant) (#2899) (performance)
  • Latent bug: swipeOn scroll-position update reads response?.found off the MCP envelope (always undefined) (#2897)
  • feat(ios): terminateApp physical-device support (currently a silent success no-op) (#2882) (ios)
  • Output reduction: extend observe perf-strip to top-level perfTiming/gfxMetrics (#2878) (performance)
  • Automatically recover from an incomplete bunx extraction (consume the EX_TEMPFAIL / exit-code 75 signal) (#2865) (devxp)
  • iOS DND: replace version gate with behavior-based (write→independent readback) detection (#2861) (ios)
  • Output reduction 7: strip embedded observation (–actions-no-observe) (#2762) (performance)
  • Output reduction 6: observe diff for non-observe tools (–actions-diff-observe) (#2761) (performance)
  • Output reduction 5: compact/TOON observe encoding (–observe-result-compact) (#2760) (performance)
  • Output reduction 4: gate structuredContent duplication (drop for no-schema tools) (#2759) (performance)
  • Output reduction 3: finalizeToolResponse hook + lastHierarchy cache repair (#2758) (performance)
  • Output reduction 2: sanitizeObserveResult (perf-strip + node-trim + elements-drop) (#2757) (performance)
  • Output reduction 1: config plumbing for output-reduction flags (CLI + env) (#2756) (performance)
  • feat(ios): setAppPermissions — reset privacy permissions on physical iOS devices via the CtrlProxy XCUITest runner (#2491) (ios, research)
  • feat(ios): openLink — open URLs/deep links on physical iOS devices via devicectl (#2490) (ios)
  • feat(ios): listApps — enumerate installed apps on physical devices via devicectl (#2489) (ios)
  • feat(ios): terminateApp — physical-device termination via devicectl (#2488) (ios)
  • feat(ios): launchApp — physical-device launch/terminate via devicectl (#2487) (ios)
  • feat(ios): pinchOn — coordinate-based pinch/zoom via XCUITest CtrlProxy runner (#2482) (ios)

Changed

  • Dead Code Detection: Threshold Exceeded (#3257) (automated, dead-code)
  • refactor(ios): extract IOSCtrlProxyManager port health and host-control collaborators (#3218) (ios)
  • Follow-up to #2885: SessionManager barrier comment, in-process reopen reset, and trackExisting direction re-eval (#3154) (database)
  • test(db): databaseLazyPath + dbWriteBarrierResetOnClose flake (timeout) on windows-latest CI (file-backed sqlite) (#3030) (database)
  • chore(db): fileLock hardening follow-ups from PR #2995 (release incarnation-awareness + positional-format contract) (#3006) (database)
  • Remove pre-existing dead Image facade methods (transform/disableCache) (#2970) (javascript, dead-code)
  • chore(db): in-process same-path reopen can steal an in-flight migration’s own-PID lock (reclaimOwnPid) (#2947) (database)
  • chore(db): consolidate migration-state module globals into a single MigrationState + reset() (#2944) (database)
  • test(db): reset-test files bleed process.env across the suite → intermittent databaseReset.test.ts flake (#2942)
  • db: guard migration-lifecycle against a startMigrations run that settles after closeDatabase() reset (#2940) (database)
  • Trim unused ImageUtils/Image surface left over from the sharp→jimp migration (#2938) (javascript, dead-code)
  • refactor(db): consolidate closeDatabase() reset checklist behind a single resetDbLifecycleState() (#2935) (database)
  • docs(db): two inaccurate comments left by #2905 (test ‘fully true’ over-claim + null-swap safety rationale omits use-time throw) (#2934) (documentation, database)
  • chore(db): dbWriteBarrier reset is identity-swap — construction-captured consumers keep the drained barrier across a same-process reopen (#2912) (database)
  • refactor(db): encapsulate migration-lifecycle module globals into a single resettable state object (#2900) (database)
  • chore(db): no generation fence — an in-flight migration completing after closeDatabase() can stomp the next generation’s migrationsError (#2898) (database)
  • chore(db): dbWriteBarrier drain latch does not cold-start on a same-process DB reopen (#2896) (database)
  • chore(db): logged swallow for retention-cleanup catch blocks in event repositories (CLAUDE.md convention) (#2894)
  • chore(db): consume err.cause.code for a BUSY/constraint-aware SQLite retry (follow-up to #2793) (#2874) (database)
  • refactor(ios): finish control-proxy typed-model cleanups (dead CommandError cases, enum-derived responseType, WebSocketServer test) (#2859) (ios, dead-code)
  • test(ios): add control-proxy wire-parity drift tripwire + fix request_voiceover_action mismatch (#2857) (ios, testing)
  • refactor(ios): migrate control-proxy off the flat WebSocketRequest bag to a typed command model (#2846) (ios, dead-code)
  • refactor(scripts): extract scripts/lib/file-selection.sh to de-duplicate validate/apply git file-selection (#2823) (devxp)
  • refactor(scripts): extract scripts/lib/tool-install.sh to de-duplicate installer boilerplate (#2822) (devxp)
  • refactor(desktop-core): decompose 4898-line AutoMobileContent.kt into per-concern sibling files (#2820) (android)
  • chore(desktop-core): delete dead unified/ socket-client package (~1498 LOC, zero references) (#2819) (android, dead-code)
  • refactor(control-proxy): extract dispatchGestureWithResult helper; de-duplicate 5 gesture callback/perf blocks in CtrlProxy.kt (#2817) (android)
  • perf(db): batch getFailureGroups/getSampleOccurrences N+1 queries into grouped IN(…) lookups (#2810) (performance)
  • refactor(server): decompose registerDeviceAware handler pipeline + replace boolean-trap signature with options bag (#2804)
  • chore(db): closeDatabase() leaves migration flags set, so a same-process reopen would skip migration gating (#2796) (database)
  • chore(db): harden bunSqliteDialect — nested-txn deadlock guard, preserve SqliteError cause/stack, word-boundary RETURNING detection (#2793) (database)
  • refactor(plan): extract executeStep to de-duplicate PlanExecutor step pipeline; replace createCombinedSignal with AbortSignal.any (#2783)
  • refactor(ios): extract ProcessSupervisor to de-duplicate xctest/iproxy supervisor stacks in IOSCtrlProxyManager (#2770) (ios)
  • chore(android-cmdline-tools): remove dead installAndroidTools, dedupe AvdManager interface, fix [object Object] AVD error (#2769) (android, dead-code)
  • refactor(video): extract shared ChildProcessTracker; de-duplicate exit-tracking across ffmpeg/platform backends (#2767) (video)
  • ci: enable tsc type-checking in CI (unblock tsc, triage 548 hidden type errors, then gate) (#2766) (ci)
  • refactor(observe/android): consolidate scattered telemetry/crash ingestion in AndroidCtrlProxyClient behind SdkEventIngestor (#2764) (android)
  • refactor(observe/ios): extract wire-decode module + IosSdkEventIngestor from 2147-line IOSCtrlProxyClient (#2763) (ios)
  • refactor(observe): standardize AdbClientFactory injection, remove factory-vs-executor sniff across 11 observe classes (#2754) (android)
  • refactor(models): introduce BaseActionResult to collapse ~65 duplicated action Result types (#2753)
  • refactor(android): finish WebSocketServer typed-handler migration in control-proxy (retire LegacyWebSocketRequest) (#2752) (android, dead-code)

Fixed

  • Daemon shutdown mid-startup-migration doesn’t await in-flight migrations before closeDatabase() (#3044)
  • JimpCliBackend wiring + drop jimp/wasm-webp + Windows smoke (closes #2974) (#3012) (performance, javascript)
  • Windows CI: databaseLazyPath + dbWriteBarrierResetOnClose file-DB tests still flake (EBUSY/livelock) despite #2916/#2923 (#2992)
  • jimp image tests fail locally (bun/macos-arm64) while passing in CI (#2971) (javascript)
  • test(nav): isolate NavigationGraphManager.test.ts singleton-backed blocks to fix cold-first-run flakiness (#2969)
  • fix(db): transactionalize promoteSuggestion + recordHierarchyNavigation graph writes (siblings of #2791) (#2968) (database)
  • Flaky CI: windows-latest file-backed SQLite close/reopen tests (EBUSY/livelock) intermittently fail (#2916) (database)
  • Flaky CI: DefaultProcessExecutor “exec captures stdout” times out (30s) on macos-latest; spawns real subprocess (#2914)
  • iOS runner: widen gesture request coordinate fields to Double (Int decode + roundCoordinates:false is a latent robustness gap) (#2909) (ios)
  • fix(db): migration columns store literal “datetime(‘now’)” instead of a timestamp (48 columns, 24 migrations) (#2895) (database)
  • fix(db): route NavigationGraphManager shutdown write through the DB-write barrier without perturbing nav/hierarchy ordering (follow-up to #2792) (#2885) (maintenance, database)
  • fix(db): wrap FailureAnalyticsRepository.recordFailure in a single transaction (close count-ahead-of-occurrence window) (#2877) (database)
  • fix(cli): direct-mode DB guard transiently over-refuses during daemon startup (publish dbPath before DB open) (#2871) (database)
  • fix(daemon): daemon process detection is POSIX-only (ps), breaking singleton enforcement + forcing direct-mode guard fail-open on Windows (#2870)
  • fix: 6 remaining TS2304 out-of-scope identifiers (2 latent runtime ReferenceErrors in Capture/RestoreSnapshot) (#2866)
  • fix(cli): refuse –no-proxy/–direct when a live daemon already owns auto-mobile.db (#2795) (database)
  • fix(db): guard runMigrations with a cross-process lock so two DB openers can’t trip a spurious startup failure (#2794) (database)
  • fix(db): drain in-flight DB writes before closeDatabase() so shutdown cannot strand on Kysely ConnectionMutex (#2792) (maintenance, database)
  • fix(db): make NavigationGraphManager.recordNavigationEvent graph write transactional (#2791) (database)
  • fix(db): non-transactional get-or-create / read-modify-write races across coverage, navigation, prediction, and appearance repositories (#2790) (database)
  • fix(db): add UNIQUE index on failure_groups.signature and make recordFailure an atomic upsert (#2789) (database)
  • fix(db): reset failed migrationsPromise and surface a cached startup error synchronously so a floating rejection can’t kill the daemon (#2786) (database)
  • fix(db): destructive migration auto-recovery (default-on) can DROP every table on a populated database (#2785) (database)
  • fix(daemon): make startup DB/migration failure fatal so the daemon doesn’t run query-dead while reporting healthy (#2784) (database)
  • fix(talkback): FocusNavigationExecutor.navigateToElement throws ReferenceError on zero-swipe path (accessibilityService out of scope) (#2765) (android, a11y)
  • fix(ios): setDeviceState binary Do Not Disturb does not verify on iOS 18.6 simulator (notifyutil read-back unchanged) (#2545) (ios)

Other

  • Support subscriber-controlled iOS hierarchy polling cadence (#3381)
  • startDevice reports a device as booted before the OS has finished booting (#3334)
  • Add configurable live observation cadence for stream subscribers (#3333)
  • Flaky: stripToolResultWireBoundary.test.ts DEBUG-gate trace fails under full-suite ordering (#2962 test) (#3256) (flaky test, testing)
  • Investigate dead replayTools / ReplayToolsService surface (#3209)
  • Add focused ToolRegistry pipeline collaborator coverage (#3208)
  • fix(db): resolve #3176 migration typecheck errors and ratchet baseline down (#3204)
  • refactor(doctor): fold ios.ts local createExecResult clone into canonical createExecResult (#3200)
  • typecheck gate hardening: signature-swap blind spot, base-drift UX, exact TS pin, test/** scope (#3196)
  • typecheck burndown: resolve TS2300 CtrlProxyHierarchy + TS2305 missing-export clusters (ratchet #3172 AC#3) (#3195)
  • control-proxy: tighten LaunchCancellationScanner to flag conditional rethrows in broad catches (#3192) (android)
  • control-proxy: generalize CancellationException-swallow scan beyond the curated suspend-fn list (#3191) (android)
  • Follow up: clear hierarchy request owners after uncorrelated observe completions (#3190)
  • ci(image): investigate intermittent Ubuntu Bun image runtime smoke null-reference failure (#3189)
  • Follow up physical iOS all reset for every XCUIProtectedResource (#3188)
  • test-infra: decide keep-vs-retire the unit-test DB guard’s opt-in fallback (flag + preload + #3117 tripwire) after arm-by-default (#3140 follow-up) (#3185)
  • perf(db): cap structured-JSON large-text columns at the telemetry backfill boundary (os/layout/failure) (#3182) (performance, database)
  • Track control-proxy lintDebug failures (#3181)
  • perf(telemetry): capture & emit prior UserDefaults value from iOS CtrlProxy runner (follow-up to #3000) (#3174) (performance)
  • Normalize storage_events.value_type vocabulary across iOS/Android (#3173) (database)
  • Add a scoped tsc –noEmit typecheck gate for src/ (fail on new errors) (#3172)
  • iOS SDK storage_changed never captures real key/value/type (KVO emits nil/”unknown”) (#3171) (database)
  • test(db): use bounded temp DB cleanup in synchronous pragma readback test (#3160) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3158) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3157) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3156) (database)
  • chore(db): normalize MemoryBaselineManager retention comparison (datetime()) to match #2937 (#3155) (database)
  • follow-up(ios): finish DeviceAppManager variable cleanup in IOSCtrlProxyManager (#3150) (ios)
  • Reduce MCP output token cost for agentic runs (inert –actions-no-observe, element subtree bloat, pretty-printed JSON) (#3141)
  • test-infra: make the unit-test DB guard arm-by-default (opt-out) instead of preload-opt-in (#3083 follow-up) (#3140)
  • perf(db): shared batched telemetry ingestion path (buffer + multi-row INSERT + shared EventRetentionPolicy) (#3138) (performance, database)
  • chore(db): converge telemetry-event retention onto the canonical offset(N-1)+id-tiebreak idiom (#3137) (database)
  • chore(db): extract a shared cleanupIfNeeded retention helper for the six event repos (#3136) (database)
  • test(ios): unit-test the physical-reset permission→XCUIProtectedResource mapping table (#3134) (ios, testing)
  • Android CtrlProxy: add behavioral test for EXTRACT_HIERARCHY error-frame emission (#3089 follow-up) (#3131) (android)
  • Android CtrlProxy: commandReceiver outer catch swallows CancellationException (#3130) (android)
  • Guard-test the ‘side-effects outside fn’ convention for runBothReposInTransaction (follow-up to #3075) (#3129)
  • Make ServiceScopeGuard correlation structural for raw serviceScope.launch (follow-up to #3104) (#3128) (android)
  • Add fallback-to-back-button test for DefaultUIStateSetup.dismissTopModal bottom-sheet branch (#3125)
  • refactor(ios): reduce launchApp / launchWithPayloadUrl drift in DeviceAppInspector (#3123) (ios)
  • refactor(ios): DeviceAppInspector name no longer reflects its scope (install/launch/terminate/open-URL) (#3122) (ios)
  • ci(ios): ‘Daemon failed to start within 10000ms’ flake in XCTestRunner — 10s readiness budget too small on cold macOS runners (#3110) (ios)
  • ci(ios): XCTestRunner videoRecording step fails deterministically — unit-test DB guard (#3082) trips the integration test (#3109) (ios)
  • Optional: ToolRegistry.callInternal(name, args) seam to remove the residual mark-then-call footgun (#3108)
  • Revisit structural-id content-identity adoption (limitation 1) with real-device data; optional pre-move fromKey (#3107)
  • DefaultUIStateSetup.dismissTopModal calls getTool(“swipe”) — never registered, so bottom-sheet swipe-dismiss is dead code (#3106)
  • Enforce/close the raw serviceScope.launch fire-and-forget silent-hang gap (AsyncActionRunner adoption) (#3104) (android)
  • refactor: ActionableError sweep for OpenURL / DeviceAppInspector / DeviceCtlClient result-error family (#3102)
  • refactor(ios): fold DeviceCtlClient open-URL primitive into DeviceAppInspector (dedup devicectl wrapper) (#3099) (ios)
  • Flaky: IOSCtrlProxyManager “externally managed test-without-building runner” test times out at ~5s on macOS CI (#3098)
  • observe/android: consider short-circuiting verifyServiceReady retries on a deterministic runner handler failure (#3097) (android)
  • Android CtrlProxy: correlate the ADB-broadcast fallback hierarchy request (sync_ uuid) into the wait (#3089) (android)
  • Enforce broadcast-helper guard adoption (ResultBroadcaster/AsyncActionRunner) so #3045/#3023 can’t silently regress (#3085) (android)
  • test-infra: fire-and-forget TelemetryRecorder guard-throw surfaces as an unhandled rejection, not a deterministic test failure (#3084)
  • test-infra: unit-test DB guard fails open if the bun test preload is skipped (#3083)
  • Follow-ups from withFileBackedDb harness (#3046/PR #3078): enforcement + generic cleanup + optional hooks binder (#3081)
  • docs: document the AUTOMOBILE_DB_* env-var family (follow-up from #3065/#3071) (#3079)
  • fix(ios): surface devicectl stderr diagnostic (not just “Command failed”) on physical terminate failure (#3077) (ios)
  • refactor(ios): extract a shared “process already gone” terminate-error matcher (simctl + devicectl) (#3076) (ios)
  • Extract shared two-repo runInTransaction helper for NavigationGraphManager (follow-up to #2980) (#3075)
  • test: pin the sdkNavigationAppIds skip mechanism in the SDK-screen-name preservation test (#3068)
  • test-infra: guard against unit tests resolving the real file-backed getDatabase() (#3067)
  • Guard against production AUTOMOBILE_DB_PATH=:memory: (migrated-but-empty app connection footgun) (#3065)
  • test(observe): “getLatestHierarchy > should preserve SDK screen names when hierarchy updates follow navigation events” fails on main (#3063)
  • observe/android: let requestHierarchySync surface the runner error text instead of collapsing to null (#3062) (android)
  • Android CtrlProxy: correlate request_hierarchy_if_stale (stale_ id) error frames into the hierarchy wait (#3061) (android)
  • Tech-debt: consider a protected SharedGestureDelegate.coord() so Android-only gesture overrides reuse the shared rounding (#3049) (android)
  • Test coverage: two-finger swipe concurrency + error-frame (type:”error”) resolution path (#3048) (android)
  • Move dbWriteBarrierResetOnClose barrier test to a :memory: sentinel DB (eliminate the file-handle flake class) (#3047)
  • Shared withFileBackedDb test harness to enforce the DB-lifecycle flake-avoidance pattern (#3046)
  • Silent-hang when a broadcast helper’s own broadcast() throws (pre-existing, #3023-adjacent) (#3045) (android)
  • Enforce “new async actions get correlated-error-on-throw for free” structurally (#3023 follow-up) (#3043) (android)
  • Add production-wiring guard test for CtrlProxy async launch sites (#3023 follow-up) (#3042) (android)
  • Cleanup: minor follow-ups from ImageBackend consumer migration (#3009 / PR #3036) (#3041) (javascript)
  • test(ios): cover TerminateApp observed-interaction path + fix perf.end() tree ownership (#3037) (ios)
  • Android CtrlProxy error-envelope: hierarchy handler failures still hang the awaiter (type:”error” not routed into waitForFreshData) (#3032) (android)
  • Harden: plan retry can exceed the 10-min CI step cap if an attempt hits the outer 300s callTool timeout (#3029) (ios)
  • iOS observe cold-bring-up waitFor timeout: fix root cause behind the Reminders launch/add retries (#3028) (ios)
  • Refactor: hoist RemindersIntegrationBase retry into a shared defaultRetryCount hook (#3027) (ios)
  • Android CtrlProxy: async action failures inside launched coroutines still hang the awaiter (#3023) (android)
  • Android CtrlProxy error-envelope: iOS parity (rewriteUnknownCommandError, out-of-range legibility, targeted send) (#3022) (android)
  • Android CtrlProxy: decode failures send no wire error frame (silent drop) — mirror iOS #2986 field-attributed decode errors (#3017) (android)
  • Minimal Bun repro for sharp 0.35.x-under-Bun abort (non-blocking upstream) (#3014) (dependencies)
  • doctor image-backend check + cache-portability contract docs (#3013) (devxp, javascript)
  • cwebp/dwebp provisioning: bundle libwebp binaries + CliWebpCodec (#3011) (devxp, javascript)
  • SharpBackend + pin sharp 0.34.5/@img + dependabot ignores + build externals (macOS/Linux) (#3010) (performance, dependencies, javascript)
  • Migrate pixel consumers (PerceptualHasher/ScreenshotComparator/ContrastChecker/image-utils) to ImageBackend (#3009) (javascript)
  • Image backend seam: ImageBackend interface + declarative ImageTransformer + FakeImageBackend (#3008) (devxp, javascript)
  • ktfmt: make version-pin comparison robust to 2-part vs 3-part version strings (follow-up to #2993) (#3004)
  • ktfmt: make merge.yml full-tree ktfmt a branch-protection required check (follow-up to #2966) (#3003)
  • fix(ios): recordStorageEvent call passes undeclared ‘operation’ and omits required valueType/changeType (masked by Bun no-typecheck) (#3001) (database)
  • perf(telemetry): emit prior storage value from CtrlProxy runners to skip recordStorageEvent lookup (#3000) (performance, database)
  • Flaky: XCTestRunner Simulator ‘RemindersLaunchPlanTests’ observe waitFor timeout reds non-required CI (#2998) (ios)
  • Tech debt: extract shared bind-both-repos transaction helper in NavigationGraphManager when a 4th caller lands (Devin §4) (#2994)
  • iOS parity: guard non-finite pinch rotationDegrees in CtrlProxy CommandHandler (mirror Android #2964 / PR #2984) (#2991) (testing)
  • Android two-finger swipe result correlation is orphaned — resolves only via 5s timeout (handleTwoFingerSwipeResult has no caller) (#2988) (android)
  • iOS runner: extend decode-error legibility to typeMismatch/valueNotFound (field-attributed) — #2965 option 2 (#2986) (ios)
  • Android CtrlProxy runner swallows decode/handler failures — no error envelope sent to client (#2985) (android)
  • Make NavigationGraphManager.promoteSuggestion atomic (partial-write on mid-sequence throw) (#2981)
  • Harden recordHierarchyNavigation: guard + transactionalize the coverage-repo enlistment (follow-up to #2968) (#2980)
  • validate_ktfmt.sh: add set -euo pipefail + explicit process-substitution error handling (#2967)
  • ktfmt: enforce the pinned formatter version so version drift can’t silently land on red main (#2966)
  • iOS runner: opaque decode-boundary error for out-of-range numeric literals (1e309) — surface an actionable message (#2965) (ios)
  • Android runner: reject non-finite gesture coordinates (isFinite guard) — mirror iOS #2928, load-bearing on the kotlinx wire (#2964) (android, testing)
  • refactor(ios): merge redundant CtrlProxyVoiceOverActionResult into CtrlProxyActionResult (#2956) (ios)
  • test(ios): make control-proxy wire-parity scan structural (AST) + import-graph-derived, not regex/adjacency-based (#2955) (ios, testing)
  • test(ios): field-name wire-parity backstop for control-proxy (JSON snapshot fixtures) (#2954) (ios, testing)
  • test(db): tripwire so a non-Windows bun:sqlite handle-leak can’t hide behind removeTempDbDir’s silent give-up (#2949) (database)
  • test(db): consolidate remaining sync best-effort temp-dir cleanup (backupDatabaseFile) into a removeTempDbDirSync helper (#2948) (database)
  • refactor(utils): consolidate DefaultProcessExecutor / DefaultHostCommandExecutor duplication + unify exec-seam type export (#2945)
  • refactor(db): extract a single EVENT_TABLES constant to de-duplicate the telemetry event-table list (follow-up to #2918) (#2943) (performance)
  • Add real-pixel regression tests for the jimp image pipeline (#2939) (testing, javascript)
  • chore(db): upgraded-DB parity for updated_at defaults (repair migration + relax type) (#2937) (database)
  • iOS runner: reject non-finite gesture coordinates (isFinite guard) at the decode/handler boundary (#2928) (ios)
  • Android runner: widen gesture request coordinate fields to Double (symmetric to iOS #2909) (#2927) (android)
  • chore(db): reconcile updated_at columns declared notNull with no default (asymmetric with created_at) (#2913) (database)
  • perf(db): add a CI drift guard for the telemetry event tables’ index inventory (follow-up to #2893) (#2908) (performance)
  • Follow up Codex skill metadata location for .agents wrapper (#2901)
  • perf(db): drop now-redundant single-column device indexes on telemetry event tables (follow-up to #2788) (#2893) (performance)
  • test(ios): hermetic LaunchApp-level coverage for clearAppData on a physical device (#2884) (ios)
  • Testing: regenerate #2755 observe baseline from a raw capture to exercise node-trim on real data (#2879) (performance, testing)
  • docs(db): document migration corrupted-recovery flow + AUTOMOBILE_MIGRATION_RECOVERY (=true vs =1) semantics (#2869) (documentation, database)
  • fix(db): duplicate date-prefixed migration filenames make Kysely ordering fragile (#2868) (database)
  • Guard MIGRATION_RUNTIME_DEPENDENCIES against drift from migration runtime imports (#2867) (devxp)
  • notifyutil: verify whether the -1 registration is actually required for notify_set_state (helper + comments may overstate it) (#2864) (ios, devxp)
  • Reminders add-reminder plan is pinned to CI’s iOS Reminders labels (Done/New Reminder, English) (#2855) (flaky test, ios, testing)
  • Daemon startup DB migration hard-fails when bunx extraction is missing a transitive dep (e.g. kysely) (#2833)
  • nightly: PR title/body don’t reflect a runner-only SHA256 change (#2816)
  • iOS: bake a version constant into the XCTestRunner SPM package (#2814)
  • Enforce the version pin across a reused/shared daemon (PID-file stamp + client mismatch fail) (#2812)
  • Flaky: RemindersAddPlanTests.testAddReminderPlan (UI ‘Done’ tap race at plan step 5) (#2811) (flaky test, ios, testing)
  • Versioning: resolve (or formally accept) the -SNAPSHOT coordinate divergence for local Gradle builds (#2807)
  • Release integrity: store iOS runner SHA256 per registry entry (not a global scalar) (#2806)
  • perf(db): WAL hygiene — set journal_size_limit and checkpoint(TRUNCATE) on close (#2802) (performance, database)
  • perf(db): truncate request/response bodies in the getNetworkEvents list projection (#2801) (performance, database)
  • perf(db): batch N+1 query fan-out in getFailureGroups and getTestRuns (dashboard read paths) (#2800) (performance, database)
  • perf(db): amortize per-insert retention COUNT(*) in event repositories (#2799) (performance, database)
  • perf(db): add covering index for recordStorageEvent previous-value lookup (#2798) (performance, database)
  • perf(db): add a bounded prepared-statement cache to the Bun SQLite dialect (#2797) (performance, database)
  • perf(db): add composite (device_id, timestamp) indexes to telemetry event tables to eliminate ORDER BY filesorts (#2788) (performance, database)
  • perf(db): set PRAGMA synchronous = NORMAL under WAL to stop per-commit fsync on the telemetry write stream (#2787) (performance, database)
  • Output reduction 0: measurement harness (fixture + byte-breakdown script) (#2755) (devxp, performance, testing)
  • Provide hermetic single-version CI pinning for all clients (daemon + ctrlproxy APK/IPA + junit-runner + XCTestRunner) (#2746)
  • Release integrity: iOS runner-binary checksum never wired (verification disabled) + no version-equality release gate (#2745)
  • Shared per-uid daemon socket is unguarded for non-TS clients (JUnit/XCTest) — add server-side version/build-identity handshake (#2744)
  • Multiple checkouts share one per-uid daemon socket → wrong-build daemon serves frontend (version skew, opaque “Unknown tool” -32603) (#2732)
  • Evaluate Compose interop hidden-region text heuristic with real-world data (#2634)
  • feat(ios): invoke custom accessibility actions via tapOn (#2265)
  • No loading-awareness when refreshing element position before tap (#1949)

[v0.0.40] - 2026-06-30

Added

  • Cross-platform tool to read/write app preferences (adb prop / SharedPreferences / iOS UserDefaults) (#2714)
  • install.sh should detect and help install the required Android SDK platform (compileSdk) (#2680)

Fixed

  • doctor reports all-green while iOS observe is broken (no client↔runner round-trip check) (#2693)
  • iOS CtrlProxy forced-restart recovery should use PortManager to clear processes bound to the target port (#2692)
  • iOS CtrlProxy port management collides with adb; client and runner ports diverge (#2691)

Other

  • Stamp git SHA into pre-release daemon version so the version gate distinguishes dev builds (#2738)
  • Verify build-mismatch daemon restart doesn’t worsen the #2599 session-wedge for sibling MCP sessions (#2737)
  • doctor: surface daemon build identity (entryScript / buildId) to spot wrong-build skew (#2736)
  • doctor: iOS round-trip check can’t detect runner/client port mismatch (#2735)
  • fix(ios): simulator runner ignores allocated port (binds 8765) when Android is connected → client/runner port mismatch, all iOS ops fail (#2731)
  • Daemon log file is unlinked by bunx temp-dir cleanup; on-disk logs end up empty (#2724)
  • openLink times out at 30s on slow deeplinks, then logs success=true after the timeout (#2723)
  • Emulator launches windowed by default; aborts with opaque “code: null” on headless hosts (#2722)
  • Headless daemon start fails 10s budget: open -a Simulator → OSLaunchdErrorDomain Code=125 in no-GUI launchd session (#2721)
  • Remove heapdump native addon dependency for Node 26 compatibility (#2719)
  • iOS CtrlProxy reconnect cooldown is very long (~137s) and observe gives no ‘reconnecting’ signal (#2695)
  • Demote/clarify WARN: ‘Failed to read simulator app bundle for …XCTestServiceApp’ during iOS setup (#2694)
  • iOS CtrlProxy runner reports 320x480 screen (missing launch screen) instead of real device size (#2683)
  • iOS highlight (SDK path): verify/fix coordinate scaling so highlights land on the correct element (#2682)
  • iOS highlight: remove non-SDK runner-overlay fallback and report honestly that it requires the AutoMobile SDK (#2681)
  • doctor: add iOS CtrlProxy runner check so iOS gives the same certain feedback as Android (#2678)

[Unreleased]

Fixed

  • iOS highlight: remove the non-functional runner-overlay fallback and report honestly that highlighting requires the in-app AutoMobile SDK (#2681) (ios)

[v0.0.39] - 2026-06-29

Added

  • Implement iOS Simulator app-container file management (#2571)
  • Implement Android app-container file management (#2570)
  • Add internal app file management service abstraction (#2569)
  • Design platform-neutral app file MCP API (#2568)
  • feat(ios): highlight — visual element highlight overlay on iOS (#2502) (ios)
  • feat(ios): mockNetwork — register mock network response rules via URLProtocol (#2500) (ios)
  • feat(ios): sqlQuery — SQLite database inspection on iOS via the in-app SDK HTTP server (#2498) (ios)
  • feat(ios): changeLocalization — locale/timezone/calendar on physical iPhones (#2492) (ios, research)
  • feat(ios): pressButton — volume_up/volume_down/power hardware buttons (#2485) (ios)
  • feat(ios): shake — simulate device shake gesture via XCUIDevice.shake() (#2484) (ios)
  • feat(ios): executeGesture — multi-finger / VoiceOver multi-finger swipe via XCPointerEventPath (#2483) (ios, a11y)

Changed

  • Consolidate duplicated device-vs-session resolution in SocketServer.getRequestArgumentScopeKey (#2664)
  • Trim over-broad Random/Backoff utils and unify three UUID sources onto IdGenerator (#2663) (dead-code)
  • iOS network mock-rule sync is copy-pasted from Android (require() in ESM, any-typed, debug-swallowed) (#2662) (ios)
  • appFileService: replace positional-boolean params in executeAndroidAppFileCommand with options object (#2660) (android, devxp)
  • Refactor oversized orchestrators: split TapOnElement.ts (1.6k lines) and toolRegistry.ts (909 lines) (#2659)
  • Establish & document an error-handling convention (throw vs return vs log-and-continue) (#2657)
  • Refactor: de-duplicate DevicePool assignment methods (LRU drift) + remove left-in [DEVICE-POOL-DEBUG] logging (#2656)
  • Type safety: replace any in navigation hierarchy logic with existing ViewHierarchyNode type (#2655)
  • Dead Code Detection: Threshold Exceeded (#2361) (automated, dead-code)

Fixed

  • AndroidSystemConfigurationAdapter.setTimeZone reports success without read-back verification (#2661) (android)
  • fix(ios): postNotification requires appId on iOS but the schema marks it optional (#2544) (ios)
  • fix(ios): SDK in-app hierarchy (:8766) merged into observes of unrelated foreground apps — ~2.5MB hierarchies (#2540) (ios)
  • fix(intellij): #2464 device-disconnect deviceEvents wired only to uncalled LayoutInspectorDashboard (live view may still freeze) (#2531) (intellij plugin)

Other

  • doctor: make daemon health socket probes non-destructive (#2658)
  • putAppFile resolves a relative sourcePath against the daemon cwd (homedir), not the launch cwd — ENOENT/wrong-file under a detached daemon (#2644)
  • doctor: reports ‘Daemon is not running’ while it is serving, and prints device=emulator-5554 during an iOS-only run (#2643)
  • recentApps on iOS reports success but doesn’t reach the App Switcher (lands on cover-sheet/home) (#2642)
  • launchApp returns a stale embedded observation (pre-transition app) — follow with a fresh observe (#2641)
  • clipboard get on iOS can return a stale in-memory ‘shadow’ value, masking a failed/changed real read (#2640)
  • pinchOn returns ‘not supported on iOS yet’ even though the iOS runner advertises request_pinch (#2639)
  • Daemon DisconnectMonitor churns on phantom/removed devices: stale ‘Failed to stop recording’ every ~5s + repeating miss counts (+ emulator resurrection) (#2638)
  • iOS SDK: network-mock enforcement compiles into RELEASE builds (mock short-circuit sits outside #if DEBUG) (#2637)
  • Generated schemas/tool-definitions.json is missing 10 production tools — generator skips 5 register*Tools categories (#2636)
  • Pre-commit hook crashes: planYaml.ts uses js-yaml APIs removed in v5 (blocks all commits) (#2635)
  • Clarify maxDurationSeconds behavior for iOS stream-copy remux (#2627)
  • Add iOS simulator videoRecording start-stop MP4 integration test (#2628)
  • Keep plan-executable tools available inside criticalSection (#2614)
  • highlight on iOS has no working path for non-SDK apps: runner-overlay fallback disabled by default (AUTOMOBILE_IOS_LIVE_HIGHLIGHTS) (#2607)
  • videoRecording stop fails on iOS simulator: mov→mp4 FFmpeg finalize produces no output and the error hides the cause (#2606)
  • getAppPermissions fails on iOS simulator: sqlite3 called with ‘.mode json’ + SQL in one positional arg (‘extra argument’) (#2603)
  • Daemon restart desyncs connected MCP clients: all tool calls + resource reads return opaque ‘Session not found’ with no auto-recovery (#2599)
  • clipboard get on Android returns empty success when the read is denied by ClipboardService (background a11y), and cmd clipboard fallback doesn’t exist (#2596)
  • changeLocalization silently fails on Android: reports success but the system locale never changes (invalid ‘cmd locale set-locales’, no-op fallback, no verification) (#2595)
  • sqlQuery: INSERT/UPDATE/DELETE … RETURNING on Android commits the mutation but returns an error (RETURNING not recognized by isReadQuery) (#2594)
  • CtrlProxy APK refresh blocks every tool call on slow/no network (~30s each); local ops like sqlQuery hang offline (#2590)
  • tool_calls.duration_ms is never populated (NULL for all rows) — per-call timing not recorded (#2588)
  • iOS startDevice/listDeviceImages returns “Available images: none” despite a booted, available simulator (#2572)
  • MCP tool errors discard subprocess stderr / daemon-log context, surfacing only opaque messages (#2562)
  • Multi-daemon detection false-positive: a single daemon’s own shell wrapper is counted as an “other” daemon (#2561)
  • Daemon inherits spawner cwd; a deleted cwd makes forked children fail ENOENT, misreported as “Android emulator not found” (#2560)
  • Concurrent instances crash on startup with SQLiteError: database is locked (no busy_timeout) (#2559)
  • openLink lacks an MCP request-timeout floor; slow deeplinks fail with -32001 (#2558)
  • junit-runner and manager.ts hardcode @latest, defeating consumer version pinning (#2386)
  • Detect Compose interop content hiding and signal OCR fallback (#2374)
  • launchApp rejects ‘packageId’ parameter — LLM commonly uses wrong field name (#2217)

[v0.0.38] - 2026-06-25

Added

  • feat(android): accessibilityFocus — set/clear TalkBack cursor focus (#2503) (android, a11y)
  • feat(ios): biometricAuth — Touch ID / Face ID simulation via simctl Darwin notifications (#2497) (ios)
  • feat(ios): getNotificationPolicy — read per-app notification authorization on simulators via BulletinBoard (#2496) (ios, research)
  • feat(ios): postNotification — deliver simulated push to target bundle via simctl push (#2495) (ios)
  • feat(ios): deviceSnapshot — capture and restore simulator settings (includeSettings) (#2494) (ios)
  • feat(ios): setDeviceState — Do Not Disturb mode fidelity and physical-device support (#2493) (ios, research)
  • feat(ios): getDeepLinks — URL scheme & universal link discovery via Info.plist (#2486) (ios)
  • feat(ios): dragAndDrop — coordinate drag via XCUITest CtrlProxy runner (#2481) (ios)

Fixed

  • fix(ios): daemon runs the published-release CtrlProxy runner, not source — new runner commands fail “Unknown command type” against a stale binary (#2539) (ios)
  • fix(ios): CtrlProxy WebSocket and AutoMobile SDK server collide on port 8766 — all iOS observe/gesture ops fail (Expected 101) (#2538) (ios)
  • fix(daemon): signal/exception handlers registered inside main() after dynamic imports — startup window with no cleanup (regression from #2465) (#2532) (release engineering)
  • fix(ios): observation stream double-pushes initial hierarchy frame on cold subscribe (#2530) (ios)

Other

  • Client can silently use a daemon of a mismatched version (@latest spawn + restart cooldown) (#2452)
  • Crash/force-kill leaves stale PID and socket files; no exit-time cleanup (#2451)
  • Device disconnects are not surfaced to observation-stream subscribers (#2450)
  • Screenshot backoff stops after initial burst; live view freezes on static screens (#2449)
  • Observation stream pushes no initial frame on subscribe; idle devices show blank (#2448)
  • Observation-stream request_observation command is a no-op; socket clients cannot force a frame (#2447)
  • Daemon stream socket paths are not discoverable, causing silent connect failures on env mismatch (#2446)
  • Device pool never prunes shut-down devices, wedging discovery until daemon restart (#2445)
  • Daemon readiness inferred from PID/socket-file existence, not an actual connection (#2444)
  • Device held ~30s when a client dies before its first heartbeat (#2443)
  • iOS device pool never auto-boots an installed-but-shutdown simulator to satisfy criteria (#2442)
  • Daemon version skew is only reconciled one direction; stale daemon can serve newer clients (#2441)
  • Add a fast --version flag; today it hangs by falling through to the stdio server (#2440)

[v0.0.37] - 2026-06-24

Other

  • No changes.

[v0.0.36] - 2026-06-23

Other

  • installApp succeeds but app not present for launchApp/openLink (device resolution incoherence) (#2387)

[v0.0.35] - 2026-06-10

Other

  • launchApp times out on iOS when clearAppData is true (#2368)

[v0.0.34] - 2026-06-04

Other

  • No changes.

[v0.0.33] - 2026-06-04

Other

  • No changes.

[v0.0.32] - 2026-06-02

Changed

  • Dead Code Detection: Threshold Exceeded (#2313) (automated, dead-code)

Other

  • Can’t pin the on-device CtrlProxy release independently of the daemon (#2293)
  • retryIfNoChange fires false-positive retries during activity transitions (#2283)

[v0.0.31] - 2026-05-27

Changed

  • Dead Code Detection: Threshold Exceeded (#1874) (automated, dead-code)

Other

  • Only 2 of 7 daemon CLI flags log a startup confirmation (#2286)
  • CtrlProxy getLatestHierarchy 100ms fresh-data wait too short for contended environments (#2285)
  • Issue 3: SelectionStateTracker ignores --no-ui-perf-mode and dominates CI ADB overhead (#2284)
  • retryTapIfNoChange throws ReferenceError: isTalkBackEnabled is not defined (#2282)
  • Bug: ReferenceError ‘isTalkBackEnabled is not defined’ in tapOn retryIfNoChange path (#2277)
  • bug(ios): observe returns “received Android hierarchy for iOS device” inside conversation views (#2275)

[v0.0.30] - 2026-05-20

Other

  • Remove tapClickableParent from tapOn schema — redundant with auto-escalation (#2248)

[v0.0.29] - 2026-05-20

Other

  • SelectAllText accessibility-service path crashes: AdbExecutor passed to AdbClientFactory consumer (#2231)
  • InputText accessibility-service path crashes: AdbExecutor passed to AdbClientFactory consumer (#2229)
  • ImeAction accessibility-service path crashes: AdbExecutor passed to AdbClientFactory consumer (#2230)
  • PinchOn accessibility-service path crashes: AdbExecutor passed to AdbClientFactory consumer (#2228)
  • Daemon WebSocket observation-stream setup crashes: AdbExecutor passed to AdbClientFactory consumer (#2224)
  • ClearText accessibility-service path crashes: AdbExecutor passed to AdbClientFactory consumer (#2226)
  • ExecuteGesture accessibility-service path crashes: AdbExecutor passed to AdbClientFactory consumer (#2225)
  • Clipboard accessibility-service path crashes: AdbExecutor passed to AdbClientFactory consumer (#2227)
  • Add runtime shape guard to *CtrlProxyClient.getInstance() factories (#2223)
  • observe waitFor screenshot loop: Operation cancelled every ~130ms until session heartbeat timeout (#2216)
  • Navigation screenshot path passes undefined platform causing ‘Unsupported platform’ error (#2215)
  • PerformanceAudit crashes with ‘J.create is not a function’ in 0.0.28 build (#2214)

[v0.0.28] - 2026-05-19

Added

  • feat: Android emulator telephony and SMS simulation (#1579) (android)
  • iOS: Implement ScreenCaptureKit simulator window capture (#1096) (ios)
  • iOS: Implement Swift helper for AVFoundation device capture (#1095) (ios)

Changed

  • refactor: extract test helper for CommandHandlerTests boilerplate (#1879) (ios, testing)

[v0.0.27] - 2026-05-18

Added

  • IDE Plugin: Display exported YAML in Record Test UX after finishing (#1073) (intellij plugin)
  • epic: detect image/media loading via network and view hierarchy correlation (#1015) (android, research, ai)
  • feat: correlate network requests with media views for loading detection (#1014) (android, ai)
  • Extend focus navigation to handle scroll-then-focus for off-screen elements (#472) (android, a11y)

Changed

  • refactor: extract sendCommand helper to eliminate WebSocket delegate boilerplate (#1880)
  • Chore: Test multi-device execution (#764)

Other

  • PlanMigrator: notification.timeout → awaitTimeout (#2120)
  • Plan execution ADB contention: skip screenshots and cancel orphaned jobs (#2119)
  • Tap resilience: ghost tap detection and pre-tap stability (#2118)
  • No way to configure accessibility service flags at runtime (#2099)
  • Reduce ADB overhead during plan execution (#2098)
  • Stability failures with remote emulators and long-running tool calls (#2097)
  • Tapping notifications inside collapsed Android groups opens app generically instead of deep-linking (#2096)
  • Ghost taps - touch events fail to register regardless of input method (#2081)
  • ADB pipe congestion from event-driven hierarchy broadcasts causes off-screen bounds (#2080)
  • No way to opt into observe step capture from CI without modifying test code (#1973)
  • executePlan timeout too short for long UI plans - premature Operation cancelled in CI (#1972)
  • No MCP tool for setting Android SCHEDULE_EXACT_ALARM app op (#1967)
  • No MCP tool for toggling Android Do Not Disturb policy access (#1966)
  • executePlan silently continues past observe waitFor timeout instead of failing the step (#1963)
  • tapOn diagnostics lost when surfaced through executePlan - no visibility into tap mechanics (#1961)
  • Android screenrecord produces corrupt/truncated video files on stop (#1960)
  • Support segmented video recording to chain multiple screenrecord sessions past the 180-second Android cap (#1959)
  • No way to capture per-step observe snapshots for CI debugging (#1958)
  • No opt-in mechanism for pre-tap element stability verification (#1950)
  • Navigation screenshots add constant I/O pressure to CI emulators (#1947)
  • Queued MCP forward requests burn timeout budget while waiting in serialization queue (#1946)
  • HTTP server requestTimeout kills long plans + id:unknown error responses cause silent hangs (#1944)
  • executePlan MCP timeout too short - premature Operation cancelled (#1943)
  • Streamable HTTP SSE auto-reconnect triggers 409 session teardown (#1942)
  • Concurrent MCP socket forwards corrupt shared HTTP session (#1939)
  • Create Homebrew formula for AutoMobile (#978) (release engineering, env)

[v0.0.26] - 2026-05-06

Other

  • WebSocket timeout cascade causes daemon blindness after slow hierarchy extraction (#2079)

[v0.0.25] - 2026-05-06

Other

  • Daemon mode ignores CLI flags (dismiss-keyboard, no-ui-perf, etc.) (#2065)

[v0.0.24] - 2026-05-01

Other

  • observe returns iOS hierarchy despite setActiveDevice to Android emulator (#2053)
  • ensureConnected should check if target simulator is still booted before relaunching CtrlProxy (#2052)

[v0.0.23] - 2026-04-30

Other

  • No changes.

[v0.0.22] - 2026-04-30

Other

  • No changes.

[v0.0.21] - 2026-04-30

Other

  • No changes.

[v0.0.20] - 2026-04-29

Other

  • No changes.

[v0.0.19] - 2026-04-29

Other

  • Daemon leaks unix-domain socket FDs; accepted peers never closed (backpressure + keepalive gap) (#2008)
  • CI cannot configure daemon flags without pre-starting manually - no JUnit runner integration (#1971)
  • No way to programmatically close the notification shade - pressButton “back” is fragile (#1969)
  • No MCP tool for granting Android runtime permissions - permission dialogs block CI tests (#1965)
  • observe waitFor matches wrong element in lists - no way to scope by container (#1962)
  • No screen state captured when executePlan step fails - blind debugging in CI (#1957)
  • tapOn silently taps stale coordinates when accessibility tree changes between observe and tap (#1948)
  • Emulator crash leaves active sessions hanging until full MCP timeout (#1945)
  • ECONNREFUSED on daemon MCP hop due to IPv4/IPv6 mismatch on Linux CI (#1938)
  • Add AutoMobileAPI protocol and default implementation for dependency injection (#1937)
  • Add delegate-based network recording API as primary integration path (#1936)
  • Add configuration options to disable crash/signal handler subsystems (#1935)
  • Add AutoMobileSDK product to root Package.swift for SPM consumers (#1934)
  • iOS SDK walker: surface visual properties for pure SwiftUI shapes via CALayer introspection (#1926)

[v0.0.18] - 2026-04-17

Other

  • iOS: text entry fails despite focused UITextField with react native (#1925)

[v0.0.17] - 2026-04-16

Added

  • startDevice: accept generic parameters and return/boot matching device (#1887)
  • Add resource for installed app metadata (version, build number) (#1886)
  • Support iOS app installation in installApp (#1885) (ios)
  • Add uninstallApp tool (#1884)

[v0.0.16] - 2026-04-03

Added

  • IDE Plugin: Implement screen stream display in Layout Inspector (#1033) (android, ios)
  • Server: Implement screen stream receiver and relay to IDE plugins (#1032)
  • Feature: iOS UserDefaults Inspection and Management (#1022) (ios, devxp, testing)
  • feat: identify media-displaying views in hierarchy by class and role (#1013) (android, a11y)
  • feat: Android version matrix testing in CI (#835) (android, ci, testing)

Changed

  • Dead Code Detection: Threshold Exceeded (#1648) (automated, dead-code)

Fixed

  • tapOn fails to match text with Unicode curly apostrophe (U+2019) (#1798) (ios)
  • Daemon disconnect cascade causes 6GB+ log flood and crash-restart loop (#1773)

Other

  • iOS: Add rotate support via CtrlProxy (#1859)
  • iOS: Add systemTray support via CtrlProxy (#1858)
  • iOS: Add recentApps support via CtrlProxy (#1857)
  • iOS inputText fails with dismissKeyboard enabled: isDismissKeyboardAfterInputEnabled is not a function (#1840)
  • setActiveDevice should allow launchApp when both platforms are connected (#1839)
  • inputText: should not require dismissKeyboard, default to false (#1836)
  • tapOn: error message when ‘action’ is omitted is unclear (#1835)
  • Auto-disable stylus handwriting on Android emulators (#1834)
  • CtrlProxy iOS broken on Xcode 26: checksum mismatch + simctl spawn failure (#1833)
  • startDevice returns generic DEVICE_NOT_FOUND when AVD userdata is corrupt (#1672)
  • feat: iOS simulator live locale changes (SpringBoard restart + AppleLanguages) (#1613)
  • test: increase Android test coverage for changeLocalization (#1612)
  • feat: add setCalendarSystem MCP tool (rename to calendar) (#1611)
  • bug: doctor --ios always fails with “undefined is not an object (evaluating ‘…runtimes.filter’)” on Xcode 26.2 (#1448)
  • ci: run JUnitRunner emulator tests on macOS/Windows/Linux matrix (#959) (android, ci, testing)

[v0.0.15] - 2026-03-26

Other

  • No changes.

[v0.0.14] - 2026-03-26

Added

  • feat: implement iOS clipboard operations (get/copy/paste/clear) (#1501) (ios)
  • feat: add boomerang support to VoiceOverSwipeExecutor (#1451) (ios, a11y)
  • feat: VoiceOver Phase 4 — documentation, example scripts, and parity review (#1366) (documentation, ios, a11y)
  • feat: VoiceOver Phase 3 — accessibility focus tracking and rotor support (#1365) (ios, a11y)
  • feat: VoiceOver Phase 2 — adapt tapOn and swipeOn for VoiceOver gestures (#1364) (ios, a11y)
  • feat: VoiceOver Phase 1 — detection via UIAccessibility.isVoiceOverRunning (#1363) (ios, a11y)
  • feat: AutoMobileBiometrics.overrideResult() SDK hook for deterministic biometric testing (#1362) (android, ios, testing)
  • feat: expand vision fallback to support element search in swipeOn, pinchOn, dragAndDrop (#1361) (android, ios, ai)
  • feat: add accessibility MCP tool to enable/disable TalkBack and VoiceOver (#1360) (android, ios, a11y)
  • feat: TalkBack Phase 4 — accessibility focus tracking in observations and polish (#1359) (documentation, android, a11y)
  • feat: TalkBack Phase 3 — adapt swipeOn to use two-finger swipe and accessibility scroll actions (#1358) (android, a11y)
  • feat: TalkBack Phase 2 — adapt tapOn to use ACTION_CLICK when TalkBack is enabled (#1357) (android, a11y)
  • feat: capture and expose network request logs for media correlation (#1012) (android)
  • feat(ios): Code signing configuration UI in Xcode Companion app (#914) (ios)
  • Implement automated mitmproxy certificate installation for Android (#465) (android, chore)
  • Research mitmproxy integration architecture for automated certificate trust (#464) (android, research)
  • Xcode companion app: menu bar mode for quick access (#407) (ios, devxp)
  • Xcode companion app: execution log and error view (#406) (ios, devxp)
  • Xcode companion app: feature flag toggles (#405) (ios, devxp)
  • Xcode companion app: performance/timing history view (#404) (ios, devxp)
  • Xcode companion app: navigation graph rendering view (#403) (ios, devxp)
  • iOS Managed Apple IDs/profiles: detect restrictions + document test plan guidance (#365) (ios, devxp)
  • iOS Managed App Configuration: surface policy-driven failures + guidance (#364) (ios, devxp)
  • Xcode Source Editor Extension: plan template/run/open commands (#362) (ios, devxp)
  • Xcode companion app: test recording flow + plan generation (#361) (ios, devxp)
  • Xcode companion app: MCP transport selection + dev server discovery (#359) (ios, devxp)
  • Xcode companion app: scaffold macOS app + MCP connection shell (#358) (ios, devxp)
  • IDE plugin: sandbox testing and runIde validation (#259) (devxp, intellij plugin)
  • IDE plugin: backwards compatibility + matrix testing (#245) (release engineering, testing, intellij plugin)
  • Add iOS support for accessibility audit mode (#103) (ios, a11y)
  • mitmproxy network call inspection (#34)

Changed

  • chore: extend lychee link checking to cover CONTRIBUTING.md and root markdown files (#1457) (ci, devxp)
  • chore: fix CONTRIBUTING.md dead link to local-development.md (#1456) (documentation, dead-code)
  • chore: add git-lfs setup to hot-reload dev environment bootstrap (#1455) (devxp)
  • Dead Code Detection: Threshold Exceeded (#1369) (automated, dead-code)
  • refactor: rename XCTestServiceApp to CtrlProxy and ios directory to control-proxy (#1356) (ios)
  • refactor: rename AccessibilityService to CtrlProxy and gradle subproject to control-proxy (#1355) (android)
  • chore: remove demoMode MCP tool (#1352) (dead-code)
  • refactor: replace rawViewHierarchy tool with raw flag on observe (#1351) (dead-code)
  • chore: remove MCP HTTP transport (#1350) (dead-code)
  • Dead Code Detection: Threshold Exceeded (#1293) (automated, dead-code)
  • Tighten XcodeExtension signing once .appex exists (#921) (ios)

Fixed

  • Startup benchmark flake: FIFO stderr line truncation drops STARTUP_BENCHMARK prefix (#1563) (performance, testing)
  • App view hierarchy disappears when keyboard/EditText is focused (#1488) (android)
  • bug: CtrlProxy reboots multiple times per minute in hot reload and normal MCP use (#1354) (ios)
  • bug: hot reload reboots iOS simulator unexpectedly (#1353) (ios, devxp)

Other

  • feat: iOS simulator support for changeLocalization tool (#1578)
  • Install Fails without SSH Configured (#1559)
  • research: iOS accessibility scroll action equivalent to Android scroll_forward/scroll_backward (#1452) (ios, a11y, research)
  • test: add unit tests for VoiceOverSwipeExecutor (#1450) (ios, a11y, testing)
  • Release: sign + notarize macOS companion app (#375) (ios, release engineering, devxp)
  • CI: add macOS job for Xcode companion app + Source Editor Extension build (#373) (ios, ci)

[v0.0.13] - 2026-02-13

Other

  • Add CI checks for host control Docker scripts across macOS/Linux/Windows (#981) (ci, env)
  • Publish to official MCP registry (#26) (release engineering)
  • Publish AutoMobile on Docker Hub (#25) (release engineering)

[v0.0.12] - 2026-02-11

Other

  • No changes.

[v0.0.11] - 2026-02-11

Added

  • IDE plugin: always use active (white) toolbar icon (#1214) (intellij plugin)
  • Remove feature flag for video test recording (#1203) (video)
  • IDE plugin: show ‘Device Disconnected’ when observed device becomes unavailable (#1202) (intellij plugin)
  • IDE Plugin: Add full-window FileEditor mode for dashboard (#1167) (intellij plugin)
  • feat: iOS version matrix testing in CI (#836) (ios, ci, testing)
  • Support custom accessibility rules (#104) (devxp, a11y)

Changed

  • refactor: ViewHierarchy has near-clone findFocusedElement / findAccessibilityFocusedElement (#1191)
  • refactor: UIStateExtractor reimplements ElementParser traversal and property extraction (#1190)
  • refactor: BugReport.traverseNode() reimplements ElementParser inline (#1189)
  • refactor: DebugSearch reimplements ElementParser, TextMatcher, and ElementFinder inline (#1188)
  • chore: upgrade GitHub Actions upload-artifact and download-artifact to v4.6+ (#1158) (ci)
  • Dead Code Detection: Threshold Exceeded (#1143) (automated, dead-code)

Fixed

  • IDE plugin: device disconnected notification is too aggressive (#1244) (intellij plugin)
  • iOS: toggle switch tap does not trigger view hierarchy or screenshot update (#1227)
  • bug: IDE plugin settings page fails to load feature flags with MCP error -32603 (#1213) (intellij plugin)
  • Bug: IDE plugin crashes with IllegalArgumentException when opening test plan YAML file (#1205) (intellij plugin)
  • Bug: failing JUnit Runner test does not produce a failing JUnit test result (#1204) (testing)
  • iOS: Unable to observe system permission dialogs in view hierarchy (#1147) (ios)

Other

  • CI: add Xcode 26 to iOS build and test matrix (#1207) (ios, ci)
  • CI: auto-retry iOS jobs when no simulator runtimes are installed on macOS runner (#1206) (ios, ci)
  • CI: add macOS job for iOS Accessibility Bridge build + XCTest runner tests (#372) (ios, ci)
  • Publish AutoMobile Android SDK on Maven Central (#122) (android, ci, release engineering)
  • Publish AutoMobile JUnitRunner Library (#121) (android, ci, release engineering, testing)

[v0.0.10] - 2026-02-06

Added

  • Support custom accessibility rules (#104) (devxp, a11y)

Other

  • chore: upgrade GitHub Actions upload-artifact and download-artifact to v4.6+ (#1158)
  • Publish AutoMobile Android SDK on Maven Central (#122) (android, ci, release engineering)
  • Publish AutoMobile JUnitRunner Library (#121) (android, ci, release engineering, testing)

[v0.0.9] - 2026-02-04

Added

  • Test Runners: Cascade MCP tool failures to JUnitRunner/XCTestRunner via executePlan response (#1078) (android, ios, testing)
  • IDE Plugin: Add Cancel button to Record Test entry screen (#1075) (intellij plugin)
  • IDE Plugin: Add ‘Refine’ button to simplify exported test plans with AI (#1074) (intellij plugin, ai)
  • IDE Plugin: Merge Exploratory Test into Record Test UX (#1072) (intellij plugin)
  • IDE Plugin: Expose startTestRecording MCP tool (#1071) (intellij plugin)
  • IDE Plugin: Expose exportPlan MCP tool for Finish Recording (#1070) (intellij plugin)
  • [IDE Plugin] Wire up StreamingFailuresDataSource for real-time failure updates (#1066) (intellij plugin)
  • [SDK] Add handled exceptions API for non-fatal error reporting (#1065) (android)
  • [IDE Plugin] Implement RealStorageDataSource for key-value storage inspection (#1064) (intellij plugin)
  • [MCP Server] Add storage inspection tools and Unix socket push channel for key-value data (#1063)
  • [AccessibilityService] Add WebSocket message types for storage data and real-time sync (#1062) (android)
  • [SDK] Add SharedPreferences/DataStore reading API for key-value storage inspection (#1061) (android)
  • Live performance data for currently selected app (#1060) (performance, intellij plugin)
  • Navigation Graph should only accept named nodes (#1059)
  • Navigation Graph Fog Mode (#1058)
  • Research: iOS real-time screen streaming options (#1034) (ios, research)
  • Android: Implement video server JAR (VirtualDisplay + MediaCodec) (#1031) (android)
  • Research: Android real-time screen streaming architecture (MediaProjection/MediaCodec) (#1030) (research)
  • Feature: Android SharedPreferences Inspection and Management (#1021) (android, devxp, testing)
  • Feature: Crash and ANR Monitoring via ADB, simctl, and AccessibilityService (#1020) (android, ios, devxp, testing)
  • Feature: Database Inspection and Management for Android AutoMobile SDK (#1019) (android, devxp, testing)
  • feat(mcp): add setUI tool for declarative form field population (#986) (android, ai)
  • IDE plugin: Compose charting for performance timelines (#306) (android, intellij plugin)
  • IDE Plugin: Display recent performance debug data (#283) (android, performance, intellij plugin)
  • IDE plugin: MCP resource viewer UI (#255) (intellij plugin)
  • IDE plugin: add source mapping support (#247) (intellij plugin)

Changed

  • refactor: move src/features/observe/accessibility/ to src/features/observe/android/ (#1123) (android)
  • refactor: consolidate screenshot utilities (#1121)
  • refactor: decompose SwipeOn - extract overlay detection and scroll-until (#1120) (android)
  • refactor: decompose ViewHierarchy - separate screenshot handling (#1119) (android)
  • refactor: decompose TapOnElement - extract focus navigation (#1118) (android)
  • refactor: replace getInstance() singletons with constructor injection (#1117)
  • refactor: add interfaces for ObserveScreen, Window, AwaitIdle (#1116)
  • refactor: decompose XCTestServiceClient using delegate pattern (#1115) (ios)
  • refactor: migrate raw setTimeout/setInterval to Timer interface (#1114)
  • refactor: replace inline retry logic with DefaultRetryExecutor (#1113)
  • refactor: consolidate ad-hoc caches to use TTLCache (#1112)
  • Decompose Explore.ts (1870 lines) (#1108)
  • Decompose AccessibilityServiceClient.ts (4652 lines) (#1107) (android)
  • Migrate remaining AdbClient instantiations to AdbClientFactory (#1106) (android)
  • Dead Code Detection: Threshold Exceeded (#1027) (automated, dead-code)

Fixed

  • pressButton should properly await fresh view hierarchy before returning observation (#1051)

Other

  • perf: explore queueMicrotask optimization for FakeTimer (#1130) (devxp, performance)
  • Navigation nodes should preserve aspect ratio instead of cropping screenshots (#1052) (android, devxp, intellij plugin)
  • Research: DevXP for work profile app install tracking (#754) (android, devxp, research)

[v0.0.8] - 2026-01-24

Added

  • View hierarchy contains duplicate elements from merged sources (#999) (performance)
  • criticalSection: accept normalized params in nested steps (#960)
  • Abstract other macOS CLI tools through host control daemon (#932) (ios, env)
  • Abstract xcodebuild commands through host control daemon for Docker support (#931) (ios, env)
  • Abstract simctl commands through host control daemon for Docker support (#930) (ios, env)
  • feat(ios): Xcode provisioning profile integration for physical device deployment (#913) (ios)
  • feat(ios): Add iproxy port forwarding lifecycle management for physical devices (#912) (ios)
  • feat(ios): download XCTestService.ipa from GitHub releases instead of building from source (#906) (ios, release engineering, devxp)
  • Automatic wakefulness check and unlock on Android emulator boot (#879) (android, devxp)
  • feat: streamlined development workflow for iOS XCTestService updates (#878) (ios, devxp)
  • iOS: Interactive installer with Xcode/simulator validation (#871) (ios)
  • iOS: Doctor tool for iOS dependency verification (#869) (ios)
  • iOS: MCP resources for simulator sessions and installed apps (#868) (ios)
  • iOS: Parallel multi-simulator test orchestration (#867) (ios)
  • iOS: Session context for multi-simulator tool execution (#866) (ios)
  • iOS: Multi-simulator session allocation in daemon (#865) (ios)
  • iOS: Integrate visual highlights with bug report generation (#864) (ios)
  • iOS: Integrate visual highlights with video recording (#863) (ios, video)
  • iOS: MCP tool for visual highlighting during debugging (#862) (ios)
  • iOS: WebSocket commands for visual highlight control (#861) (ios)
  • iOS: Visual highlight overlay for XCTest service (#860) (ios)
  • iOS: Expose navigation graph as MCP resource (#859) (ios)
  • iOS: Implement identifyInteractions tool (#858) (ios)
  • iOS: Implement explore tool for automatic app discovery (#857) (ios)
  • iOS: Navigation graph building and exploration (#856) (ios)
  • iOS: MCP tools and resources for video recording (#855) (ios, video)
  • iOS: Integrate video recordings with FFmpeg post-processing (#854) (ios, video)
  • iOS: Video recording capture backend using simctl (#853) (ios, video)
  • iOS: Add comprehensive tests for simulator snapshot feature (#852) (ios, testing)
  • iOS: Implement simulator snapshot restore (#851) (ios)
  • iOS: Implement simulator snapshot capture using simctl (#850) (ios)
  • feat: built-in Claude plugin for marketplace distribution with AutoMobile skills (#848) (release engineering, devxp)
  • feat: optimize CLAUDE.md for progressive disclosure and automatic validation updates (#847) (documentation, devxp, ai)
  • feat: simplify MCP tool schema - move selector id/text to top-level parameters (#845) (devxp)
  • feat: seamless release workflow - consolidate bump version and changelog into single Release workflow (#844) (ci, release engineering)
  • feat: automatically match target device light/dark mode to host system settings (#837) (android, ios, devxp)
  • feat: harden regex parsing for device data (#834) (android, ios)
  • feat: streamlined development workflow for Android/iOS embedded service updates (#831) (android, ios, devxp)
  • ci: only run iOS CI checks when iOS or TypeScript code changes (#829) (ios, ci, devxp)
  • ci: only run Android CI checks when Android or TypeScript code changes (#828) (android, ci, devxp)
  • MCP resource URIs are confusing and inconsistent (#804) (devxp)
  • Integrate focus-based navigation into tapOn tool (transparent to MCP consumers) (#471) (android, a11y)
  • Set up release keystore for production builds (#431) (android, ci, release engineering)
  • Validation: implement all_fast_validate_checks.sh aggregator (#371) (ci, devxp)
  • doctor: iOS checks for missing companion app + download link (#363) (ios, devxp)
  • XCTest Runner: timing capture + publish timing history (#356) (ios, testing)
  • XCTest Runner: implement AutoMobileTestCase + plan executor (#355) (ios, testing)
  • Daemon: add iOS simulator discovery + session allocation (#354) (ios, devxp)
  • simctl integration: status bar demo mode configuration (#352) (ios)
  • simctl integration: app install/launch/terminate + capability reporting (#351) (ios)
  • simctl integration: simulator lifecycle management (#350) (ios)
  • AXe automation layer: coordinate translation + gesture injection (#349) (ios)
  • AXe automation layer: MCP tool handlers + WebSocket client (#348) (ios)
  • Accessibility Bridge: emit view hierarchy change events over WebSocket (#347) (ios)
  • Accessibility Bridge: implement element lookup + bounds + focus state (#346) (ios)
  • IDE plugin: real-time performance streaming + cache (#305) (android, performance, intellij plugin)
  • Enhanced contrast detection for gradients and overlays (#102) (a11y)

Changed

  • Upgrade json-schema-validator to 3.0.0 (requires Jackson 3 migration) (#967) (android, dependencies)
  • Remove unused kotlinx-datetime dependency (#966) (android, dependencies)
  • Remove p99 from MCP Tool Throughput Benchmarks (#950) (performance)
  • Improving TypeScript dead code detection (#946) (devxp, dead-code)
  • Dead Code Detection: Threshold Exceeded (#939) (automated, dead-code)
  • Reduce slow wakeAndUnlock unit tests (<100ms) (#919) (testing)
  • chore: remove checkForeground parallel mode - single dumpsys is 12.9x faster (#872) (android, performance)
  • chore: cleanup top-level leftover planning markdown files (#849) (documentation)
  • chore: set up GitHub Sponsors for project donations (#846)
  • chore: update changelog for v0.0.7 release (#843) (documentation, release engineering)
  • chore: set up release key signing for iOS libraries (#842) (ios, release engineering)
  • chore: set up Dependabot for iOS Swift Package Manager dependencies (#841) (ios, dependencies)
  • chore: set up Dependabot for Android Gradle dependencies (#840) (android, dependencies)
  • chore: update Python/uv dependencies in /scripts/github (#839) (dependencies, python:uv)
  • chore: update TypeScript dependencies - research major version upgrades (#838) (dependencies)
  • docs: clean up and organize documentation (#830) (documentation)
  • Chore: Test notification triggering (#765)

Fixed

  • MCP startup benchmark sometimes hangs without reasonable timeout (#1002) (ci, performance)
  • setActiveDevice does not single out iOS simulators for observe (#1001) (ios)
  • rawViewHierarchy tool doesn’t support iOS (#1000) (ios)
  • iOS: Cannot detect or launch system apps (Settings, Fitness, etc.) (#984) (ios)
  • iOS: Home button press and homeScreen tool not working (#983) (ios)
  • MCP tools/list fails due to tapOn schema using union type at root (#973) (ai)
  • Security: Update qs to fix arrayLimit bypass DoS vulnerability (#964) (dependencies)
  • Security: Update modelcontextprotocol/sdk to fix ReDoS vulnerability (#963) (dependencies)
  • Security: Update hono to fix JWT Middleware algorithm confusion (#962) (dependencies)
  • Security: Update hono to fix JWK Auth Middleware JWT algorithm confusion (#961) (dependencies)
  • Handle corrupted migrations in daemon startup (#947)
  • bug: hot reload development workflow not working (#832) (devxp)
  • Bug: Auto-generated bump versions PR does not trigger CI workflows (#812) (ci, release engineering)
  • Upgrade Bun to 1.3.6 to fix CI segmentation fault crashes (#811) (ci, dependencies)
  • Accessibility service state detection issues after automatic setup (#801) (android, a11y)
  • Prevent automated changelog PR from erroring on fork origin (#793) (ci, release engineering)
  • Fallback to uiautomator when AccessibilityWindowInfo.root returns null for active window (#775) (android, a11y)

Other

  • docs: add reveal/collapse wrappers for demos to reduce page distraction (#987) (documentation)
  • Add CI checks for host control docker scripts across macOS/Linux/Windows (#980)
  • ci: run TypeScript Node build/test on macOS/Windows/Linux matrix (#958) (ci, testing)
  • ci: run interactive installer on macOS/Windows/Linux matrix (#957) (ci, release engineering, testing)
  • Add recorded GIF demo to interactive install script documentation (#953) (documentation)
  • AGP 9.0 bump fails due to org.jetbrains.kotlin.android plugin (#896) (android, ci, automated, dependencies)
  • Dependabot Android PRs fail CI due to missing signing secrets (#895) (android, ci, automated, dependencies)
  • iOS: First-run path documentation from setup to first task (#870) (documentation, ios)
  • chore: research slim Docker image for Android emulator management (#833) (android, env, research)
  • Codex setup missing in install docs (#825) (documentation, ai)
  • Explore automatic retry for flaky emulator tests in CI (#808) (flaky test, ci, research)
  • Benchmark NPM Unpacked Size (#796) (release engineering, research)
  • Reduce NPM Unpacked Size (#795) (release engineering, performance)
  • Accessibility Bridge distribution without App Store (#376) (ios, release engineering)
  • CI: audit workflows to keep Linux for non-iOS checks and macOS only where required (#374) (ios, ci, devxp)
  • XCTest Runner: configuration via env vars + sample test target docs (#357) (documentation, ios, testing)
  • Run AutoMobile self tests on Emulator.wtf (#77) (android, ci, testing)
  • iOS ViewHierarchy WebSocket Accessibility Service/App (#33) (ios)

[0.0.7] - 2026-01-15

Added

  • Add configurable fade animation for highlights (1-5 second duration) (#656) (android, devxp)
  • Add smooth ink-line path drawing for freehand annotations (#655) (android, devxp)
  • Add runtime permission handling for drawing overlays (#654) (android, devxp)
  • Integrate visual highlights with video recording for reproduction videos (#653) (devxp)
  • Integrate visual highlights with bug report generation (#652) (devxp)
  • Add MCP tool for visual highlighting during debugging (#651) (devxp)
  • Add Node.js client for visual highlight control (#650) (devxp)
  • Add WebSocket commands for controlling visual highlights (#649) (devxp)
  • Add drawing API for shapes in AccessibilityService overlay (#648) (android, devxp)
  • Add cmdline-tools installation to doctor MCP tool (#620) (android, devxp, ai)
  • Detect Homebrew avdmanager when system images are in $ANDROID_HOME (#619) (android, devxp)
  • Detect old avdmanager with JAXB error and provide helpful message (#618) (android, devxp)
  • Add Device Owner/Device Admin setup for advanced operations and CA certificate management (#615) (android, devxp)
  • Complete implementation of Last Screenshot MCP resource (#613)
  • Feature: Enable element search across both main hierarchy and window hierarchies in tapOn/interaction tools (#543) (android)
  • Feature: Keep screen awake on physical devices during automation (#536) (android)
  • Implement Android AccessibilityService clipboard operations (#500) (android)
  • Implement focus path calculation and navigation engine (#470) (android, a11y)
  • Implement focus position tracking and accessibility tree traversal (#469) (android, a11y)
  • Design focus-based navigation algorithm for TalkBack element targeting (#468) (android, a11y, research)
  • Implement network traffic capture MCP tools with mitmproxy (#466) (android)
  • Implement postNotification MCP tool with SDK hook and cmd notification fallback (#463) (android)
  • Implement setNetworkState MCP tool for Wi-Fi/cellular/airplane mode control (#462) (android)
  • Implement clipboard MCP tool with ADB and helper APK fallback (#461) (android)
  • Implement biometricAuth MCP tool with emulator fingerprint support (#460) (android, research)
  • Add accessibility focus tracking to observations (#459) (android, a11y)
  • Adapt swipeOn tool for TalkBack using two-finger swipe and scroll actions (#458) (android, a11y)
  • Adapt tapOn tool for TalkBack mode using ACTION_CLICK (#457) (android, a11y)
  • Implement TalkBack auto-detection and infrastructure (#456) (android, a11y)
  • Add capability detection for settings-based accessibility toggle (#409) (android, devxp)
  • Implement adb settings-based accessibility service toggle (#408) (android, devxp)
  • Add optional device labels to device-scoped tool calls (#388) (android)
  • Block MCP tool calls during executePlan (#330) (devxp)
  • Video recording: Android + iOS capture backends (#326) (android, ios, video)
  • Video recording: MCP tools/resources + CLI config (#324) (devxp, video)
  • Video recording: core service + archive retention (#323) (video)
  • Interactive install script with gum + animated AutoMobile logo (#322) (env, devxp)
  • Implement hybrid iOS automation architecture (#319) (ios)
  • Feature Request: Implement pinch-to-zoom gesture in accessibility service (#264) (android, a11y)
  • IDE plugin: MCP feature flags UI (#256) (intellij plugin)
  • IDE plugin: navigation graph rendering (#253) (intellij plugin)
  • IDE plugin: Unix socket transport for MCP attachment (#252) (intellij plugin)
  • Explore scrollToward/contentDirection for swipeOn semantics (#249) (android, devxp)
  • IDE plugin: support TCP/HTTP transport for bun dev mode (#246) (devxp, intellij plugin)
  • Add visual fallback for selected-state detection (#242) (android, devxp, ai)
  • Add identifyInteractions MCP tool to suggest available actions (#224) (android)
  • Add dry run mode for explore tool call (#223) (android)
  • Allow whitelisting navigation graph nodes and edge tool calls (#222) (android)
  • Add await element option to tapOn for waiting on next UI state (#219) (android)
  • Support tapOn for non-unique text within a specific container (#211) (android)
  • Cancel in-progress MCP commands when AI agent or JUnitRunner disconnects (#204) (android, devxp)
  • startDevice should error if AVD already running (#176) (devxp)
  • openSystemTray should avoid redundant swipe when tray already open (#173) (android, devxp)
  • Add retry mechanism for transient CI failures (Maven 403, network issues) (#172) (ci, devxp)
  • MCP Resource: Installed Apps per Device (#163) (android)
  • MCP Resource: Connected Devices (#162) (devxp)
  • MCP Resource: Available Emulators/Simulators List (#161) (devxp)
  • Doctor Tool for Onboarding and Diagnosis (#160) (devxp)
  • Expose tool call history as MCP resource (#130) (devxp)
  • Expose navigation graph nodes as individual MCP resources (#129)
  • Expose navigation graph as MCP resource for IntelliJ plugin (#128) (android, intellij plugin)
  • Expose internal debugging as MCP resource (#127) (devxp)
  • Include Debug Information in MCP Tool Error Responses (#108)
  • Back stack awareness (#78)
  • IntelliJ IDE plugin (#67) (android, devxp)
  • Permission Audit & Capability Inventory (auditPermissions) (#59)
  • Sensitive Data Exposure Scanner (scanDataLeakage) (#57)
  • Element Search Fallbacks (#54)
  • TalkBack Navigation Simulator (simulateTalkBack) (#53)
  • Dark Mode Consistency Checker (#50)
  • Locale & System Configuration Manager (#49)
  • Battery & Charging State Simulator (#48)
  • Sensor Simulation Framework (#47)
  • Live Interactive Element Inspector (#43)
  • HTTP Request Mocking & Recording (mockNetwork) (#42)
  • Network Condition Simulator (simulateNetworkCondition) (#41)
  • ANR Risk Detector (profileAnrRisk) (#39)
  • Navigation graph: Handle bottom sheets, popups, and dialogs (#28)
  • Navigation graph: Handle scroll position as UI state (#27)
  • Retain and Reuse Navigation (#10)
  • clipboard get action returns empty string after successful copy operation (#778)
  • systemTray find with both title AND body criteria always fails to find notifications (#777)
  • Tool registration regression: interaction tools silently failed to register (#745) (ai)
  • dragAndDrop schema allows empty selectors; runtime rejects (#686) (devxp)
  • dragAndDrop should check accessibility service availability (enabled + installed) (#681) (android, a11y)
  • Android drag requests never execute; dragAndDrop always times out (#680) (android, a11y)
  • Preserve double-tap behavior in TalkBack mode (#672) (android, a11y)
  • Dead code detection job fails with ‘Argument list too long’ when issue count is high (#641) (ci, devxp)
  • Navigation graph MCP resources remain empty after active app observation (#614)
  • AutoMobile fails to detect installed Android system images (#612) (android, env)
  • Material3 navigation text labels missing from accessibility hierarchy due to sibling occlusion bug (#591)
  • installApp MCP tool fails with ‘adb: unknown command dump’ (#587) (android)
  • MCP observe responses are excessively large due to unfiltered data (#539) (ai)
  • IDE plugin: AutoMobile tool window ignores IntelliJ theme (#335) (android, intellij plugin)
  • swipeOn direction parameter causes AI agents to swipe opposite of intended direction (#226) (android, devxp)
  • swipeOn tool description causes AI agents to swipe on screen instead of targeting lists (#225) (android, devxp)
  • Selected state not correctly interpreted from view hierarchy (#213) (android)
  • Git state becomes dirty from .mcp.json and .gitignore changes on branch/worktree checkout (#212) (devxp)
  • Stale view hierarchy returned to AI agents after interactions (#205) (android, devxp)
  • MCP client fails to connect at startup with handshaking error (#186) (env, devxp)
  • AutoMobile CLI hangs and doesn’t exit after executePlan completes (#109)
  • Large MCP response warning on Accessibility Service websocket timeout (#86) (devxp)
  • Observe call happening right after an action that should have included observation (#66)
  • Add stub listDevices MCP tool (#781) (devxp, ai)
  • Add stub listApps MCP tool (#780) (devxp, ai)
  • Add keyboard MCP tool with open/close/detect actions (#779) (devxp, ai)
  • Google Weather app filtered out from listApps MCP resource (#715)
  • Accessibility service filters out Android home launcher widgets from view hierarchy (#714)
  • Make identifyInteractions a debug-only MCP tool (#673)
  • Add polling support to tapOn action with searchUntil parameter (#662)
  • Add optional waitFor parameter to observe MCP tool (#658)
  • Add overlay window capability to AccessibilityService (#647)
  • tapOn should use parent clickable element when matched element is not clickable (#646)
  • swipeOn container selection should avoid overlaying clickable elements (#645)
  • Playground app: Add accessibility semantics to navigation components (#571)
  • Research TalkBack/VoiceOver MCP tool behavior and create design doc (#430) (a11y, research)
  • Experiment: Toggle AutoMobile accessibility service via adb settings (#384) (android, a11y, research)
  • Feature Request: Implement drag-and-drop gesture and MCP tool call (#265)
  • swipeOn tool needs better container parameter schema, docs, examples (#263)
  • tapOn tool needs better container parameter schema, docs, examples and validation (#262)
  • explore should stay within current foreground app (#174)
  • [Android] Automatic Work Profile adaptation (#35) (android)
  • Debug Interactions (#11)
  • Retain Navigation in Memory (#9)
  • Android Library SDK (#8)
  • Android WebSocket server (#7)
  • Dockerize AutoMobile (#5) (env)
  • Database for memory and settings (#2)
  • Rewrite internals with interfaces (#1)

Changed

  • Cache installed apps list in SQLite and update via package broadcast receivers (#750) (performance)
  • Optimize observe: Make screenshot capture async/non-blocking (#749) (performance)
  • Optimize launchApp: Run detectTargetUser and checkInstalled in parallel (#748) (performance)
  • Add strict ‘exactly one’ selector enforcement to swipeOn.lookFor (#740) (android, testing, chore)
  • Add strict ‘exactly one’ selector enforcement to pinchOn container (#739) (android, testing, chore)
  • Add strict ‘exactly one’ selector enforcement to tapOn tool (#738) (android, testing, chore)
  • Clean up MCP response message when searchUntil doesn’t need to poll (#700)
  • Add toolResults parsing in AutoMobilePlanExecutor for JUnitRunner (#697) (android, testing)
  • Create Kotlin serialization data classes for tool results in :test-plan-validation (#696) (android, testing)
  • Enhance tapOn response to include selectedElement metadata (#694) (android, testing)
  • Add selectionStrategy parameter to tapOn tool (#693) (android, testing)
  • Add boomerang field to swipeOn for dry-run gesture testing (#675) (devxp, ai)
  • Convert listApps to MCP resource with query support to reduce context usage (#674) (devxp, ai)
  • Optimize Docker publish job cache export settings to reduce build time by ~60% (#640) (ci, performance)
  • Improve error output in startup benchmark script (#639) (ci, performance)
  • Convert daemon management tools to unix socket requests (#608) (ai)
  • Merge enableDemoMode and disableDemoMode into unified demoMode tool (#605) (ai)
  • Merge localization tools into unified changeLocalization tool (#604) (ai)
  • Restrict executePlan and criticalSection tools to daemon mode only (#603) (ai)
  • Refactor deviceSnapshot MCP tools (#601) (ai)
  • Move test recording from MCP tools to unix socket interface (#600) (ai)
  • Refactor MCP video recording tools (#596) (ai)
  • Evolve MCP tool call openSystemTray (#595) (ai)
  • Move identifyInteractions and getNavigationGraph to debug-only tools (#594) (ai)
  • Validate accessibility service version compatibility even when skipAccessibilityDownload is true (#580) (android)
  • Consolidate MCP benchmark PR comments into a single unified comment (#576) (ci, devxp)
  • Optimize accessibility service setup: rename skipAccessibilitySetup to skipAccessibilityDownload (#570) (performance)
  • Feature: Merge window hierarchies into main hierarchy for unified view (#544) (android)
  • Write integration tests for AccessibilityService focus tracking (#533) (android, a11y, testing)
  • Write unit tests for AccessibilityFocusTracker (#532) (testing)
  • Implement dead code detection for TypeScript (#518) (ci, devxp, testing)
  • Memory leak detection and profiling for TypeScript MCP server (#512) (performance, testing)
  • Additional performance benchmarks: observe latency, device boot, test plan execution (#510) (performance, testing)
  • Implement MCP server and daemon startup time benchmark (#509) (devxp, performance, testing)
  • Implement MCP tool call throughput benchmark (#508) (performance, testing)
  • Add comprehensive tests for device snapshot feature (#506) (testing)
  • Implement full app data backup and restore for ADB snapshots (#505) (android, testing)
  • Refactor: Convert all ‘java’ directories to ‘kotlin’ in Android project structure (#504) (android, chore)
  • CI: Cache Android system images to reduce emulator test setup time from 11+ min to <1 min (#497) (android, ci, devxp, performance)
  • IDE plugin: YAML autocomplete for test plan files (#493) (devxp, intellij plugin)
  • CI: Split IDE Plugin validation into separate Build and Test jobs (#486) (ci, intellij plugin)
  • ‘On Merge’ workflow should require all jobs to pass before publishing to Docker Hub (#475) (ci, release engineering)
  • Change explore tool to navigate known graph instead of building it (#445) (devxp)
  • Skip long-running CI jobs for documentation-only PRs (#438) (documentation, ci, devxp, performance)
  • Skip CI checks for accessibility service SHA256 update PRs (#437) (ci, performance, chore)
  • Optimize MCP tools context usage to reduce token consumption (#434) (devxp, performance, ai)
  • Update accessibility setup flow to prefer settings-based toggle (#410) (android, devxp)
  • executePlan schema: multi-device + criticalSection (#392) (devxp, testing)
  • JUnitRunner/Daemon: allocate devices for plan labels (#391) (android, testing)
  • executePlan: multi-device labels + implicit parallelism (#390) (android, testing)
  • Add criticalSection tool call for serialized multi-device steps (#389) (android, testing)
  • IDE plugin: test plan YAML linting (#387) (devxp, intellij plugin)
  • Validate executePlan YAML on read/author (#386) (devxp, testing)
  • Add YAML validation across repo (#385) (devxp, testing)
  • Validation: add XML auto-format/fix script (#370) (ci, devxp)
  • Validation: add shell script auto-fix via shfmt (#369) (ci, devxp)
  • Validation: add TypeScript test validation script (#368) (ci, devxp, testing)
  • Validation: add TypeScript build validation script (#367) (ci, devxp)
  • Validation: add ESLint validation + auto-fix scripts (#366) (ci, devxp)
  • Xcode companion app: core UI surfaces (nav graph, performance, feature flags, logs) (#360) (ios, devxp)
  • Accessibility Bridge distribution: bundle vs on-demand download/caching (#353) (ios, release engineering)
  • Feature: enforce MCP context thresholds via benchmark script (#339) (devxp, performance)
  • Feature: estimate MCP context usage (tools, resources, operations) (#338) (devxp, performance)
  • Recorded test plan migrations + MCP versioning (#331) (devxp)
  • IDE plugin: migrate all UX to Jewel + Compose (#328) (android, intellij plugin)
  • Add curl-based interactive installer entrypoint in README + docs/install (#327) (documentation, env, devxp)
  • Video recording: FFmpeg backend with hardware acceleration (macOS/Linux) (#325) (performance, video)
  • Add AutoMobile tests/plans for Playground docs/using demos (#321) (android, testing)
  • Playground app: add demo flows for docs/using workflows (#320) (android, devxp)
  • IDE plugin: add test recording and YAML plan generation (#318) (android, intellij plugin)
  • Add MCP resources for test timings and performance results (#317) (performance)
  • Feature: Extract Android ‘Displayed’ time metrics from logcat for startup profiling (#311) (android, performance)
  • IDE Plugin: Display recent UI performance results (#282) (android, performance, intellij plugin)
  • IDE Plugin: Display historical test timing data for visual analysis (#281) (android, performance, testing, intellij plugin)
  • JUnitRunner: Use historical test timing to optimize execution order (#280) (android, testing)
  • MCP Daemon: Provide historical test timing to JUnitRunner on startup (#279) (android, testing)
  • MCP Daemon: Record test execution timing in SQLite database (#278) (testing)
  • Rely on view hierarchy updates for navigation destination instead of SDK navigation events (#277) (android)
  • Add GHA workflow to update CHANGELOG from issues since last tag (#274) (release engineering)
  • Add manually triggered GHA workflow for version bumping (#273) (release engineering)
  • Track historical accuracy of predictive UI state (#221) (android, performance)
  • Add predictive UI state to observations based on navigation graph (#220) (android, performance)
  • Start test recording via in-app overlay or accessibility service shortcut (#218) (android)
  • Auto-update accessibility service APK SHA256 via PR when source changes (#217) (android, ci, release engineering)
  • Enable AccessibilityService to filter out views completely hidden by overlays (#214) (android, performance)
  • Track Compose recomposition counts in observation results (#202) (android, devxp, performance)
  • Auto-detect and upgrade accessibility service APK when SHA mismatch (#199) (android, release engineering, devxp)
  • Add Codex MCP client installation docs (#184) (documentation, devxp)
  • Revamp Hot Reload Development Workflow (#164) (devxp)
  • Session State Management to Reduce Required Tool Parameters (#159) (devxp)
  • Dynamic MCP Tool Loading via Workflow-Based Selection (#158) (devxp)
  • Test parallel execution across multiple devices (#151) (testing)
  • Update core tools to respect sessionUuid for device targeting (#150) (testing)
  • Integrate session context into tool execution (#149) (testing)
  • Update CLI to accept –session-uuid parameter (#148) (testing)
  • Add daemon commands for device/session queries (#147) (testing)
  • Make UI stability thresholds configurable (#138) (performance)
  • Analyze and prevent JUnitRunner test pollution (#134) (android, devxp, testing)
  • CI: Run Playground Automobile tests on emulator (#132) (android, ci, testing)
  • Expose latest observation as MCP resource (#131) (devxp)
  • CI: Auto-install accessibility APK for JUnitRunner emulator tests (#126) (ci, performance)
  • MCP Server Daemon for CLI (#125) (performance, testing)
  • Optimize accessibility audit performance with contrast caching (#105) (performance, a11y)
  • Add comprehensive unit tests for accessibility audit checks (#101) (devxp, a11y)
  • Add ESLint rule to prevent .js extensions in TypeScript imports (#90) (devxp)
  • Touch latency testing implementation (#85) (devxp, performance)
  • Migrate test runner from Mocha to Bun’s built-in test runner (#81) (ci, devxp)
  • Natural Language Test Commands (#56)
  • Navigation Graph Test Coverage and Recommendations (#55) (testing)
  • –accessibility-audit mode where WCAG violations fail tests (#52)
  • Flaky Test Detection & Quarantine (#51)
  • Device State Snapshot & Restore (#46) (devxp, performance)
  • Test Recording & Playback with Smart Locators (#45)
  • Parallel Multi-Device Test Orchestration (#44)
  • Visual Regression Testing (compareScreenshot) (#40)
  • –mem-perf-audit mode where leaks, excessive GC, memory pressure, etc fail tests (#38)
  • App Startup Performance Analyzer (profileAppStartup) (#37)
  • –ui-perf-audit mode where jank and poor FPS fail tests (#36)
  • Consolidate scroll, swipeOnScreen, and swipeOnElement into swipeOn (#30)
  • Create monkeyNavigate tool for efficient graph exploration (#29)
  • systemTray find returns cached observation instead of system tray when tray is closed (#776) (android)
  • gfxinfo not reaching stability after launchApp for simple UX (#699) (performance)
  • Test plan/IDE validator doesn’t validate dragAndDrop params (#687) (devxp, intellij plugin)
  • dragAndDrop uses stale cached hierarchy (can drag wrong coords) (#684) (android)
  • dragAndDrop uses fixed 5s timeout; long gestures always fail (#683) (android, performance, a11y)
  • dragAndDrop dropDelay default mismatch with schema/docs (#682) (documentation)
  • MCP Startup Benchmark PR comment has mangled output with escaped newlines (#575) (ci, devxp)
  • AccessibilityService: Hierarchy optimization removes clickable elements with text labels (#572) (android)
  • JUnit runner + MCP daemon parallel execution completely broken (3 critical bugs) (#541) (android, testing, ai)
  • CI: Android Emulator Tests Failing Due to Disk Space Exhaustion (#522) (android, ci)
  • 3 JUnit Runner emulator tests are skipped due to missing test plan file (#473) (android, testing)
  • GitHub Actions runner: No space left on device during Docker Hub publish (#435) (ci, release engineering, env)
  • Build Docker Image CI failing: MCP stdio protocol ENOENT /workspace/src/db/migrations (#382) (ci, env)
  • Update Changelog workflow should use AUTO_MOBILE_PR_TOKEN for PRs (#297) (ci, release engineering)
  • Bump Versions workflow fails because ripgrep is missing (#296) (ci, release engineering)
  • Flaky ClockAppAutoMobileTest fails to reach MCP server in CI (#257) (flaky test, testing)
  • listApps returns all system apps for every profile, causing huge MCP response (#215) (android, performance)
  • Improve long press implementation and add playground testing areas (#203) (android, testing)
  • Flaky accessibility-service WebSocketServerIntegrationTest in CI (#197) (android, flaky test, ci, testing)
  • Navigation tests fail with Robolectric OnBackPressedDispatcher incompatibility (#190) (android, ci)
  • Playground emulator tests fail: koog-agents dependency classloading issue (#189) (android, ci, testing)
  • CI: Android emulator tests failing with shell exit code 1 (#156) (android)
  • JUnit Runner Emulator Tests failing with shell syntax error (#140) (android, ci)
  • Migrate from better-sqlite3 to bun:sqlite for Bun compatibility (#118) (enhancement)
  • JUnit Runner: Test Timeout When Running Multiple Tests Together (#107)
  • PluginException: TestPlanInspection shortName mismatch (#768)
  • Chore: Test clipboard tool (#767)
  • Chore: Test system tray lookFor (#766)
  • Chore: Test biometrics stubbing (#763)
  • Chore: Test takeScreenshot fallback tool (#762)
  • Add unit tests for accessibility APK download/verification paths (#730) (android, testing)
  • Harden accessibility APK download (HTTP status + curl fallback + integrity check) (#729) (android, release engineering, env)
  • Use unique, OS-portable temp path for accessibility APK download (#728) (android, release engineering, env)
  • APK download fails on macOS due to sha256sum dependency (#727) (android, release engineering, env)
  • Add tests for occlusion filtering behavior (#719) (android, performance, testing)
  • Update tool-definitions.json for tapOn selectionStrategy and selectedElement (#695) (documentation, android, testing)
  • Add dragAndDrop test coverage; fakes/interface lack requestDrag (#685) (devxp, testing)
  • Research effectiveness of current navigation graph implementation (#676) (documentation, research)
  • Enhancement: Hybrid hierarchy combining accessibility service + UIAutomator for apps with poor accessibility (#588)
  • Change accessibility service SHA256 update to run daily instead of on every main merge (#577)
  • CI: bun pm trust heapdump exits 1 in memory leak detection (#569)
  • CI failures after #562: native addon build errors (#568)
  • Standardize naming convention: auto-mobile for Maven artifacts, automobile for package names (#540) (android, release engineering, chore)
  • Build and deploy AccessibilityService APK with focus tracking (#534) (android, devxp)
  • CI: Optimize Android emulator test daemon warmup (currently ~90s overhead) (#527) (android, ci, devxp, performance)
  • Memory leak detection and profiling for IntelliJ IDE Plugin (#515) (devxp, performance, testing, intellij plugin)
  • Memory leak detection and profiling for JUnitRunner library (#514) (android, performance, testing)
  • Memory leak detection and profiling for Android AccessibilityService (#513) (android, performance, a11y, testing)
  • Validate and test VM snapshot emulator console commands (#507) (android, testing, research)
  • End-to-end testing for clipboard MCP tool (#501) (testing)
  • Refactor gradle modules: extract shared test plan validation into android/test-plan-validation (#492)
  • Standardize environment variable naming: AUTOMOBILE_ vs AUTO_MOBILE_ prefix (#483) (documentation, env, devxp, chore)
  • Optimize slow TypeScript unit tests (35 files exceed 100ms) (#481) (performance, testing)
  • Add Gradle test report patterns to root .gitignore (#476) (android, testing, chore)
  • Optimize Android emulator test job runtime and reduce flakiness (#446) (android, flaky test, ci, performance)
  • Enable auto-merge on accessibility service update PR (#436) (ci, devxp, chore)
  • Document settings-based accessibility toggle (#412) (documentation, devxp)
  • Test settings-based accessibility toggle on API 29 & 35 (#411) (android, devxp, testing)
  • Research: validate Android design-doc experiments with adb (#393) (android, research)
  • Clarify bug reproduction doc with snapshot and MCP action links (#345) (documentation)
  • Link test recording and YAML plan workflow from user docs (#344) (documentation, android)
  • Call out accessibility service enablement in install/usage docs (#343) (documentation, android)
  • Add decision guide for MCP vs IDE plugin vs JUnitRunner vs SDK (#342) (documentation, android)
  • Add Android first-run path from device setup to a concrete task (#341) (documentation, android)
  • Review docs/ directory for accuracy and add implementation citations (#276) (documentation)
  • Setup Trusted Publishing for npm packages with GitHub Actions (#275) (release engineering)
  • Refactor Tap and Long Press tabs into unified screen with real-time duration tracking (#266)
  • Optimize JUnitRunner heartbeat mechanism for faster daemon timeout detection (#232) (android, devxp, performance, testing)
  • Docker Hub publish job fails: missing bun installation (#188) (ci, release engineering, env, devxp)
  • Phase 3b: JUnitRunner Direct Socket IPC (170ms/test optimization) (#145) (android, performance, testing)
  • Optimize JUnitRunner performance based on #133 research (#135) (android, ci, devxp, performance)
  • Analyze and optimize JUnitRunner performance bottlenecks (#133) (ci, performance)
  • Performance Research, Analysis, and Upgrade of Emulator CI jobs (#123) (android, ci, performance)
  • Register Maven central namespace (#120) (android, release engineering)
  • Enable JUnit Runner tests in GitHub Actions CI (#110) (android, ci, devxp)
  • Improve Android user profile parsing to use structured data instead of regex (#106) (android, devxp)
  • Run Android AutoMobile self tests on an Android Emulator in GHA (#94) (ci, devxp)
  • Android CI Perf Improvements (#93) (ci, devxp, performance)
  • Rename monkeyNav MCP tool call to explore (#80) (devxp)
  • Migrate from pnpm to bun for peak performance (#79) (ci, devxp)
  • Convert from npm to pnpm (#63)
  • Skip Docker CI if Dockerfiles and package.json did not change (#62)
  • Document Claude Code installation and usage (#31) (documentation)
  • Publish scoped package on NPM (#19) (release engineering)

Fixed

  • Bug: Duplicate/embedded observe in launchApp causing bloated MCP responses (#751) (performance)
  • Fix swipeOn coordinate calculation and overlay detection bugs (#722)
  • Bug: swipeOn with lookFor scrolls in wrong direction repeatedly (#671) (android)
  • Fix: Taps via accessibility service were being interpreted as long presses (#666) (android)
  • Bug: launchApp not correctly observing app state after launch (#537) (android)
  • Bug: tapOn schema validation error - container field expects object but receives string (#535)
  • Flaky test: planExecutionLock ‘allows MCP tool calls when no plan is executing’ times out in CI (#482) (flaky test, ci, testing)
  • Fix Android emulator CI job failures - 13m wasted on bugs, Gradle times out (#447) (android, ci)
  • Regression: JUnitRunner tests only using 1 device instead of device pool (#444) (testing)
  • Bug: AutoMobile incorrectly identifies system notification permission dialog as permission controller (#402)
  • Bug: Work profile apps fail observation due to hardcoded u0 user profile in regex patterns (#314) (android)
  • Fix FakeAccessibilityServiceManager interface import path (#731) (android, testing)
  • Flaky test: Session Lifecycle with Device Reuse sometimes returns different device (#548) (flaky test, ci, testing)
  • Fix MonkeyNavigate integration test timeouts (#73)
  • Flaky test: AccessibilityServiceClient WebSocket connection failure handling (#72) (flaky test)
  • Flaky test: AccessibilityServiceClient WebSocket connection failure timeout (#68) (flaky test)

Deprecated

  • Enhance devices resource with pool status and deprecate listDevices tool (#606) (ai)

Removed

  • Remove deprecated listApps MCP tool (#713)
  • Remove daemon_available_devices tool and forward usage to listDevices (#607) (ai)
  • Remove listSnapshots tool - create automobile:snapshots resource instead (#602) (ai)
  • Remove listPerformanceAuditResults MCP tool (#599) (ai)
  • Remove getTestTimings tool (#598) (ai)
  • Remove listVideoRecordings tool - already exposed via automobile:video/archive resource (#597) (ai)
  • Remove duplicate ‘Publish Docker Image’ workflow - Docker publishing already handled by ‘On Merge’ workflow (#474) (ci, release engineering, chore)
  • Remove KotlinPoet and automated test authoring references (#200) (documentation, android)
  • Remove installPlatformDependencies now that AutoMobile is dockerized (#177)
  • Remove getAllConfigs/setDeviceMode/resetConfig MCP tool calls (#175)
  • Delete source mapping and automatic test authoring (#4)
  • Delete iOS implementation (#3)

Security

  • Deep Link Security Validator (validateDeepLinkSecurity) (#58)
  • Security: Insecure temporary file creation in daemon manager (#157)
  • CodeQL check failing in CI (#141) (ci)

[0.0.6] - Unreleased

Changed

  • Placeholder: started fork; release notes not recorded.

[0.0.5] - 2025-07-22

Added

  • Add ADB command auto retry

Changed

  • Improve view hierarchy search for elements with auto retry
  • Refactor ConfigurationManager

Fixed

  • Test authoring fixes

[0.0.4] - 2025-07-08

Added

  • Automate Accessibility Service install and enablement on first ADB command for a device
  • Check APK SHA256 before installing
  • Allow element search to restrict to specific containers in the view hierarchy

Changed

  • Increase accessibility node inspection for better view hierarchy data
  • Filter unnecessary view hierarchy data to reduce observe payloads
  • Parallelize and cache observation and idling steps
  • Refactor BaseVisualChange
  • Reduce tool calls to make it easier for agents to determine tool call selection

[0.0.3] - 2025-07-08

Added

  • Automate Accessibility Service install and enablement
  • Check APK SHA256 before installing
  • Allow element search to restrict to specific containers in the view hierarchy

Changed

  • Increase accessibility node inspection for better view hierarchy data
  • Filter unnecessary view hierarchy data to reduce observe payloads
  • Parallelize and cache observation and idling steps
  • Refactor BaseVisualChange
  • Reduce tool calls to make it easier for agents to determine tool call selection

[0.0.2] - 2025-07-01

Added

  • Accessibility service with availability checks
  • Active window caching
  • Device session management

Changed

  • Improved docs for setup and installation
  • More test coverage

[0.0.1] - 2025-06-24

Added

  • Initial release