Conversation
Adds a block-style ProbeScript construct — matching Maestro's `travel` command — that walks the device's GPS location through an ordered list of waypoints over a duration, for maps/delivery/rideshare/fitness test flows. It's pure orchestration on top of the existing single-point `set location` primitive: the executor linearly interpolates between consecutive waypoints and calls SetLocation repeatedly at ~1s intervals, rather than adding any new device-level GPS integration. Follows the same physical-device exclusion `set location` already has, and the same INDENT-delimited block-parsing shape `retry N times` established. - internal/parser: new TOKEN_TRAVEL/TOKEN_OVER tokens, Waypoint/ TravelStep AST nodes, parseTravel/parseWaypoints. Extracted parseCoordinateLine out of parseActionSetLocation so both share the exact same "lat, lng" reconstruction logic. - internal/runner: DeviceContext.Travel + buildTravelRoute (pure interpolation math, unit-testable without a real/faked adb/simctl), executor dispatch + stepDescription + runTravel. - Docs: dictionary.md, syntax.md, platform/android.md, comparisons/patrol-alternative.md, README.md, CHANGELOG.md. - MCP: write_test tool description and mcp.md example session updated per the MCP coverage rule. Tested: parser tests (waypoints, negative coordinates, optional "over" clause, malformed-waypoint errors) and executor tests (route interpolation math, cloud-mode skip, waypoint-count/coordinate validation). NOT verified against a real emulator/simulator/device — no such device is reachable from this sandbox.
github-merge-queue
Bot
removed this pull request from the merge queue due to a conflict with the base branch
Aug 16, 2026
# Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements FP-6: GPS route simulation, matching Maestro's
travelcommand — a way to walk the device's GPS location through an ordered list of waypoints over time, simulating movement for maps/delivery/rideshare/fitness test flows.New syntax:
lat, lngwaypoints undertravel to, followed by an optional siblingover N secondsclause at the same indent level (same trailing-clause shapewith examples:uses after a test body).over N secondsis optional; omitting it defaults to ~1 second per leg of the route instead of jumping instantly.SetLocationprimitive — the executor linearly interpolates between consecutive waypoints and callsSetLocationrepeatedly at ~1-second intervals (never tighter, to avoid hammeringadb/simctl). No new device-level GPS integration was added.set locationalready has: skips with a single warning on real devices (checked once up front inDeviceContext.Travel, not once per interpolated frame).What changed
internal/parser/token.go,ast.go,parser.go— newTOKEN_TRAVEL/TOKEN_OVERtokens,Waypoint/TravelStepAST nodes,parseTravel/parseWaypoints. ExtractedparseCoordinateLineout ofparseActionSetLocationso bothset locationandtravel toshare the exact same "lat, lng" token-reconstruction logic (no duplicated coordinate parsing).internal/runner/device_context.go—DeviceContext.Travel+buildTravelRoute(pure interpolation math with no device I/O, so it's unit-testable without a real or fakedadb/simctl).internal/runner/executor.go— dispatch case,stepDescription,runTravel(validates waypoint count and parses lat/lng before touching the device, mirroring the cloud-mode skip pattern otherDeviceContext-only verbs use).website/src/content/docs/probescript/dictionary.md,syntax.md,platform/android.md,comparisons/patrol-alternative.md,README.md,CHANGELOG.md([Unreleased]).internal/mcp/server.go(write_testtool description) andwebsite/src/content/docs/tools/mcp.md(new "GPS route simulation" example session) — per this repo's MCP Server Coverage rule.Test plan
go build ./...— passesgo test ./...— passes, summary belowstaticcheck ./...— clean, no new issuesgo vet ./...— cleanset location), optionaloverclause, malformed-waypoint parse error, sibling step after the block still parses correctlybuildTravelRouteinterpolation math (frame/gap counts, exact endpoint landing, default-duration fallback, degenerate <2-waypoint case), cloud-mode skip (nildeviceCtx), waypoint-count validation error, invalid-coordinate error,stepDescriptionoutputadbandxcrunbinaries present but no running emulator/simulator/device to actually drive — I did not claim or fake real-device verification. Everything above is unit/parser/executor-level coverage only; before shipping this in a release, it should be live-verified against a real Android emulator and iOS simulator the way recent CHANGELOG entries forset locationdocument (e.g. "Live-verified fixed against a real emulator").Out of scope for this PR (flagged, not implemented): the Maestro migration converter (
internal/migrate) does not yet map Maestro's owntravel:YAML step to this new syntax — it would currently fall through to a TODO comment like any other unmapped construct. Happy to follow up in a separate PR if wanted.