Documentation
¶
Index ¶
- Constants
- Variables
- func AppendEvidenceStep(run RunState, step EvidenceStep) error
- func GenerateReport(run RunState) (string, error)
- func NewExecutor(r Runner) drivers.Executor
- func RegisterDefaultDrivers(reg *drivers.Registry, exec drivers.Executor)
- func Run(ctx context.Context, args []string, stdout, stderr io.Writer) error
- func SaveConfig(root string, cfg Config) error
- func SaveCurrentRun(root string, run RunState) error
- type AgentElement
- type AgentTreeOptions
- type CLI
- type Capabilities
- type CommandFailed
- type CommandResult
- type Config
- type CrashSummary
- type Element
- type ElementChange
- type EvidenceStep
- type ExecRunner
- type FailurePolicy
- type Flow
- type FlowAfter
- type FlowCondition
- type FlowCoordinate
- type FlowParam
- type FlowPathPoint
- type FlowStep
- type FlowWait
- type GlobalOptions
- type ImageEvidence
- type LaunchCandidate
- type LaunchCommands
- type LaunchConfig
- type NearSelector
- type NetworkEvidence
- type Output
- type PersistedTree
- type PhysicalDevice
- type ReportData
- type ReportEvidenceStep
- type ReportIssue
- type RunState
- type Runner
- type Selector
- type Simulator
- type TreeDelta
- type VideoValidation
Constants ¶
const ( MavDir = ".mav" ConfigFile = ".mav/config.yaml" AppMapFile = ".mav/app-map.yaml" CurrentRunRef = ".mav/current-run" )
const EvidenceStepsFile = "evidence.jsonl"
const TreesDir = "trees"
TreesDir is the subdirectory under a run dir where snapshot/delta JSON files live. Created on demand by PersistTree.
Variables ¶
var Version = "dev"
Version is what this binary reports as itself. It is stamped at link time by the release build (-X github.com/bitomule/mav/internal/mav.Version) and left as "dev" otherwise, so a locally built binary never claims to be a release it is not.
It exists because until now mav could not answer the question. An agent reporting a bug, a run whose evidence is read weeks later, and anyone comparing what is installed against what a project expects all need a version, and `mav --version` answered `unknown_command`.
Functions ¶
func AppendEvidenceStep ¶
func AppendEvidenceStep(run RunState, step EvidenceStep) error
func GenerateReport ¶
func NewExecutor ¶ added in v0.4.0
NewExecutor adapts a mav.Runner to drivers.Executor. Drivers receive this in their constructors instead of the full Runner.
func RegisterDefaultDrivers ¶ added in v0.4.0
RegisterDefaultDrivers wires the canonical driver portfolio into reg: AXe (fast a11y + semantic tap), idb (device coord tap / screenshot / logs / crashes / install), Baguette (sim multitouch + system UI + hardware buttons), simctl (sim lifecycle / video / locale / log stream).
idb is the canonical device driver. Sim-only multitouch / system-UI / hardware-button operations go through baguette. On device targets where baguette is unavailable, cli.go surfaces a structured error rather than silently falling back.
func SaveConfig ¶
SaveConfig serializa cfg a .mav/config.yaml.
It uses yaml.Marshal deliberately instead of the hand-written writer that lived here before: that one omitted empty values (writeCommandKV), which makes it impossible to express "this field is present and holds the empty string". That distinction did not matter while the config was flat, but it is exactly the one platform profiles need so a profile can *cancel* a command inherited from the base instead of inheriting it.
Note on what does NOT change: this function rebuilds the whole file, so comments the user wrote by hand are lost. That already happened with the previous writer; SaveConfig has never read the prior file to preserve anything.
func SaveCurrentRun ¶
Types ¶
type AgentElement ¶ added in v0.4.0
type AgentElement struct {
ID string `json:"id,omitempty"`
Label string `json:"label,omitempty"`
Role string `json:"role,omitempty"`
Value string `json:"value,omitempty"`
Title string `json:"title,omitempty"`
Subrole string `json:"subrole,omitempty"`
Focused string `json:"focused,omitempty"`
Enabled string `json:"enabled,omitempty"`
Frame string `json:"frame,omitempty"`
Actionable bool `json:"actionable"`
}
AgentElement is the LLM-facing projection of Element. It drops fields agents rarely use (Frame by default, redundant Hint-like fields), promotes the "is this useful for the current decision?" verdict (Actionable), and ranks the list so the most relevant ~40 nodes are at the top.
The goal is the same that drove the RocketSim CLI's --agent mode: ~50%+ fewer tokens vs the full tree without losing decision-grade information.
func AgentTree ¶ added in v0.4.0
func AgentTree(elements []Element, opts AgentTreeOptions) []AgentElement
AgentTree projects elements to the agent-facing shape, ranked by relevance:
- focused first (the field the user is in matters most)
- then actionable + enabled + visible-ish (taps/inputs the agent can use)
- then everything else, in original order
Ranking is stable across runs because Element ordering from ExtractElements is already deterministic. The cap is applied after sort.
type AgentTreeOptions ¶ added in v0.4.0
type AgentTreeOptions struct {
// Max caps the output length. Zero -> agentDefaultMax (40).
Max int
// WithFrame keeps the Frame field on each element. Off by default
// because frames are 30-50 bytes of noise per element for most agent
// decisions.
WithFrame bool
}
AgentTreeOptions controls the compact projection.
type CLI ¶
type CLI struct {
Runner Runner
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
Root string
// contains filtered or unexported fields
}
func (CLI) OK ¶ added in v0.8.0
OK is the CLI-bound counterpart of the package-level OK: it's the single place a command's success fields pick up which simulator or device they actually acted on. Route every success output through c.OK (not the bare OK) so nobody has to remember to add the field by hand -- in hot-path usage (an agent driving mav command-by-command, not just via `mav run`) that field is how the next call knows which target to keep using instead of guessing; guessing wrong with several agents on one machine means silently driving someone else's simulator while taps and assertions keep passing.
type Capabilities ¶ added in v0.0.10
type Capabilities struct {
// Kind is the target these capabilities were resolved FOR. fields()
// needs it because the right guidance differs by platform: prescribing
// baguette or simtime to a macos target sends the reader to install
// tools that provide nothing there.
Kind drivers.TargetKind
Tools map[string]bool
LaunchRecipe bool
Accessibility bool
AccessibilityDriver string
SemanticActions bool
CoordinateTap bool
CoordinateTapDriver string
DeviceFallback bool
DeviceFallbackDriver string
Multitouch bool
MultitouchDriver string
NetworkCapture bool
NetworkCaptureDriver string
WallClock bool
Debug bool
IDBIssue string
IDBNext string
// macOS: TCC is the deciding factor, not the API. It is reported
// separately because the permission holder is NOT mav but the process
// running it, and that must be said or the user looks where it is not.
MacPermissions string
MacPermissionsNext string
}
type CommandFailed ¶ added in v0.6.0
type CommandFailed struct{}
CommandFailed requests a non-zero process exit after a structured failure line has already been written. It avoids duplicating the failure on stderr.
func (CommandFailed) Error ¶ added in v0.6.0
func (CommandFailed) Error() string
type CommandResult ¶
type Config ¶
type Config struct {
ProjectName string
Root string
TargetKind string
AppTarget string
DeviceTarget string
DeviceUDID string
DeviceName string
BundleID string
ProcessName string
SimulatorUDID string
SimulatorName string
SimulatorRuntime string
Locale string
Language string
LogSubsystem string
LogCategory string
PreferredUIDriver string
AllowShell bool
TargetCommand string
// TargetCommandRequired says a configured target_command is the only
// acceptable source of the simulator: if it fails, times out or prints
// nothing, the command fails instead of quietly falling back to whatever
// simulator happens to be booted. nil means unset, which resolves to
// true (see targetCommandRequired) -- the config declared how the target
// is chosen, so choosing differently in silence contradicts it. Setting
// it to false is the explicit opt-out back to warn-and-fall-back.
TargetCommandRequired *bool
// TargetCommandTimeout bounds a single target_command invocation. Empty
// means the default (see defaultTargetCommandTimeout). A Go duration
// string: "90s", "3m".
TargetCommandTimeout string
Launch LaunchConfig
Tools map[string]bool
// DefaultProfile and Profiles are kept raw so they can be rewritten
// without being lost, and so `mav doctor` can list them. ActiveProfile
// is the one resolved for this invocation ("" if none).
DefaultProfile string
Profiles map[string]profileYAML
ActiveProfile string
Fixtures map[string][]string
// VM says the target app runs inside a disposable macOS VM instead of
// on this machine. Which tool provides that VM is mav's business, not
// the config's: see internal/mav/vm.go.
VM bool
// AppPath is filled by the launch recipe at run time (app_path step);
// it is neither read from nor written to the YAML. It is how the macOS
// driver knows which bundle to run, its equivalent of the UDID.
AppPath string
}
func DefaultConfig ¶
func LoadConfig ¶
LoadConfig loads .mav/config.yaml applying whichever profile the documented precedence selects. Equivalent to LoadConfigWithProfile(root, "").
func LoadConfigRaw ¶ added in v0.12.0
LoadConfigRaw loads the config WITHOUT applying any profile. It is what the paths that later write (setup, sim select, device select) must use: only a config without an overlay can go back to disk without flattening the profile onto the base. See SaveConfig's guardrail.
func LoadConfigWithProfile ¶ added in v0.12.0
LoadConfigWithProfile loads the config and overlays a platform profile.
Selection precedence, strongest to weakest:
- profileOverride, whatever an explicit --profile brings
- MAV_PROFILE in the environment
- default_profile in the config itself
- none: the base fields are used as is
A requested profile that does not exist is an error, never a no-op: accepting the flag and carrying on with the base would be dead configuration of the same kind target_command_ignored exists to make visible.
type CrashSummary ¶ added in v0.4.0
type CrashSummary struct {
// Header fields
BundleID string `json:"bundle_id,omitempty"`
AppName string `json:"app_name,omitempty"`
AppVersion string `json:"app_version,omitempty"`
OSVersion string `json:"os_version,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
IncidentID string `json:"incident_id,omitempty"`
BugType string `json:"bug_type,omitempty"`
// Body fields (best-effort, may be empty depending on bug_type)
Process string `json:"process,omitempty"`
Exception string `json:"exception,omitempty"` // e.g., "EXC_BAD_ACCESS (SIGSEGV)"
Termination string `json:"termination,omitempty"` // e.g., "SIGNAL Code -1"
Reason string `json:"reason,omitempty"` // exception.subtype + asi when present
CrashedThread string `json:"crashed_thread,omitempty"` // thread name when present
}
CrashSummary is the parsed view of an iOS .ips crash report. iOS 15+ stores .ips as two concatenated JSON documents: a header line followed by a body. We extract just the fields agents and humans actually need for triage; the full body stays in the original .ips on disk.
func ParseIPS ¶ added in v0.4.0
func ParseIPS(raw []byte) (CrashSummary, error)
ParseIPS reads an iOS 15+ .ips body and extracts a CrashSummary.
The .ips format is two JSON documents separated by a newline: the first line is the header (app/bundle/version metadata), the rest is the body (exception, termination, threads, ...). We split on the first `\n{` boundary so a header with arbitrary keys still parses cleanly.
Older formats (iOS 14 and below; PLIST-style symbol-rich text) are NOT supported -- this parser intentionally targets the modern JSON format where idb's `crash show` output now lives.
func (CrashSummary) OneLiner ¶ added in v0.4.0
func (s CrashSummary) OneLiner() string
OneLiner renders a single-line summary suitable for the HTML report's crash card. Format: "EXC_BAD_ACCESS (SIGSEGV) in MyApp on com.example — reason". Empty when the summary lacks the bits we need.
type Element ¶
type Element struct {
ID string `json:"id,omitempty"`
Label string `json:"label,omitempty"`
Role string `json:"role,omitempty"`
Value string `json:"value,omitempty"`
Frame string `json:"frame,omitempty"`
Enabled string `json:"enabled,omitempty"`
Selected string `json:"selected,omitempty"`
Visible string `json:"visible,omitempty"`
Subrole string `json:"subrole,omitempty"`
Title string `json:"title,omitempty"`
PID string `json:"pid,omitempty"`
Focused string `json:"focused,omitempty"`
Depth int `json:"depth,omitempty"`
}
Element is the framework-neutral view of a single node in an accessibility tree (axe or baguette JSON). It collapses the differences between drivers so callers (`mav ui tree`, `mav ui tap`, flow conditions, gesture helpers, focus probes) can reason in a single vocabulary.
func Compact ¶ added in v0.4.0
Compact applies the 80-element cap on top of an already-dedup'd slice. Exported so PersistTree can re-cap a raw extraction without re-parsing.
func ExtractElements ¶
ExtractElements parses an AX tree (axe JSON or any structure that walkAX understands) and returns a flat, de-duplicated list of Elements. Bounded at 80 to keep output tractable for downstream callers; the same cap drove `compactElements` historically.
func ExtractElementsRaw ¶ added in v0.4.0
ExtractElementsRaw parses an AX tree and returns the de-duplicated flat list WITHOUT the 80-element cap. Used by evidence persistence so the `*.full.json` fixture stays complete; downstream tooling (agents, the HTML report) still consumes the compact (capped) variant from ExtractElements / Compact.
func LoadPersistedTree ¶ added in v0.4.0
LoadPersistedTree reads back a compact tree snapshot. Used by `mav ui tree --since step-N` to compute a fresh delta against an older step without needing the caller to keep history in memory.
type ElementChange ¶ added in v0.4.0
type ElementChange struct {
ID string `json:"id,omitempty"`
Key string `json:"key,omitempty"` // populated when ID is empty
Diffs map[string]string `json:"diffs"`
}
ElementChange records the per-field deltas between the same logical element (matched by ID, or by structural key when ID is empty) in two snapshots. Diffs maps field name -> "old → new".
type EvidenceStep ¶
type EvidenceStep struct {
Name string `json:"name"`
Note string `json:"note,omitempty"`
File string `json:"file"`
Kind string `json:"kind"`
CreatedAt string `json:"created_at"`
// Tree snapshot fields (P4 upgrade). Populated when the step also
// persisted an accessibility tree under <runDir>/trees/. Absent on
// older evidence steps; readers MUST tolerate empty values.
TreePath string `json:"tree_path,omitempty"`
FullPath string `json:"tree_full_path,omitempty"`
DeltaPath string `json:"tree_delta_path,omitempty"`
TreeHash string `json:"tree_hash,omitempty"`
// Video correlation (P4 upgrade). When a recording is active,
// MonotonicMs is the host monotonic clock at capture; VideoOffsetMs
// is monotonic_ms minus the recording's start, in milliseconds.
// Both empty when no recording is running.
MonotonicMs int64 `json:"monotonic_ms,omitempty"`
VideoOffsetMs int64 `json:"video_offset_ms,omitempty"`
}
func LoadEvidenceSteps ¶
func LoadEvidenceSteps(run RunState) []EvidenceStep
type ExecRunner ¶
type ExecRunner struct{}
func (ExecRunner) Run ¶
func (ExecRunner) Run(ctx context.Context, name string, args ...string) CommandResult
func (ExecRunner) Start ¶
func (ExecRunner) Start(ctx context.Context, logPath string, name string, args ...string) (int, error)
Start launches a background process and returns its PID.
An empty logPath means "discard the output", not an error. Launching a macOS app needs it: there stdout and stderr are not the real log channel, OSLog is, and mav already captures that on its own with `log stream`, so forcing the driver to invent a file just to throw it away would be worse. Before this, an empty logPath died with an `open : no such file or directory` that said nothing about the cause.
type FailurePolicy ¶ added in v0.6.0
type Flow ¶
type FlowCondition ¶
type FlowCondition struct {
ID string `yaml:"id,omitempty"`
Text string `yaml:"text,omitempty"`
TextContains string `yaml:"textContains,omitempty"`
TextStartsWith string `yaml:"textStartsWith,omitempty"`
TextRegex string `yaml:"textRegex,omitempty"`
Value string `yaml:"value,omitempty"`
ValueContains string `yaml:"valueContains,omitempty"`
Role string `yaml:"role,omitempty"`
Enabled *bool `yaml:"enabled,omitempty"`
Selected *bool `yaml:"selected,omitempty"`
Focused *bool `yaml:"focused,omitempty"`
Visible *bool `yaml:"visible,omitempty"`
Index *int `yaml:"index,omitempty"`
Bounds string `yaml:"bounds,omitempty"`
Near *NearSelector `yaml:"near,omitempty"`
ParentOf *Selector `yaml:"parentOf,omitempty"`
ChangedFrom string `yaml:"changedFrom,omitempty"`
Stable bool `yaml:"stable,omitempty"`
Any []FlowCondition `yaml:"any,omitempty"`
All []FlowCondition `yaml:"all,omitempty"`
Not *FlowCondition `yaml:"not,omitempty"`
}
func (FlowCondition) Selector ¶ added in v0.6.0
func (c FlowCondition) Selector() Selector
type FlowCoordinate ¶ added in v0.6.0
type FlowPathPoint ¶ added in v0.6.0
type FlowStep ¶
type FlowStep struct {
Action string
Params map[string]string
Where Selector
After *FlowAfter
OnFailure FailurePolicy
Any []FlowCondition
All []FlowCondition
Not *FlowCondition
Points []FlowPathPoint
Do []FlowStep
Env map[string]string
}
type FlowWait ¶ added in v0.6.0
type FlowWait struct {
ID string `yaml:"id,omitempty"`
Text string `yaml:"text,omitempty"`
TextContains string `yaml:"textContains,omitempty"`
Value string `yaml:"value,omitempty"`
ChangedFrom string `yaml:"changedFrom,omitempty"`
Stable bool `yaml:"stable,omitempty"`
Any []FlowCondition `yaml:"any,omitempty"`
All []FlowCondition `yaml:"all,omitempty"`
Not *FlowCondition `yaml:"not,omitempty"`
Timeout string `yaml:"timeout,omitempty"`
}
type GlobalOptions ¶
type ImageEvidence ¶ added in v0.3.3
type ImageEvidence struct {
OK bool `json:"ok"`
Issue string `json:"issue,omitempty"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Size int64 `json:"size,omitempty"`
}
func ValidateEvidenceImage ¶ added in v0.3.3
func ValidateEvidenceImage(path string) ImageEvidence
type LaunchCandidate ¶ added in v0.0.10
type LaunchCommands ¶ added in v0.0.10
type LaunchCommands struct {
Healthcheck string `yaml:"healthcheck,omitempty"`
Build string `yaml:"build,omitempty"`
AppPath string `yaml:"app_path,omitempty"`
Install string `yaml:"install,omitempty"`
Launch string `yaml:"launch,omitempty"`
Cleanup string `yaml:"cleanup,omitempty"`
}
LaunchCommands is the base config's launch recipe. The fields carry omitempty because in the base "empty" and "absent" mean the same thing: no command. The distinction does matter in a platform profile, which needs to be able to *override* an inherited command with nothing, which is why profiles use their own pointer-based type (see profileLaunchCommandsYAML) instead of reusing this one.
type LaunchConfig ¶ added in v0.0.10
type LaunchConfig struct {
Mode string `yaml:"mode"`
Commands LaunchCommands `yaml:"commands"`
}
type NearSelector ¶ added in v0.6.0
type NetworkEvidence ¶ added in v0.5.0
type NetworkEvidence struct {
HAR string `json:"har,omitempty"`
OK bool `json:"ok"`
Issue string `json:"issue,omitempty"`
Requests int `json:"requests,omitempty"`
Responses int `json:"responses,omitempty"`
Status4xx int `json:"status_4xx,omitempty"`
Status5xx int `json:"status_5xx,omitempty"`
UniqueDomains int `json:"unique_domains,omitempty"`
Active bool `json:"active,omitempty"`
}
type Output ¶
type PersistedTree ¶ added in v0.4.0
type PersistedTree struct {
CompactPath string // <runDir>/trees/step-NN_<name>.json (capped, agent-facing)
FullPath string // <runDir>/trees/step-NN_<name>.full.json (uncapped, debug)
DeltaPath string // <runDir>/trees/step-NN_<name>.delta.json — empty when previous == nil
Hash string // sha256 hex of the compact JSON; populates EvidenceStep.TreeHash
}
PersistedTree is the metadata PersistTree returns to its caller so the evidence step record can reference it.
func PersistTree ¶ added in v0.4.0
func PersistTree(runDir string, stepIdx int, name string, raw []Element, previous []Element) (PersistedTree, error)
PersistTree writes the compact and full snapshots of a tree under <runDir>/trees/, optionally also writing a delta vs `previous`.
Naming uses the step index zero-padded to 2 digits plus a slug derived from name (alphanumerics + dashes). The leading index keeps the directory listing chronological — important for the HTML report.
When previous == nil no delta is written and DeltaPath is empty. The hash is the sha256 of the compact JSON so EvidenceStep.TreeHash can identify identical screen states cheaply.
type PhysicalDevice ¶ added in v0.1.0
func ListPhysicalDevices ¶ added in v0.1.0
func ListPhysicalDevices(ctx context.Context, runner Runner) ([]PhysicalDevice, error)
type ReportData ¶
type ReportData struct {
RunID string `json:"run_id"`
CreatedAt string `json:"created_at"`
// Fixture is the named state seeded before launching the app, if there
// was one. Without this the manifest cannot answer "what state did
// this start from?", and a run whose evidence does not say that is not
// reproducible, which is exactly what the verified manifest promises.
Fixture string `json:"fixture,omitempty"`
Dir string `json:"dir"`
Screenshot string `json:"screenshot,omitempty"`
// A pointer so it can be ABSENT. As a value, a run without a loose
// screenshot, which is every flow, serialized
// `"screenshot_evidence":{"ok":false}`: a negative verdict on something
// that never existed. In an evidence layer that is worse than saying
// nothing, because an agent cannot tell it apart from a broken capture.
ScreenshotEvidence *ImageEvidence `json:"screenshot_evidence,omitempty"`
Steps []ReportEvidenceStep `json:"steps"`
Video string `json:"video,omitempty"`
VideoMP4 string `json:"video_mp4,omitempty"`
VideoStatus string `json:"video_status"`
VideoIssue string `json:"video_issue,omitempty"`
VideoDuration string `json:"video_duration,omitempty"`
VideoFrames string `json:"video_frames,omitempty"`
Logs string `json:"logs,omitempty"`
Network NetworkEvidence `json:"network,omitempty"`
Crashes []string `json:"crashes,omitempty"`
Commands []string `json:"commands,omitempty"`
Issues []ReportIssue `json:"issues,omitempty"`
ValidStepCount int `json:"valid_step_count"`
InvalidStepCount int `json:"invalid_step_count"`
Verdict string `json:"verdict"`
Outputs map[string]string `json:"outputs,omitempty"`
}
type ReportEvidenceStep ¶ added in v0.3.3
type ReportEvidenceStep struct {
EvidenceStep
Index int `json:"index"`
DisplayName string `json:"display_name"`
Image ImageEvidence `json:"image"`
}
type ReportIssue ¶ added in v0.3.3
type RunState ¶
type RunState struct {
ID string
Dir string
LogsPath string
Commands string
Processes string
Started time.Time
}
func NewProjectRunState ¶ added in v0.3.2
func NewRunState ¶
type Selector ¶ added in v0.6.0
type Selector struct {
ID string `yaml:"id,omitempty" json:"id,omitempty"`
Text string `yaml:"text,omitempty" json:"text,omitempty"`
TextContains string `yaml:"textContains,omitempty" json:"textContains,omitempty"`
TextStartsWith string `yaml:"textStartsWith,omitempty" json:"textStartsWith,omitempty"`
TextRegex string `yaml:"textRegex,omitempty" json:"textRegex,omitempty"`
Value string `yaml:"value,omitempty" json:"value,omitempty"`
ValueContains string `yaml:"valueContains,omitempty" json:"valueContains,omitempty"`
Role string `yaml:"role,omitempty" json:"role,omitempty"`
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
Selected *bool `yaml:"selected,omitempty" json:"selected,omitempty"`
Focused *bool `yaml:"focused,omitempty" json:"focused,omitempty"`
Visible *bool `yaml:"visible,omitempty" json:"visible,omitempty"`
Index *int `yaml:"index,omitempty" json:"index,omitempty"`
Bounds string `yaml:"bounds,omitempty" json:"bounds,omitempty"`
Near *NearSelector `yaml:"near,omitempty" json:"near,omitempty"`
ParentOf *Selector `yaml:"parentOf,omitempty" json:"parentOf,omitempty"`
}
Selector is the typed, driver-neutral predicate used by CLI commands and flows. All populated fields are combined with AND. Index is applied after every other filter.
type Simulator ¶
func ListSimulators ¶
type TreeDelta ¶ added in v0.4.0
type TreeDelta struct {
Added []Element `json:"added,omitempty"`
Removed []Element `json:"removed,omitempty"`
Changed []ElementChange `json:"changed,omitempty"`
}
TreeDelta is the difference between two Element snapshots. Agents consume it to reason about state transitions without re-reading the full tree on every step. The shape is intentionally JSON-stable: agents can rely on added/removed/changed keys.
func TreeDiff ¶ added in v0.4.0
TreeDiff computes the delta from prev to next. Elements are matched by non-empty ID first; for elements without ID, by a structural key (role + label + frame). Empty deltas (matched, no field difference) are omitted.
Determinism: outputs are sorted by ID then Key so JSON serialisation is stable across runs — critical for golden tests and for the HTML report's diff renderer.
type VideoValidation ¶ added in v0.0.7
func ValidateEvidenceVideo ¶ added in v0.0.7
func ValidateEvidenceVideo(path string) VideoValidation
Source Files
¶
- agent_tree.go
- baguette_glue.go
- capabilities.go
- cli.go
- config.go
- crash_fallback.go
- crashparse.go
- dap.go
- device.go
- drivers_adapter.go
- drivers_register.go
- evidence.go
- flow.go
- flow_lint.go
- idb_repair.go
- launch.go
- launch_env.go
- macclock.go
- macproxy.go
- macvideo.go
- matrix.go
- network.go
- output.go
- runner.go
- runstate.go
- selector.go
- setup_detectors.go
- sim.go
- simlock.go
- target.go
- treediff.go
- treepersist.go
- uiobservation.go
- version.go
- vm.go
- vmattach.go
- vmguest.go
- vminstall.go
- vmrunner.go
- worker.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package codes is MAV's structured error vocabulary.
|
Package codes is MAV's structured error vocabulary. |
|
Package drivers defines the pluggable driver layer that MAV uses to talk to iOS simulators and physical devices.
|
Package drivers defines the pluggable driver layer that MAV uses to talk to iOS simulators and physical devices. |
|
axe
Package axe wraps the AXe accessibility CLI as a MAV driver.
|
Package axe wraps the AXe accessibility CLI as a MAV driver. |
|
baguette
Package baguette wraps the baguette CLI (https://github.com/tddworks/baguette) — a Swift host-side simulator driver built on private SimulatorKit symbols.
|
Package baguette wraps the baguette CLI (https://github.com/tddworks/baguette) — a Swift host-side simulator driver built on private SimulatorKit symbols. |
|
idb
Package idb wraps Facebook's idb_companion.
|
Package idb wraps Facebook's idb_companion. |
|
macos
Package macos groups the drivers that operate on the Mac's own apps.
|
Package macos groups the drivers that operate on the Mac's own apps. |
|
network
Package network provides the network-capture drivers.
|
Package network provides the network-capture drivers. |
|
simctl
Package simctl wraps Apple's `xcrun simctl` for simulator lifecycle, video recording, log streaming, screenshots, and locale config.
|
Package simctl wraps Apple's `xcrun simctl` for simulator lifecycle, video recording, log streaming, screenshots, and locale config. |