Commit Graph
59 Commits
Author SHA1 Message Date
Brent Vatne d6b97331b3 Flows: compare two runs of a flows file checkpoint by checkpoint (compare:flows)
compare:flows --before DIR --after DIR [--output FILE] pairs the checkpoints of two runs by
flow and checkpoint name and diffs each pair with the review's screenshot diff, setting aside
the status bar and home indicator as a review does. Each checkpoint is unchanged, changed
(with the regions that differ), missing (no picture on one side, with why), different-size
(another device or orientation, so not diffed), added or removed.

The runs' conditions that differ (app, platform, device, OS version, locale, orientation,
appearance) are listed rather than refused, so an iPhone run and an Android run still line
up. On a foldable the status bar is not set aside, because a run does not record which panel
was in use; the result says so.

The pairing is a pure function in contracts/flow-comparison.ts; the diff is in
review/flow-comparison.ts. cli now imports review, which ARCHITECTURE lists.
2026-10-24 14:00:39 -07:00
Brent Vatne 6394778533 Merge the second round of flows fixes from #74: strategy.ts session inputs wait for the session's platform on a flows run
runSessionExploration now chooses its strategy before it knows the platform, so the #74 change
is ported onto strategyInputs: a flows run without --platform reads its secrets once the
session reports its platform.
2026-10-24 11:59:55 -07:00
Brent Vatne d944e7d6d8 Flows: keep a checkpoint a budget stops, cap a described step at 40 calls, and skip flows with nothing to compare
From a second review of #74:

- A checkpoint was marked attempted before the explorer answered, so a screen, turn or time
  budget that stopped the run during the call dropped it from exploration.flows. It is now
  marked once the call returns, and recorded as "The run stopped before it." otherwise.
- A described step's 40-call limit relied on the session's maxTurns, which a Codex session
  does not have: one step could spend the whole run's budgets. runGoal now counts the calls
  and fails the step at the limit.
- A checkpoint on a screen that withholds its picture (a secret on it, a blocked screenshot)
  is recorded without one and its flow goes on, as the code did; the README said it ended the
  flow. The docs now say so, and the run's summary lists such checkpoints.
- A flow with no checkpoint on the platform being run is skipped, and its steps need no model
  or secrets.
- explore:session --flows without --platform required every platform's secrets. It now checks
  them once the session reports its platform, still before any device work.
- A test runs a described step through runBoundedSession, which rejects with AGENT_CANCELLED
  when step_done ends the step, as the real sessions do.
2026-10-24 11:58:05 -07:00
Brent Vatne 66393ddbc9 Merge the flows fixes from #74: strategy.ts filters secrets and model access by platform, counts turns, and hands the explorer the checkpoints a flows run never attempted 2026-10-23 23:01:36 -07:00
Brent Vatne e66fc6c690 Flows: record every planned flow and checkpoint, and fix what a relaunch left stale
From a review of #74 and an adversarial review of its fixes:

- A checkpoint reused the picture taken on arriving at a screen even after a relaunch, or after
  the model looked again. The arrival picture now lasts only until the next look at the app.
- Flows and checkpoints went missing from exploration.flows: a flow whose relaunch failed, a
  checkpoint whose observation threw (its flow still said completed), and on a budget stop,
  everything not reached. start_flow now creates the record before relaunching; a checkpoint
  that throws is recorded as missing and fails its flow; and when the run ends, the explorer
  asks the strategy which checkpoints it never attempted and records them as missing. A run
  blocked at launch records every flow as failed.
- explore:session's first flow started wherever the app was. The first open relaunches when
  the run follows flows, before the check that the app stays open.
- A flow's journey stopped at the first screen change that was not a transition. The walk now
  goes on as another journey of the flow (journeyIds).
- A launch-URL error, at the start or during a relaunch, was a plain error that ended the run
  without its secrets removed. Both are wrapped through failureText. After two relaunches fail
  in a row, the flows stop.
- A described step or a secret limited to another platform no longer needs a model or a value.
- assertFlowsFit counts the tool calls the flows take, as assertReplayFits does.
2026-10-23 22:58:54 -07:00
Brent Vatne 1b0a0a1d96 Explorations: one place chooses and starts the strategy that drives the explorer
binary/strategy.ts holds what explore:binary and explore:session each branched on: chooseStrategy
checks the options before any device starts (a model, a replay plan or a flows file),
strategyInputs reads the {{secret:NAME}} inputs they need, and startStrategy returns the session
that drives the explorer's tools, with how the report names it. A new strategy is one more case
there. assertAppUrl moves to binary/app-url.ts so strategy.ts does not import run.ts.
2026-10-23 22:03:29 -07:00
Brent Vatne 064d8be4e4 Flows: follow named flows through a build, with named checkpoints that two runs pair up by
explore:binary and explore:session take --flows FILE: named flows, each a list of exact actions
(the --replay format), steps described in words ({"do": …}) and named checkpoints. Each flow after
the first starts from a relaunched app. A model carries out each described step on its own, with
only observe and act, so the explorer still records and blocks what it always does.

The explorer offers start_flow, checkpoint and end_flow to a flows run. A checkpoint is always
recorded, reusing the picture taken on arrival when nothing has happened since. A flow becomes a
journey of the map, named after the flow, and the exploration report lists each flow with its
status and its checkpoints in order (exploration.flows, optional). A failed step ends its flow
and names the checkpoints it did not reach; the next flow still runs.
2026-10-23 21:42:44 -07:00
Brent Vatne ac30f4d691 Hosted repack: share a run's repack by native fingerprint, not by the build each job found (#71) 2026-10-23 17:56:25 -07:00
Brent Vatne eaba870ac9 CI capture: timings per job, and a review waiting on a baseline says what it is doing (#68) 2026-10-23 16:47:59 -07:00
Brent Vatne c9ab89025b Screens: a filmstrip layout beside the grid, switched at the top right; the sidebar is headed by its find field (#64) 2026-10-23 12:03:24 -07:00
Brent Vatne f2de6c9002 Repack sharing: list the EAS environment without --non-interactive, and check every eas flag against the pinned eas-cli (#61) 2026-10-20 17:13:34 -07:00
Brent Vatne 8e86e6a14e Argent capture waits for a new session's tool server, and a side keeps its light captures when only its dark session fails (#58) 2026-10-20 16:38:49 -07:00
Brent Vatne ebbcbb62c4 A failed hosted repack starts again, and a run's matrix jobs share one repack of each commit (#59) 2026-10-20 16:34:15 -07:00
Brent Vatne f620577e30 A review waits beside head for a baseline of its base commit that is still capturing (#56) 2026-10-20 14:15:25 -07:00
Brent Vatne b72a70f7d8 Capture asks again when simulator:control --list fails, and a session that can't switch to its appearance stops before folding (#54) 2026-10-20 13:46:16 -07:00
devin-ai-integration[bot]andbrent e47399440f Store opened iPhone Duo screenshots upright in explore:binary/session (#51)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-20 12:18:17 -07:00
devin-ai-integration[bot]andbrent 46b46bb184 Add --replay to explore:binary and explore:session (#50)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-20 12:11:32 -07:00
Brent Vatne 942bdaad40 Capture waits for a focused field's keyboard, and the comment names off-screen changes (#52) 2026-10-20 12:09:40 -07:00
Brent Vatne b1edd7ea81 Reviews survive one target's flaky session: resend a tool whose service didn't start, and report the targets that captured (#48) 2026-10-19 19:47:06 -07:00
Brent Vatne 50230b7f93 Viewer previews: wait 20 s for the alias, then link it with a going-live note (#46) 2026-10-19 19:18:48 -07:00
Brent Vatne 33f31da08e CI: retry a failed simulator:control action and a GitHub lookup the Actions API hasn't caught up on (#47) 2026-10-19 19:18:43 -07:00
Brent Vatne 1796a9b810 Viewer: screenshots fade in, go blank on a target switch, and Compare reads the next screen ahead (#44) 2026-10-19 16:17:56 -07:00
Brent Vatne 87aec5b820 Screens, search and the counts leave out routes a public report never captured, as the Map does (#42) 2026-10-19 12:51:11 -07:00
Brent Vatne 6539b5c002 Source planning: follow every single-directory tsconfig paths alias (#38) 2026-10-19 09:28:17 -07:00
Brent Vatne 422cf8caf4 Viewer: theme, full screen and shortcuts in a "…" menu; the top right keeps only the Map's camera (#37) 2026-10-19 09:24:13 -07:00
devin-ai-integration[bot]andbrent b281c734f4 Viewer: make the Inspector resizable from its left edge (#34)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 22:39:36 -07:00
devin-ai-integration[bot]andBrent Vatne 23227ca55c capture.maxSessions: a review-wide session ceiling, spent on separate light/dark sessions when that pays (#32)
Co-authored-by: Brent Vatne <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 21:42:28 -07:00
devin-ai-integration[bot]andBrent Vatne ed1bf34434 Faster capture: parallel compare with early-abort region search, one Argent bridge thread per capture (#29)
Co-authored-by: Brent Vatne <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 21:29:58 -07:00
Brent Vatne bdf9e597d3 Large moves read as one moved region instead of fragments (#18) 2026-10-18 17:03:07 -07:00
devin-ai-integration[bot]andbrent 9063de5c52 Inspector: stack Before over After for landscape screenshots (#24)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:55:35 -07:00
devin-ai-integration[bot]andbrent 21ed8c06f6 Text that differs between a build's own light and dark captures is runtime state, not a change (#28)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:49:03 -07:00
devin-ai-integration[bot]andbrent 6795f19d04 Viewer: ⌘K is a command palette (#22)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:47:31 -07:00
devin-ai-integration[bot]andbrent 990e2ecc8d Ignore a foldable's rail status-bar pill like a phone's status bar (#23)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:44:10 -07:00
devin-ai-integration[bot]andbrent 6fa7cba087 Viewer: switch targets in place, glide [ ] and +/- from the key down, keep screenshots up while they swap (#20)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:38:35 -07:00
devin-ai-integration[bot]andbrent f728eb187b Quiet PR comment: count + report link heading, per-device subtitle, changed screens as a list, previous run kept while a new run works (#19)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:36:23 -07:00
devin-ai-integration[bot]andbrent d069a892dc Clip diff regions that cross a system band; Android status-bar band 7 % (#25)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:33:21 -07:00
devin-ai-integration[bot]andbrent 929ac82765 A comment or whitespace-only edit to a source file changes no screen (#26)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:31:59 -07:00
devin-ai-integration[bot]andbrent d5d6a5ff72 Inspector says why an excluded or redirect route has no screenshot (#31)
Co-authored-by: brent <[email protected]>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-18 16:31:26 -07:00
devin-ai-integration[bot] 5c19061b0f Excluded routes leave the public map instead of showing as "Not compared" (#27) 2026-10-18 14:45:06 -07:00
Brent Vatne 1254a99841 Viewer preview fixtures: one report per target (#16) 2026-10-18 10:00:26 -07:00
Brent Vatne c2bae00f31 Fix flaky CI: stray SIGTERMs, port-lock race, fixture colour collisions, mid-review downloads, cold-Vite reloads (#17) 2026-10-18 09:56:13 -07:00
Brent Vatne 65b79684f3 Hosted previews serve the report as static files under the token, with no encryption and no Explore expiry (#14) 2026-10-18 09:45:24 -07:00
Brent Vatne b8b43ee2c8 Hosted previews open from a manifest, load screenshots on demand, and switch targets in place (#11) 2026-10-18 09:45:23 -07:00
Brent Vatne c59ccce32b PR comment map: opt in with report.comment.map; README: Compare at full width; release 0.19.7 (#13) 2026-10-17 21:54:20 -07:00
Brent Vatne c24049c443 README: animated hero and Compare, a map of changed screens in the PR comment (#12) 2026-10-17 21:31:58 -07:00
Brent Vatne 078902710b Capture iPhone Duo on EAS Simulator with eas simulator:control, for both controllers (#9)
Capture iPhone Duo on EAS Simulator with eas simulator:control, for both controllers

- eas-cli 25.2.0: app.approveUrlScheme after install, appearance.set for Argent on
  iOS EAS sessions, and springboard.restart as the last fold recovery step. The
  controller's own tools come first; these only fill what neither controller has.
- iPhone Duo on EAS: both controllers' folds are verified (Argent by its tree,
  agent-device by its screenshot) and recovered by restarting SpringBoard and
  folding again, once; never by stopping the session's tool-server.
- agent-device opens the app before folding on EAS, as it does locally.
- agent-device pinned to 0.21.29-nightly.20261018.74 for callstack/agent-device#3776,
  which stops @expo/ui sliders on a regular-width display from wedging its runner.
- A session EAS fails to start is replaced, up to five times within 30 minutes,
  with a growing wait, only when the failure is provably EAS's.
- doctor warns about Argent's single appearance only for Android EAS sessions.
2026-10-17 20:44:41 -07:00
Brent Vatne 46ff99aad1 Viewer: held keys repeat and glide, arrows enter the map, held modifiers show their keys, T and ⇧T (#10) 2026-10-17 18:52:55 -07:00
Brent Vatne a75cbf84ea Link the deployment when the example alias still serves an earlier one
The example report reuses one token and the same fixture reports, so an alias
still pointing at the previous deployment serves the token page and the same
report bytes; only its reports.json (an older Viewer's listing) differed, and
that mismatch failed the job as PREVIEW_VERIFY_FAILED. The alias now counts as
moved only once it serves this deployment's listing and reports, and an alias
that never does is PREVIEW_ALIAS_BEHIND: the verified deployment is linked
with a warning. The deployment's own origin is still checked strictly.

The README's "Run it yourself" now opens with the two ways to use Explore and
which one needs an Expo account.
2026-10-17 16:26:40 -07:00
Brent Vatne 6c10477c5b Run explore:binary on a local simulator, and bring the README up to date (#8)
explore:binary --simulator local explores a build on a simulator or emulator
it creates on this Mac, with no EAS login: the same devices capture uses,
recorded for the startup sweep, driven by agent-device with its own daemon or
by a local Argent tool-server. The report opens in the local Viewer; --upload
hosts it.

The README now covers local repack and local simulators, a single-path quick
start that reviews a change or explores a build, targets, and requirements
split by what each path needs. The explore-binary, explore-setup and
readme-refresh skills follow.
2026-10-17 15:53:21 -07:00
Brent Vatne 284ae6a780 Local simulators and emulators, capture targets, faster and sturdier runs (#7)
Capture on this machine (local iOS simulators and Android emulators, with agent-device or Argent) as well as on EAS Simulator; name several capture targets per config (a phone, a foldable closed and open, Android) and review them in parallel with shared builds; repack locally with a local simulator; and make captures faster and harder to break: controller fault containment, an Argent fold recovery, upright captures of an opened iPhone Duo, a settle after each root reset, a route retry after an adb drop, emulator port reservation, a startup sweep of what interrupted captures leave running, and agent-device 0.21.28.
2026-10-17 14:55:21 -07:00