YamlCommandReader in Maestro: Purpose, Methods, and Usage Examples
YamlCommandReader is the central entry point in the Maestro framework for loading, parsing, and validating YAML flow definitions, converting them into executable MaestroCommand objects while abstracting file I/O and error translation.
The YamlCommandReader class serves as the primary façade for Maestro's YAML-based scripting engine. In the mobile-dev-inc/Maestro repository, this component bridges raw flow files written by developers and the internal orchestration system that executes mobile UI tests, handling everything from simple file reads to complex error reporting with line numbers.
Core Responsibilities of YamlCommandReader
Located at maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCommandReader.kt, this utility class delegates heavy parsing logic to MaestroFlowParser while managing the complete lifecycle of YAML flow processing:
- Flow File Ingestion: The
readCommands(flowPath)method loads entire flow definitions from.yamlor.ymlfiles, returning aList<MaestroCommand>(source) - Single Command Parsing:
readSingleCommand(flowPath, appId, command)handles inline command strings for API interactions like the Studio REPL (source) - Configuration Extraction:
readConfig(flowPath)isolates theMaestroConfigblock without processing the full command list, useful for metadata inspection (source) - Workspace Configuration:
readWorkspaceConfig(configPath)parses the optionalmaestro.yamlworkspace file or returns an emptyWorkspaceConfigif absent (source) - File Watching:
getWatchFiles(flowPath)identifies dependent files—such as referencedinitFlowscripts or media assets—that should trigger flow re-execution during hot-reloading (source) - Configuration Retrieval:
getConfig(commands)walks parsed command lists to extract the embeddedapplyConfigurationcommand (source) - Syntax Validation:
checkSyntax(maestroCode)performs dry parses to validate YAML structure without writing files to disk (source)
Error Handling and Validation Strategy
YamlCommandReader implements sophisticated error translation through mapParsingErrors and errorMessage helper methods. Rather than exposing low-level exceptions like FlowParseException or JsonProcessingException directly, it catches these at the parsing boundary and transforms them into user-friendly SyntaxError instances with precise line numbers and contextual hints (source).
This abstraction ensures that CLI users, Studio interface consumers, and programmatic API callers receive consistent, actionable error messages when flow definitions contain syntax errors or schema violations.
Practical Code Examples
Loading an Entire Flow from Disk
The CLI's TestRunner uses this pattern to initialize test execution:
import maestro.orchestra.yaml.YamlCommandReader
import java.nio.file.Paths
val flowPath = Paths.get("samples/login_flow.yaml")
val commands = YamlCommandReader.readCommands(flowPath) // Returns List<MaestroCommand>
Reference: See TestRunner.runSingle for production usage (TestRunner.kt).
Parsing Inline Commands for REPL Interfaces
Studio server components utilize this method for real-time command testing:
val flowPath = Paths.get("") // Dummy path for error reporting context
val appId = "com.example.app"
val yamlCmd = "- tapOn: \"Login\""
val command = YamlCommandReader.readSingleCommand(flowPath, appId, yamlCmd)
Extracting Flow Configuration Metadata
val config = YamlCommandReader.readConfig(Paths.get("myflow.yaml"))
println(config?.name) // Access flow name or other metadata
Identifying Files for Hot-Reload Watching
val watchFiles = YamlCommandReader.getWatchFiles(Paths.get("myflow.yaml"))
watchFiles.forEach { println("Watching: $it") }
Validating YAML Syntax Without File I/O
try {
YamlCommandReader.checkSyntax("""
- launchApp:
packageName: "com.example"
""".trimIndent())
println("Syntax validation passed")
} catch (e: SyntaxError) {
println("Invalid YAML: ${e.message}")
}
Integration Points in the Maestro Codebase
YamlCommandReader operates as the linchpin between YAML DSL files and Maestro's execution engine, with critical dependencies across the project:
| Component | File Path | Usage Pattern |
|---|---|---|
| CLI Test Runner | maestro-cli/src/main/java/maestro/cli/runner/TestRunner.kt |
Invokes readCommands() to load flows before execution (source) |
| Studio Server | maestro-studio/server/src/main/java/maestro/studio/DeviceService.kt |
Parses commands received from web UI via readSingleCommand() (source) |
| Parser Delegation | maestro-orchestra/src/main/java/maestro/orchestra/yaml/MaestroFlowParser.kt |
Heavy-weight parser that YamlCommandReader delegates to for YAML-to-object conversion |
| Exception Types | maestro-orchestra/src/main/java/maestro/orchestra/yaml/FlowParseException.kt |
Internal exceptions that YamlCommandReader translates to public SyntaxError |
Summary
- YamlCommandReader acts as the public façade for all YAML flow processing in Maestro, located in the
maestro-orchestramodule. - It provides nine primary operations ranging from full flow loading to single command parsing and workspace configuration reading.
- Error translation converts low-level parsing exceptions into actionable
SyntaxErrorinstances with line number context. - The class delegates actual YAML parsing to
MaestroFlowParserwhile managing file I/O, path resolution, and validation workflows. - Key consumers include the CLI TestRunner for batch execution and Studio Server for interactive command processing.
Frequently Asked Questions
What is the difference between YamlCommandReader and MaestroFlowParser?
YamlCommandReader serves as the high-level public API that handles file operations, path resolution, and error translation, while MaestroFlowParser performs the heavy-weight YAML syntax parsing and schema validation. The reader delegates to the parser but shields callers from implementation details like Jackson JSON processing exceptions and file system abstractions.
How does YamlCommandReader handle invalid YAML syntax?
When checkSyntax() or read methods encounter malformed YAML, the internal mapParsingErrors function catches FlowParseException or JsonProcessingException instances and converts them into SyntaxError objects. These errors include specific line numbers and contextual messages generated by the errorMessage and fallbackErrorMessage helpers, providing clear feedback about missing colons, indentation errors, or invalid command keys.
Can YamlCommandReader parse workspace configuration files?
Yes, the readWorkspaceConfig(configPath) method specifically handles the optional maestro.yaml workspace configuration files. If the file exists, it parses the workspace settings; if absent, it returns an empty WorkspaceConfig object, allowing the rest of the system to proceed with default configuration values.
Where is YamlCommandReader used in the Maestro CLI?
The CLI's TestRunner class utilizes YamlCommandReader.readCommands() at the entry point of test execution (around line 66-68 in TestRunner.kt) to transform YAML flow files into executable command lists. Additionally, Studio server components use readSingleCommand() to parse individual commands sent from the web interface during interactive debugging sessions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →