Problem
replay --maestro is a compatibility path for running common Maestro YAML flows through Agent Device replay. This issue tracks the supported subset and the remaining compatibility work so we do not imply full Maestro parity accidentally.
Reference docs:
Architecture status
Public app research
Sampled public Maestro suites:
Compatibility triage
Easy mappings should translate Maestro syntax to existing Agent Device commands without adding new runtime semantics. Runtime shims are acceptable only when scoped to Maestro compatibility and covered by parser/runtime tests.
Easy next mappings
Sampled syntax still deferred as feature work
Runtime compatibility shims now supported
Supported flow shape and composition
Supported commands
Selector support
Known semantic gaps
Acceptance criteria
Problem
replay --maestrois a compatibility path for running common Maestro YAML flows through Agent Device replay. This issue tracks the supported subset and the remaining compatibility work so we do not imply full Maestro parity accidentally.Reference docs:
Architecture status
src/compat/maestro.src/daemon/handlers/session-replay-maestro-runtime.ts.--maestrothrough generic replay backend plumbing.SessionAction[]from the compat layer.Public app research
Sampled public Maestro suites:
Compatibility triage
Easy mappings should translate Maestro syntax to existing Agent Device commands without adding new runtime semantics. Runtime shims are acceptable only when scoped to Maestro compatibility and covered by parser/runtime tests.
Easy next mappings
setAirplaneModetrue/false ->settings airplane on|off.setLocation->settings location set <latitude> <longitude>.setOrientation->rotate <orientation>.setPermissionsfor supported targets ->settings permission grant|deny|reset <target>.killApp->close <appId>where Maestro provides or config supplies the app id.pasteTextwith a string payload ->type <text>if we accept text-entry equivalence instead of clipboard semantics.startRecording/stopRecording->record start|stopwhen Maestro options map cleanly.assertTrueonly for literal boolean expressions (true/false), if useful; broader JavaScript expressions stay deferred.launchApp.arguments/launchArguments-> simulator launch arguments.Sampled syntax still deferred as feature work
repeat.while: requires replay runtime conditionals.runFlow.when.trueand full expression predicates: requires expression evaluation policy.evalScript: requires a broader sandboxing and side-effect model.eraseText: requires a neutral clear-field capability; emptyfillis intentionally unsupported.copyTextFrom: requires element text extraction into a variable/output model.toggleAirplaneMode: requires reading current state or accepting nondeterministic toggle semantics; prefersetAirplaneModefirst.launchApp.clearState: true,clearKeychain: true, clear-state command, and clear-keychain command: require neutral app reset/keychain capabilities.index,childOf,above,below,containsChild, and related variants.Runtime compatibility shims now supported
scrollUntilVisible: polls withwait/ fuzzy text lookup and scroll probes.runFlow.when.visible.runFlow.when.notVisible.runScriptfile/env with a minimal compatibility sandbox forhttp.post,json, andoutputvariables.tapOn.optional: best-effort skip after the tap retry window.tapOn.pointpercentage coordinates against the current screen snapshot frame.Supported flow shape and composition
---.appId.envmetadata parsing.${VAR}interpolation for string fields used by supported commands.${output.KEY}interpolation after supportedrunScriptoutput assignment.onFlowStart.onFlowComplete.runFlowscalar file form.runFlow.file.runFlow.env.runFlow.commands.runFlow.when.platform.runFlow.when.visible.runFlow.when.notVisible.runFlow.when.true/ expression predicates.Supported commands
launchApp.launchApp.appId.launchApp.stopAppasopen --relaunch.launchApp.clearState: falseandlaunchApp.clearKeychain: falseas tolerated no-op compatibility.launchApp.arguments/launchArguments.launchApp.clearState: true.launchApp.clearKeychain: true.launchApp.permissions.tapOnshorthand text selector.tapOn.id.tapOn.text.tapOn.enabled.tapOn.selected.tapOn.pointabsolute"x,y".tapOn.pointpercentage"x%,y%"against the screen frame.tapOn.repeat.tapOn.delay.tapOn.optional.tapOn.retryTapIfNoChange.tapOn.waitToSettleTimeoutMs.doubleTapOn.longPressOn.inputTextstring value.inputText: { text, label }.openLink.assertVisible.assertNotVisible.extendedWaitUntil.visible.extendedWaitUntil.notVisible.extendedWaitUntil.timeout.takeScreenshot.hideKeyboard.pressKey.back.pressKey.enter/pressKey.return.pressKey.home.back.waitForAnimationToEnd.waitForAnimationToEnd.timeout.stopApp.scrollscalar command.scrollUntilVisible.swipeabsolute coordinates.swipepercentage coordinates.swipe.direction.repeat.times.repeat.timesfrom${VAR}.repeat.while.eraseText.pasteText.copyTextFrom.runScriptfile/env withhttp.post,json, andoutput.evalScript.retry.toggleAirplaneMode.setAirplaneMode.setLocation.setOrientation.setPermissions.addMedia.clearStatecommand.clearKeychaincommand.killApp.travel.assertTrue.assertScreenshot.startRecording.stopRecording.Selector support
id.text.enabled.selected.point.pointagainst the screen frame.index.cssfor web.checked.focused.traits.above.below.leftOf.rightOf.containsChild.childOf.containsDescendants.text/id.Known semantic gaps
extendedWaitUntil.notVisiblecurrently translates towait <timeout>thenis hidden, not a polling hidden wait.assertNotVisibleis not a polling assertion.runScriptis intentionally minimal and does not provide full Maestro JavaScript globals,require,process, arbitrary async APIs, orevalScript.indexandchildOfare rejected instead of silently ignored.Acceptance criteria
agent-device replay --maestro <flow.yaml>reports unsupported Maestro commands with precise command names and line numbers.