Changelog
[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
[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
[v0.0.33] - 2026-06-04
Other
[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
[v0.0.22] - 2026-04-30
Other
[v0.0.21] - 2026-04-30
Other
[v0.0.20] - 2026-04-29
Other
[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
[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
[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
[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