Skip to content

v0.21.37 🍰

Latest

Choose a tag to compare

@github-actions github-actions released this 12 Nov 21:16
· 25 commits to main since this release
d2426ff

🍰 Highlights

  • TV apps on LG webOS and Samsung Tizen: new optional provider plugins @agent-device/webos (#4098) and @agent-device/tizen (#4168) drive web apps on TVs. They support open, snapshot, remote keys, pointer, text, scroll, screenshot and logs.
  • Limrun iOS runs on the shared XCTest runner (#4224, #4182). It uses the same snapshot and interaction paths as a local Simulator. Local app installs sync to the instance (#4225), and boot and shutdown map to instance leases (#4275).
  • Parallel web sessions (#4191): each web session is its own device, so sessions with different --session names run side by side on one host. Web device ids now include the session (agent-browser-chrome:session:...).
  • Pin a workspace to a device (#4384) with devicePin in agent-device.json. Commands select within the pin, and conflicting selectors fail with device_pin_conflict.
  • Safer presses on iOS: back is now a verified left-edge swipe (#4460). A synthesized gesture that may already have run is never repeated (#4474). Press and click wait for a moving target within the request's deadline and cancellation (#4461).
  • Deterministic iOS screenshots: screenshot --screen-mask black masks the simulator outline for stable visual baselines (#4206), and --capture-backend runner selects the XCTest runner capture (#4184).
  • More accurate snapshots: iOS 27 system toolbars no longer cover their own controls (#4494). Android alert titles and messages stay in snapshot -i (#4493). Empty text fields show their placeholder (#4467). Zero-area iOS nodes are marked unmeasured and point at scroll --until (#4495).
  • macOS context menus open on a native secondary click (#3962).
  • Hardening from the November audit across the daemon, remote transport, replay, capture and providers (#4355, #4358, #4360, #4362, #4363, #4366 and more).

Breaking changes (MCP)

  • Tool results are text by default (#4466). agent-device mcp returns compact text, with no output schemas and no structuredContent. To get the previous structured results and output schemas, start the server with agent-device mcp --structured. AI SDK tools keep their structured results.
  • UI targets are top-level fields (#4459). press, click, fill, longpress and hover take ref (with an optional label), selector, or x + y. get takes ref or selector. The nested target: { kind, ... } object is rejected with a message that shows the new form. This also applies to batch steps, so update saved batch --steps files and client.batch.run steps. The typed client.interactions.* API is unchanged.
    press {"ref":"@e6"}    click {"selector":"id=\"home/products\""}    press {"x":201,"y":160}
    
  • Operator-only inputs left the tool schemas (#4468). tenant, runId, leaseId and androidDeviceAllowlist are refused as tool input in MCP and AI SDK tools. Set them in the server environment (AGENT_DEVICE_TENANT, AGENT_DEVICE_RUN_ID, AGENT_DEVICE_LEASE_ID) or in config. tools/list shrank from 268 KB to 216 KB, and every input schema is now 5 KB or less.
  • Stricter server arguments and session lock (#4355). agent-device mcp accepts only --structured, --help and --version. Configure the server with AGENT_DEVICE_* variables or AGENT_DEVICE_CONFIG. The session lock now comes only from the serving process (AGENT_DEVICE_SESSION, AGENT_DEVICE_SESSION_LOCK, AGENT_DEVICE_PLATFORM), never from tool input. The stdio server also no longer stalls on blank or malformed lines, keeps answering ping and tools/list during a call, and cancels the daemon request on notifications/cancelled.

What's Changed

  • feat(provider-webos): add LG webOS TV provider plugin by @alimek in #4098
  • fix(ios): report an unreadable system prompt as ALERT_UNRESOLVED, not absence by @thymikee in #4149
  • fix(ios): report keyboard focus from the private-AX snapshot bridge by @thymikee in #4154
  • refactor(providers): share one lease table across cloud providers by @thymikee in #4158
  • chore: report only minor and corroborated review findings by @thymikee in #4178
  • fix(daemon): cancel artifact preparation and refresh failed builds by @thymikee in #4175
  • fix(record): bound a cold video-validator compile by the stop's finalize budget by @thymikee in #4150
  • fix(android): preserve labels across snapshot action boundaries by @andrewfree in #4180
  • fix(android): retry a refused helper start once, and scope the session fake's stall to its helper by @thymikee in #4156
  • .github/workflows: Migrate workflows to Blacksmith runners by @blacksmith-sh[bot] in #4185
  • fix(ios): size sole-display gestures from XCTest screen metrics by @thymikee in #4157
  • chore: print alert corpus surfaces through the Swift owner by @thymikee in #4186
  • refactor(apple): support managed XCTest runner launchers by @muvaf in #4174
  • docs: credit Blacksmith for CI in the README by @thymikee in #4193
  • fix(ios): book every surface on the lit panel, not the first window by @thymikee in #4122
  • fix(daemon): retain Apple runners for leases kept on close by @muvaf in #4195
  • refactor(android): allow providers to install prepared app artifacts by @muvaf in #4194
  • fix(ios): count the keyboard leaving as a post-gesture change by @kdy1 in #4207
  • feat(screenshot): add a per-request iOS simulator screen mask by @sync in #4206
  • perf(ios): check surface hosts inside the snapshot bridge, not with pgrep by @thymikee in #4172
  • fix(ios): report devices CoreDevice cannot reach as not booted by @gronxb in #4210
  • fix: retain third-party license notices in distributions by @thymikee in #4070
  • fix(ios): keep failed alert reads unresolved by @thymikee in #4187
  • docs: point to NoMac's agent-device plugin by @gergomiklos in #4198
  • fix(ios): give simulator AX bridge captures a tree-bound keyboard fact by @kdy1 in #4217
  • refactor(apple): share simulator tools and runner operations by @muvaf in #4213
  • refactor(ios): bind surface geometry and synthesis orientation by @thymikee in #4189
  • perf(ios): reuse current focus for native text replacement by @damian-kolasinski in #4192
  • fix(android): accept a dispatched am start timeout once the app is foreground by @zerone0x in #4143
  • fix(ios): refuse observe-only snapshots that find a system alert by @airowe in #4219
  • fix(limrun): isolate recordings with recording session IDs by @muvaf in #4196
  • fix(limrun): stop answering appstate for an unreachable iOS instance by @airowe in #4176
  • fix(daemon): run find focus through the shared touch-point decisions by @airowe in #4223
  • fix(ios): deliver simulator edge swipes as screen-edge touches by @gronxb in #4211
  • feat(lease): name the iOS simulator mode in a proxy lease device spec by @vitalyiegorov in #4183
  • fix(cli): one five-minute idle TTL for remote device leases by @thymikee in #4220
  • fix(ios): release snapshot bridge exit watchers after each round trip by @kdy1 in #4232
  • feat(limrun): replace iOS AX automation with the shared XCTest runner by @muvaf in #4224
  • feat(screenshot): select the XCTest runner capture with --capture-backend runner by @vitalyiegorov in #4184
  • fix(daemon): settle orphaned recording records when a recording starts by @sylvain-abadie in #4218
  • feat(apple): serve the Simulator AX bridge from the XCTest runner by @thymikee in #4182
  • fix(record): warm the MP4 validator without blocking capture by @thymikee in #4248
  • refactor(apple): make runner surface policy explicit by @thymikee in #4251
  • feat(limrun): sync local iOS and Android app installs by @muvaf in #4225
  • fix(ios): keep the runner alive when XCTest cannot snapshot the app by @thymikee in #4221
  • feat(web): make each web session its own device by @kacper-mikolajczak in #4191
  • refactor(limrun): drop the unused iOS app-alias seam and stale AX-backend wording by @thymikee in #4243
  • feat(client): let callers opt out of post-gesture stabilization by @kdy1 in #4253
  • docs(capture): correct stale Limrun and Revyl capture comments by @thymikee in #4254
  • docs(help): route stale React Native state to reads, not UI navigation by @thymikee in #4231
  • docs(adr): accept 0038 snapshot capture source routing by @thymikee in #4255
  • test(ios): give the post-probe type its own commandId by @thymikee in #4261
  • fix(capture-kit): don't let an identifier-only Android leaf paint over sibling layers by @pcbeingused333 in #4266
  • fix(limrun): recover when the Limrun instance ends under a held lease by @thymikee in #4257
  • fix(mcp): return compact text for untyped tools and bound settle removals by @thymikee in #4246
  • fix(apple): recover runner snapshot bridge after a wedge or restart by @thymikee in #4256
  • fix(release): publish to npm from a GitHub-hosted runner by @thymikee in #4259
  • fix(conformance): wait for Settings to detach before the tap-retry baseline by @thymikee in #4260
  • refactor(apple): give the foreground probe one result shape by @thymikee in #4267
  • refactor(apple): name the foreground reading type by @thymikee in #4271
  • fix(apple): keep runner bridge test hooks out of the shipped package by @thymikee in #4272
  • feat(limrun): share Android text and performance reads by @muvaf in #4268
  • fix(android): clean recording evidence after its pid is reassigned by @thymikee in #4245
  • fix(daemon): keep a session closable while close withholds its device claim by @thymikee in #4263
  • feat(limrun): map boot and shutdown to instance leases by @muvaf in #4275
  • refactor(ios): walk the lit windows once per multi-type element read by @thymikee in #4250
  • fix(cli): name the state dir when daemon stop finds no daemon by @strzhao in #4280
  • docs: record the HarmonyOS clipboard limitation by @strzhao in #4281
  • refactor(apple): simplify snapshot route settlement by @thymikee in #4278
  • docs: slim remote device leases ADR by @thymikee in #4277
  • docs(adr): slim ADR 0004 to a decision record by @thymikee in #4279
  • fix(snapshothelper): preserve TalkBack during Android helper automation by @mvanhorn in #4222
  • fix(ios): preserve simulator app accessibility after runner teardown by @thymikee in #4276
  • fix(apple): stop runner connect retry on signal exit or session drain by @twotnguyen in #4273
  • docs: apply the wording follow-ups from #4277, #4278 and #4279 by @thymikee in #4299
  • fix(ios): prepare snapshot helpers within a shared readiness budget by @andrewfree in #4181
  • refactor(contracts): own snapshot provenance by @thymikee in #4306
  • fix(limrun): start the iOS runner under the hosts' Xcode 27 by @thymikee in #4305
  • docs(agents): prefer runner images and small fixes over selection code by @thymikee in #4312
  • ci(release): build the Limrun runner on the macos-27 image by @thymikee in #4311
  • fix(limrun): list only the connection's instance in devices by @thymikee in #4310
  • refactor(capture-kit): lift the iOS snapshot route into the capture-kit router by @thymikee in #4308
  • refactor(capture-kit): state each snapshot source's circuit scope by @thymikee in #4313
  • fix(daemon): refuse a lease-less provider request as unallocated by @thymikee in #4307
  • perf(ios): skip the simulator accessibility write when this host's preferences already allow it by @thymikee in #4300
  • feat(macos): open context menus on native secondary click by @janicduplessis in #3962
  • fix(macos-helper): skip the window-sharing indicator when choosing the front window by @janicduplessis in #3965
  • fix(cli): treat device status and release selectors as explicit-only by @twotnguyen in #4315
  • fix(android): delete characters with KEYCODE_DEL when typing backspaces by @twotnguyen in #4269
  • fix(daemon): enforce device claim for commands with explicit selector by @twotnguyen in #4270
  • refactor(contracts): derive snapshot producer facts from one registry by @thymikee in #4309
  • docs: route the management command family in the skill and install help by @strzhao in #4282
  • test(ios): answer the panel fixture's label through KVC by @thymikee in #4320
  • ci(vitest): annotate failing tests on the GitHub check by @thymikee in #4316
  • fix(cli): guide screenshot callers to the session prerequisite by @strzhao in #4289
  • docs: slim scroll clip authority ADR by @thymikee in #4327
  • docs: slim collocation decision record by @thymikee in #4328
  • docs: slim Apple platform consolidation ADR by @thymikee in #4325
  • docs: slim daemon runtime coupling ADR by @thymikee in #4324
  • docs: slim interactive replay ADR to a decision record by @thymikee in #4331
  • docs: slim request-bound runtime ADR by @thymikee in #4330
  • docs: slim proposed event journal ADR by @thymikee in #4329
  • docs: slim screen recording proposal by @thymikee in #4326
  • fix(cli): print failures as a recoverable summary line by @thymikee in #4302
  • feat(cli): render scoped snapshot refs in their pinned form by @strzhao in #4284
  • test(android): wait on the InputMethod window before comparing keyboard pixels by @thymikee in #4319
  • test(daemon): pin that sessionless screenshot refusals never capture by @thymikee in #4335
  • fix(interaction): omit changedFromBefore when no verify baseline was captured by @strzhao in #4338
  • docs(adr): slim ADR 0023 to a decision record by @thymikee in #4323
  • fix(platform-apple): simplify alert action retry budgets by @pcbeingused333 in #4123
  • test(repo-guards): fail when an ADR cites a missing repository file by @thymikee in #4336
  • chore(gates): typecheck every scripts/ TypeScript file by @thymikee in #4364
  • refactor: align ADRs with the code and delete unreachable command-runtime families by @thymikee in #4361
  • fix(daemon): report failed close/disconnect, cancel shutdown timers, scope daemon diagnostics by @thymikee in #4357
  • test: drive coverage-flaky timing tests by timer order and events by @airowe in #4353
  • fix(android): return framework share sheets as a system surface by @mwolson in #4349
  • fix(contracts): normalize rejected cleanup in durable resource disposal by @yuminn-k in #4346
  • fix(interaction): disclose label-fallback when the native-ref preflight recovers by label by @airowe in #4352
  • fix(cli,mcp): reliable MCP stdio, cancellation, shared session lock, strict mcp args by @thymikee in #4355
  • fix(remote): correct fill recording recovery guidance by @nikitabhagat2307-prog in #4351
  • fix(daemon): harden command input handling for type, alert, push, clipboard, paths and artifacts by @thymikee in #4360
  • fix(selectors): keep downgraded target annotations under the payload ceiling by @airowe in #4354
  • chore(gates): make test guards and CI selectors fail on the violations they exist for by @thymikee in #4356
  • feat(provider-tizen): add Samsung Tizen TV provider plugin by @alimek in #4168
  • fix(daemon): contain session artifact paths by @thymikee in #4389
  • fix(remote): reject invalid artifact responses and settle interruptions by @thymikee in #4385
  • docs(agents): correct context and prefer proven integration coverage by @thymikee in #4380
  • fix(daemon): bound materialized-path retention by @thymikee in #4383
  • fix(daemon): private launcher state and strict integer env parsing by @thymikee in #4369
  • feat(harmonyos): report the keyboard band in snapshot responses by @strzhao in #4285
  • fix(replay): escape recorded interpolation, run scripts off the event loop, harden Maestro and test flows by @thymikee in #4363
  • fix(host-kit): one async process-identity reader and one identity-checked stop escalation by @thymikee in #4359
  • fix(apple-runner): guard XCTest build cleanup paths by @thymikee in #4382
  • fix(cli): classify cloud failures by HTTP status by @thymikee in #4381
  • fix(providers): secure web text entry, harden WebDriver transport and buttons, honor --relaunch by @thymikee in #4362
  • fix(capture): audit remediation for redaction, capture lifecycle, contract validation and snapshot performance by @thymikee in #4366
  • fix(ios): clear a secure field with deletes before the caret tap by @TanmayOG in #4350
  • fix(remote): harden transport (redirects, artifact paths, upload hash, socket cap, proxy RPC errors) by @thymikee in #4358
  • fix: review follow-ups (web text-entry hint, recorder echo names, mutation report on cancel) by @thymikee in #4394
  • refactor(apple): remove redundant cleanup platform state by @thymikee in #4393
  • ci: install the Android SDK through one setup-android-sdk action by @thymikee in #4400
  • fix(selectors): make only value rewrites live recorded placeholders by @thymikee in #4398
  • fix(maestro): run child entrypoints through symlinked paths by @thymikee in #4397
  • test(daemon): assert daemon exit with the predicate retirement confirms by @thymikee in #4404
  • fix(kernel): rank visionOS below iPhone and iPad by @thymikee in #4410
  • fix(release): continue publishing plugins after failures by @thymikee in #4409
  • fix(daemon): allow idle recovery after failed relaunch by @thymikee in #4408
  • fix: fit target annotations after echo redaction by @thymikee in #4406
  • fix: scroll until through virtualized content by @thymikee in #4407
  • fix(open): boot a stopped Android AVD named by --device before claiming it by @thymikee in #4396
  • build(check): run every locally runnable catalog gate in pnpm check by @thymikee in #4401
  • fix(coverage-changed): refuse stale or foreign reports via the coverage stamp by @Huyvux12 in #4387
  • fix(daemon): authenticate before recording idle activity by @thymikee in #4430
  • fix(aws): evaluate the final readiness observation by @thymikee in #4429
  • ci: run iOS and macOS smoke on parallel Blacksmith runners by @thymikee in #4418
  • fix(test): prevent an untracked child in the mutation baseline by @thymikee in #4416
  • ci: speed validation and fix daemon exit detection by @thymikee in #4417
  • chore: apply review notes from #4406, #4408 and #4410 by @thymikee in #4415
  • fix(capture): exempt floating chrome above bottom tabs by @thymikee in #4405
  • docs(harmonyos): apply the keyboard band follow-up review notes by @strzhao in #4436
  • fix(wait): run duration waits without device discovery by @thymikee in #4433
  • fix(upload): constrain forwarded ticket schemes by @thymikee in #4431
  • fix(web): scope implicit browser sessions to workspaces by @thymikee in #4414
  • fix(capture): enforce network scan merge bounds by @thymikee in #4386
  • fix(release): treat asset tags as data by @thymikee in #4390
  • fix(ios): refuse snapshot-derived input without a screen origin by @shamilovtim in #4439
  • fix(daemon): anchor repeated gesture overlays to each execution by @thymikee in #4447
  • feat(lease): name a backend baseline in a proxy lease device spec by @V3RON in #4236
  • feat(config): pin workspace devices with explicit selectors by @Rutvij97 in #4384
  • fix(mcp): accept digest settle results in the interaction output schema by @thymikee in #4458
  • ⚠️ MCP breaking: feat(mcp)!: take UI targets as top-level ref, selector, and x/y by @thymikee in #4459
  • fix(device-selection): keep host env out of the request device cache key by @thymikee in #4464
  • test(device-pin): cover existing-session admission and error sources by @thymikee in #4465
  • ⚠️ MCP breaking: feat(mcp)!: advertise only agent inputs in MCP tool schemas by @thymikee in #4468
  • fix(daemon): put non-takeover options first in DEVICE_IN_USE hints by @thymikee in #4469
  • fix(android): keep scroll target taps outside system bars by @thymikee in #4446
  • fix(ios): own idle snapshot bridge socket errors by @thymikee in #4463
  • feat(interaction): pre-dispatch admission owner for runtime press/click by @thymikee in #4461
  • fix(apple): preserve simulator boot observation freshness by @thymikee in #4445
  • docs(adr): pre-dispatch admission for resolved targets by @thymikee in #4457
  • fix(journal): bound writes and recover rotation failures by @thymikee in #4470
  • ⚠️ MCP breaking: feat(mcp)!: return text-only tool results by default; add mcp --structured by @thymikee in #4466
  • test: enforce declared launches for daemon fixtures by @thymikee in #4432
  • fix(snapshot): print an empty text field's placeholder in snapshot -i by @shahjahanpak in #4467
  • fix(test-kit): reject companion exit gates and tolerate deleted sources by @thymikee in #4473
  • fix(journal): clarify failure diagnostics by @thymikee in #4472
  • perf(test): walk only possible daemon fixture family files in the launch guard by @thymikee in #4475
  • fix(android): recognize exited screenrecord processes by @shamilovtim in #4450
  • fix(wait): ignore an editable field's typed value in wait text by @thymikee in #4489
  • fix(android): keep alert dialog title and message in snapshot -i by @thymikee in #4493
  • fix(snapshot): stop iOS 27 system toolbars from covering their own controls by @thymikee in #4494
  • ci(android): reuse cached system images across emulator workflows by @thymikee in #4490
  • fix(capture): publish cropped screenshots atomically after scaling by @thymikee in #4478
  • fix(ios): never repeat a synthesized gesture that may have run by @thymikee in #4474
  • fix(ios): mark zero-area nodes unmeasured and point their press refusal at scroll --until by @ruizemanuel in #4495
  • fix(ios): make back the verified left-edge swipe by @thymikee in #4460

New Contributors

Full Changelog: v0.21.36...v0.21.37