Repository navigation
Conversation
Rent an iOS simulator or Android emulator from Revyl's execution API and drive it through its device-proxy actions, with no WebDriver or Appium session in between. Ships as the separately published `@agent-device/revyl` plugin on the v2 provider contract. - `connect revyl` verifies the key with one cheap request and stores the platform, optional model and OS version, and a required public app URL. - A lease starts the device, waits for the worker and the device, and stops the run it started when the start never becomes ready; release, a repeat release, and daemon shutdown all end the session. - Snapshots reuse the platform readers that already parse the same XML on a WebDriver-backed device, so refs and selectors resolve identically. - Touch, fill, scroll, back, home, open, deep links, close, and screenshots ride the device actions; every family Revyl has no action for refuses with a typed reason naming the substitute.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Size Report
Startup median (7 runs, lower is better):
|
…rides by Map Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
All reported issues were addressed across 46 files
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
Reviewed at 93627f4. The Revyl runtime can leak billed devices on several lease paths, and the Coverage CRAP check fails on code this PR adds. There are no conflicts. The leaks, the CRAP failure and the missing live run need to be fixed before merge. Release forgets the session before Revyl confirms the stop (https://github.com/callstack/agent-device/blob/93627f4/packages/provider-revyl/src/runtime.ts#L212). If /stop fails, the daemon retries, finds no session and records the lease as released. A transient Revyl error then leaves the device running until the 30-minute idle timeout. Please make a session leave the lease table only after Revyl confirmed the stop, as limrun release does, so the daemon retry reaches it. Recovery cannot stop anything after a daemon restart (https://github.com/callstack/agent-device/blob/93627f4/packages/provider-revyl/src/runtime.ts#L110). The in-memory map is empty, so
When readiness fails, the stop error is discarded (https://github.com/callstack/agent-device/blob/93627f4/packages/provider-revyl/src/revyl-session.ts#L86). No session is stored, so nothing retries, and the user sees only provider-not-ready. Please surface the cleanup failure with the run id, or keep the run in the lease table so release and shutdown retry it. Does the health probe fail on the normal attach path? The module comment says the worker answers 503 until the device is attached (https://github.com/callstack/agent-device/blob/93627f4/packages/provider-revyl/src/revyl-session.ts#L99), but
Every device-proxy endpoint, body shape and response field is checked only against a fake written from the same assumptions, and the PR states no real Revyl credentials were used. A wrong action name or body shape would fail only on a real device, and the leaks above are unobserved on the real backend. Please attach a live run from a packed install on iOS and Android: connect, open reaching device_connected with the run id, snapshot, click by ref, fill, scroll, screenshot decoding as PNG, back and home on Android, close, disconnect, and Revyl's own status showing the run stopped. Also show Ctrl-C during open leaving no orphaned run, and a kill -9 of the daemon with a live lease followed by restart and expiry recovery showing the run stopped. Please redact the key and run URLs. The Coverage CRAP check fails on Not blocking, take or leave: reject a stop body with Could the provider lease table be shared instead of re-implemented here? One table extracted from limrun could own allocate-once per lease, in-flight tracking, stop-then-forget release, a shutdown drain, deadline bounding and a recovery hook, plus a shared Two inline threads are fixed at this commit and can be resolved: the fixture overrides map #4092 (comment) and the scrypt owner derivation #4092 (comment). The P1 threads that still apply: start failure leaves session #4092 (comment); shutdown clears first #4092 (comment); restart recovery #4092 (comment); release deletes before stop #4092 (comment); deadline ignored #4092 (comment); late set after shutdown #4092 (comment); health 503 retried #4092 (comment); docs example omits plugin #4092 (comment); readiness deadline check #4092 (comment); start cancel signal #4092 (comment); swallowed cleanup error #4092 (comment); stop body success #4092 (comment). The P2 threads that still apply: compare table #4092 (comment); connection test echo #4092 (comment); incomplete PNG fixture #4092 (comment); snapshot signal recheck #4092 (comment); raw backendUrl hash #4092 (comment); non-live bind ready #4092 (comment); non-live interaction ops #4092 (comment); private https hosts #4092 (comment); artifacts listing #4092 (comment); apiUrl without apiKey #4092 (comment); smoke test url #4092 (comment); retention rule #4092 (comment); lease id segments #4092 (comment); fill delay dropped #4092 (comment); scroll duration reported #4092 (comment); refusal reason assertion #4092 (comment); operation catalog coverage #4092 (comment); test title mismatch #4092 (comment); trimmed value mismatch #4092 (comment); 404 mapping #4092 (comment); unknown fixture route #4092 (comment); health platform check #4092 (comment); scripted status repeat #4092 (comment); verify skips refused fields #4092 (comment). The P2 thread on a 200 without a success flag #4092 (comment) needs the live run to settle. Five lower-priority threads also still apply. |
…one proved A lease that expired while the daemon was down left a Revyl session nobody could name: the id came from Revyl's answer, so only the process that started the device knew it. The runtime now derives the `start_device.session_id` from the lease id, so recovery in a restarted daemon can name and stop that session, and a backend that echoes a different id is refused instead of being trusted. Release and shutdown now report what they proved. A session is forgotten only after Revyl confirms the stop; an unconfirmed one comes back as a warning on `release`, and as `provider-cleanup-pending` on recovery and shutdown. A 404 or 410 on a session route reads as released. A start that finishes while shutdown is already running stops the device it just rented rather than dropping it. The client reads a failure as the status and route that produced it, replays only a request with no side effect, and refuses a lifecycle answer that says no. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Three places reported a command as doing more than Revyl can do. `fill --delay-ms` was dropped, so a paced fill arrived as one burst. It is now paced for real: one `/input` per character with the field cleared on the first, and a fill refused partway discloses how many characters went out. `scroll --duration-ms` was echoed back in the report although Revyl's `/drag` body carries endpoints only and no duration field exists. The report names no duration now. `platform-runtime` bound its operations from the device shape and reported facts from the session, so a binding for a session that had ended still exposed device actions. The projection is filtered through the facts now, and a closed session binds nothing. A capture the caller aborted no longer reports a snapshot it finished building afterwards, and the per-cell facts matrix is asserted for every operation the catalog declares. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…y time The connect path refused the provider flags Revyl has no field for, but verify did not, so a hand-authored profile could connect with `--provider-timezone` and fail only when the first lease was allocated. Both routes now run the same declaration, and the device model and OS version go through one canonicalizer, so what the profile stores and what `start_device` receives cannot differ by whitespace. An app URL is refused when Revyl's fetcher could never read it: a host path, plain HTTP, credentials in the URL, or a host only the caller's own network can answer. `apiUrl` was applied only when `apiKey` was supplied too, and an environment URL left the fingerprint whenever a key option was present. Each option now replaces only its own variable, and only a variable the plugin still reads from the environment is declared for fingerprinting. The package smoke answers 404 for any route but the one verification call, so a stray request is a failure rather than whatever the fixture happened to return. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The setup example named `startAgentDevice({ revyl: ... })`, which is not the API:
the plugin is passed in `plugins` and the client is built from the returned scope.
Both calls are spelled out now, next to what the CLI does for the same profile.
`device-clouds.md` compares Revyl in the same columns as the other clouds, and the
versioned CLI help names it beside the other provider profiles.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
… calls Both plugin entries built the runtime themselves, with casts to hide the shape one of them returned; `setupRevylPlugin` is the one construction, and the version 1 entry returns what the legacy adapter reads out of it. The `fetch` option on `RevylRuntimeOptions` was reachable only from tests, which drive the runtime through the fixture backend instead, so it is gone. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The registration is what both entries need, so the no-registration overload — which only the fixture reached — is gone, and the fixture takes `.runtime` from the same call. A test asserts `setup` builds the owner from the credential options rather than the environment. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
All reported issues were addressed across 31 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
This follow-up reviews 846850a. Most of the earlier blocks are fixed, but three cleanup leaks remain and the live Revyl run is still missing. The code needs changes before merge. CI is green: 24 checks, none failing, and the earlier Coverage CRAP failure is gone. There are no conflicts. Fixed since 93627f4: the readiness deadline, in-flight allocation tracking, the derived-id stop on a missing run id, strict stop/cancel acceptance and the docs example. Still open:
Not blocking, and fine to take or leave: shutdown's provider-cleanup-pending (runtime.ts:214) lists every session instead of the ones whose stop failed, and counts a 404/410 stop as a failure unlike release and recovery, so report only the failed ids through the shared stop helper; and the example comment at revyl.md:146 says releasing the lease means a failure cannot leave a device rented, which stays true once point 1 is fixed. Is the session id now fixed before start_device is sent, so the start, release, recovery and shutdown branching can collapse onto one helper, endLeaseSession(leaseId, runId?)? It would resolve when Revyl confirms the stop or answers 404/410, and otherwise throw provider-cleanup-pending naming the id. Called from every exit after the POST (any start failure, cancellation, readiness failure, identity mismatch, shutdown race) and from release, recovery and shutdown, it would delete confirmedReleases, the warnings channel, the stopOrReport/cleanupAfterFailedStart split and the swallow at runtime.ts:257. Release would throw on an unconfirmed stop as limrun does, so the daemon registry and the expired-lease releaser own the retry. Longer term, the question from the last review still stands: could one provider lease table be extracted from provider-limrun (allocate-once per lease, in-flight tracking, stop-then-forget release, shutdown drain, deadline bounding, recovery hook), so Revyl supplies only start, stop-by-lease and the interactor? At about 3,350 production lines, with roughly 600 more in this delta, the growth is hard to justify while the leak class is patched site by site. What would have to change first is an answer on the shared table. If it is taken, extract it from limrun with limrun migrated first and land Revyl on top. If not, the in-PR collapse above needs no prerequisite. Open inline threads that still apply. P1: start_device ignores cancellation and the deadline #4092 (comment), and the mismatch check needs a run id #4092 (comment), sessions dropped before stop #4092 (comment), and the release retry path #4092 (comment). P2: reason assertions #4092 (comment), abort test #4092 (comment), shutdown tests #4092 (comment), close skipped #4092 (comment), 169/8 range #4092 (comment), worker connection route #4092 (comment), undefined session text #4092 (comment), fill cancellation #4092 (comment), session-gone mapping #4092 (comment). Two lower-priority threads also still apply. These threads are fixed and already resolved: no run id now stops the session #4092 (comment); derived id stop #4092 (comment); readiness deadline #4092 (comment); in-flight allocations #4092 (comment); 503/409 not ready #4092 (comment); docs example #4092 (comment); poll deadline #4092 (comment); POST no longer aborted #4092 (comment); cleanup-pending ids #4092 (comment); stop success:false #4092 (comment); docs column #4092 (comment); route list asserted #4092 (comment); PNG fixture #4092 (comment); snapshot abort check #4092 (comment); backend URL hash #4092 (comment); admitted operations #4092 (comment); admitted operations #4092 (comment); private hosts #4092 (comment); help text #4092 (comment); env overlay #4092 (comment); smoke 404 #4092 (comment); help rotation rule #4092 (comment); three segments #4092 (comment); paced input #4092 (comment); durationMs removed #4092 (comment); refusal reasons #4092 (comment); exhaustive cells #4092 (comment); four targets #4092 (comment); shared text flag #4092 (comment); session-gone route #4092 (comment); error bodies refused #4092 (comment); unknown paths 404 #4092 (comment); platform from start #4092 (comment); status per poll #4092 (comment); verify order #4092 (comment); client origin test #4092 (comment); captureScreenshot removed #4092 (comment); perf cell #4092 (comment); screenshot route #4092 (comment); help profiles #4092 (comment). Before merge, release must keep the lease on an unconfirmed stop, the start and shutdown paths must stop or report the derived session, and the live iOS and Android run from point 4 must be attached. I did not run the package tests or a live Revyl backend. I judged test validity by reading them, and I did not trace whether a live lease at kill -9 reaches recovery after restart, which the live run in point 4 would settle. |
`appErrorCode`, `revylFailureReason` and `uncertainStatus` classified the same status ranges three times, and each new call site needed all three. One table now answers a status with its code, its reason, whether the verdict came back, and whether the transport may replay the request, so a new status is one row. The same table also decides the retry loop, which is what lets the two readiness reads opt out of it: the runtime owns the poll beat and the deadline, so a transport replay in front of `health` hides Revyl's "worker not attached" for two seconds per poll and stalls the wait being polled for. `getWorkerConnection` addresses a run by id, so it is a session route: Revyl's answer that there is no such run is the same SESSION_NOT_FOUND `/stop` and `cancel` report, not a request that was never routed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ndle Four start paths could leave a device rented or report the wrong session: - `start_device` ignored the caller's cancellation and whole-allocation deadline, so a slow rent held `allocate` long after the lease request expired. The wait is now bounded by the shorter of that deadline and the client's own start timeout, and what the caller gave up on is stopped by the session id the request carried, so the device it may have rented is not left running and the caller still gets its cancellation. - A start that echoed a different `session_id` stopped and reported the id this runtime derived rather than the one Revyl named, which is the only handle that addresses the device. Cleanup and the failure now both name Revyl's id. - A start that failed to hand back a run stopped the derived id too, so a backend that kept its own identity left that session rented. - Every start cleanup path read Revyl's typed 404/410 as a failed release, even though the session being gone is the outcome cleanup wanted. All of them now share one gone-as-released rule with release and shutdown. `shutdown` no longer empties the session table before stopping: a session leaves it only once Revyl confirmed the stop, so the release that follows a failed shutdown retries the same session and reports the warning instead of recording a release that never happened. The test that claimed that now releases the lease and asserts both the warning and the second stop. The readiness failure also said 240000 ms even when the caller had allowed far less, so the budget it reports is the one that actually ran out. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…anceled `fill --delay-ms` slept between characters without the command's AbortSignal, so canceling a paced fill could wait out the delay and type another character on a device its caller had already given up on. The interactor now carries the runner signal the command came in with: it ends each pause, is checked before the next character goes out, and every device-proxy action travels on it. The report of how much text landed still comes from the same counter, so a canceled fill says where it stopped. `captureRevylSnapshot` takes the same signal for the read it starts, and the check that follows the read is now covered by a test that lands the hierarchy after the abort, which is the race the earlier test could not reach: aborting the in-flight fetch rejects before the tree ever reaches the parser. Co-Authored-By: Claude Opus 5.5 <[email protected]>
`getInteractor` dropped the runner context it was given, so an interactor built for one command knew nothing about that command's cancellation. It now passes the runner's signal on, which is what lets a paced fill and the reads behind it stop when the caller hangs up. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The paced fill reads one character, waits, reads the next. A test that only covered the pause could not tell a canceled fill from one that finished, so this one aborts while a pause is open and counts the input actions that follow: a character typed after the caller hung up fails the test. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Revyl downloads the build from its own network, so an app URL that only the caller's network can serve is refused before a device is rented. The check rejected all of `169.x.x.x`, which turned a public host such as `169.1.2.3` away as if it were link-local. Only `169.254/16` is link-local, so only that is refused, and the test now carries a public 169 address beside the link-local one. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The test says a device outside the Revyl id space is refused as an open and close target, but read the reason on only two of the five cells. A refusal that moved to another category would have kept the test green, so all five are checked now. Co-Authored-By: Claude Opus 5.5 <[email protected]>
… plugin help where it was The embed example released the lease and then closed the host in one `finally`, so a release that threw left the embedded daemon alive with the session still rented. The close now runs in its own `finally`, on every exit path. In the remote help, the plugin-installation paragraph is back where it was: the rendered text keeps its first-screen rules inside the first 30 lines, and the rewrap pushed the MCP rule past them. The Revyl lines themselves are unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
All reported issues were addressed across 18 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
The bootstrap line listed `artifacts` for every provider in it, including the ones that declare no artifact support. Now that Revyl is in that list, the command list stops short of it and the sentence says artifacts are provider-dependent, which is what the earlier review asked for and what the plugin's own facts report. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
I reviewed b3d0002 against the earlier review. The start-timeout bound, the echoed-id stop, the shutdown bookkeeping and several smaller points are fixed, but three lease-cleanup defects and the missing live run remain. I read the code and tests only. I did not run the package tests, CI or a live Revyl backend. An unconfirmed New in this change: when the caller's signal or deadline ends the race, or the request's own Still unaddressed: a start that becomes ready after shutdown began runs The PR body still reports no live run, so the Revyl contract is checked only against a fake built from the same assumptions (session-identity.ts#L16). If Revyl ignores the caller-chosen Not blocking, and fine to take or leave: The previous question about one The cubic-dev-ai threads on untyped abort errors in the interactor, the screenshot call missing the signal and unreturned warnings on stop still apply, as does one lower-priority thread on The checks are still running on b3d0002: Smoke Tests (two jobs) and Coverage are in progress, and none has failed. This change touches their routes, since Coverage runs the provider-revyl unit tests and the CRAP gate over |
…s and the screenshot Two places stopped at the seam the command signal had: - A paced fill canceled during one of its pauses rejected with the timer's own `AbortError`, so the caller saw a bare cancellation instead of Revyl's typed reason, and the count of characters already on the device was lost with it. The wait's failure is now translated before the dispatched-step evidence is added. - `screenshot` called the worker without the signal, so a canceled capture left the Revyl request running and wrote the PNG after the caller had given up. The connection factory's documentation is moved back onto `createRevylConnection`, which the declaration of `RevylConnection` had pushed off the function. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…rented a device `startMayHaveRented` carried its own list of reason strings, so the same statuses were classified a fourth time and any new reason silently became "may have rented". It now asks the status table the question it actually has: did Revyl answer with a settled refusal, or is the verdict missing? `revylFailureRefusedTheRequest` answers that from the failure's own status, and the unreachable and canceled failures, which carry no status, answer it as unknown. Coverage CRAP named this function (cyclomatic 6, no coverage). Both branches are driven now: a start Revyl answers 401 stops nothing, and one it answers 500 is stopped by the session the request carried. The classifier itself is tested against a settled 409, an unconfirmed 503 and a backend that never answered. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
All reported issues were addressed across 8 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
Apex SentinelVerdict: Since the last review: 7 new · 0 still open · 8 no longer raised 7 finding(s): 1 major, 2 minor, 4 nit. Verdict: request_changes. reached max rounds (1). Required fixes
🟠 Major (1)
🟡 Minor (2)
🔵 Nit (4)
Not in the reviewers' prompt (1 file)
Reply under an inline comment with |
…nched Revyl answers /back only on Android, so the iOS cell refuses it with the app's own back control as the substitute. A relaunch now ends the running app directly, so the close guard no longer trusts the command's resolved app and refuses every named close the session cannot be ending. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…joins A release, a recovery and a shutdown that overlap now join the lease's one in-flight /stop instead of each sending their own; a failed stop clears it so the next caller retries. An allocation that joins a lease started for a different app URL, device model or OS version is refused rather than handed that device. The fixture tracks Revyl sessions per session id. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…e docs A timed-out or canceled request is no longer replayed, and the replay reads the request's own route. The iOS docs name the accessibility tree and say back is Android-only, and the cloud page keeps Limrun's allocating commands apart from Revyl's. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Revyl captures an iOS simulator at its native scale (3x), while the host reports every iOS simulator screenshot at the requested density, 1x by default, and printed a 1320x2868 capture as @1x. The capture is rescaled from the density health's point size implies, the same normalization a local simulator screenshot gets. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The host keeps only a provider failure's code, message and hint, so a shutdown that could not stop a Revyl device now names each session id in its message and hint, through one cleanup-pending builder that also carries the run id. A first allocation that gives up names the derived session id, since the daemon releases that lease without asking the provider and a failed late stop would otherwise have no report at all. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
…istry test Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Thanks for the review of 3269324. Everything below is at 465f42e. The live iOS and Android run is in the next comment. Shutdown names every unconfirmed session. Fixed in 8a9c55c. Every cleanup-pending report now comes from one builder, A first allocation that gives up names the derived session. Also in 8a9c55c. The live run. See the next comment. Two results changed code:
The other open threads.
All threads are resolved. Each reply names the commit that fixed it, or the reason it was declined. Also new since your review:
|
|
Live run against the real Revyl backend ( Setup. Backend behavior the cleanup rule depends on.
Happy path, Android.
Happy path, iOS (after the fixes below).
Failure paths.
What the run changed.
One open question for Revyl: iOS |
There was a problem hiding this comment.
All reported issues were addressed across 49 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
The shared AX reader treats a frame with a non-finite component as no rect, reports such a root as no viewport, and keeps the node's subrole. Revyl refuses an iOS hierarchy holding a non-node member, and an iOS screenshot whose source density it cannot know. The fixture tracks the session Revyl answered with and resolves run cancels to it, and the capture-kit producer matrices cover the Revyl tree. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
All reported issues were addressed across 10 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
Apex Sentinel: 5 new findings on 8c285ea. The verdict and the full list are in the summary comment.
…root frame The shared provider capability row has one owner, the moved viewport reader keeps its comment, and a Limrun test pins the subrole the shared reader now publishes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
I reviewed 8c285ea and found no code problems that must be fixed before merge. The findings from the earlier review are fixed in this commit. I did not reproduce the live Revyl run: it is attested in the author's comment at b535a57, which predates the error-text change (8a9c55c) and the two stricter iOS readers in 8c285ea. I also did not run package tests, check:affected, or the daemon lease_allocate cancel route, so the give-up details are proven by the provider-level thrown error, not through the daemon response. Not blocking, take or leave: 8c285ea added two iOS refusals on the device path, Checks are still running: Smoke Tests (run 41113880220) and the second review check have no result for 8c285ea yet. Smoke drives the local Apple and Android runners, and this diff only adds On the open review threads: the P2 on the test fixture's |
There was a problem hiding this comment.
Apex Sentinel: 9 new findings on fb96485. The verdict and the full list are in the summary comment.
…onstants A root frame that is present but not finite is invalid viewport evidence, not absent. The shared provider capability row is frozen, Revyl's two attribution headers share one constant, an IPv4-mapped loopback counts as loopback for a local REVYL_API_URL, and the settings facts comment says which cell refuses. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
All reported issues were addressed across 6 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
…PI_URL Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
Apex Sentinel: 8 new findings on d8377f5. The verdict and the full list are in the summary comment.
…s not dispatched The push refusal has one owner, RevylPlatform has one declaration, and the shared reader says an incomplete root frame is invalid. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
The code in 861ed36 looks good, and the findings from the earlier review (#4092 (comment)) are fixed. Not blocking, and fine to take or leave: the fixture's Two Cubic P2 threads are fixed at this head and already resolved: the lifecycle fixture gate (#4092 (comment), with the missing-
The Smoke Tests run on 861ed36 is still in progress with no failure yet. It drives the local Apple and macOS runners, and this delta only touches provider producers, so a failure would likely be unrelated unless it shows a provider snapshot provenance symptom. Before merge, that run must finish green, and #4108 must land (or you accept that kill -9 recovery ships with it) so a rented device cannot outlive a killed daemon's lease. I did not run package tests, check:affected or Smoke; this review comes from reading the head code and tests. The live Revyl run is from b535a57, plus the #4108 kill -9 run. It should still cover the lease routes, because this delta does not touch lease or session-end code. The new iOS viewport fallback has not run live, so a run where the tree has no usable root frame would prove it. |
capture-kit's resolveIosAxTreeViewport now owns the whole rule both providers use (the tree root when usable, else the device's screen box), so Limrun and Revyl no longer each spell it. Revyl's loopback check uses the same net.BlockList ranges as the daemon client, and the fixture ends a session exactly when the client accepts a /stop, with a test for a refused 200. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Thanks. All three optional notes are taken in 86c4c7f:
Live run at the current head, from a packed install. 86c4c7f plus #4108's commits, installed through a local registry:
The stricter iOS readers added since b535a57 (the node validation and the screen-size refusal) did not fire on the real backend. The viewport fallback could not be forced live, because Revyl's iOS tree always reported a usable root frame. Its rule is covered by capture-kit tests. For |
There was a problem hiding this comment.
Apex Sentinel: 7 new findings on 86c4c7f. The verdict and the full list are in the summary comment.
…the dead run cancel A screenshot's source density came from the width alone, which a rotated app interface swaps. The run-cancel fallback in stopRevylSession was unreachable, because every rented session carries the issued session id, so the cancel call, its type and its fixture route go. The shared reader also treats a half-filled screen box as invalid and reads role_description as scalar text. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Summary
Adds Revyl cloud iOS simulators and Android emulators as the separately published plugin
@agent-device/revyl(packages/provider-revyl), built on the v2 provider-plugin contract.The plugin drives Revyl through its device-proxy HTTP API, without Appium. It rents a device on the first device command. Each session id is derived from its lease, so release, recovery and shutdown can always name the device to stop. An unconfirmed stop keeps the lease and reports
provider-cleanup-pendingwith the session ids.Supported:
snapshot,screenshot,click,press,fill,scroll,open,close,home, andbackon Android. Every other command refuses with a typed reason.Outside the plugin, the change does two things:
@agent-device/capture-kit/ios-ax-tree, because Revyl answers iOS in the same shape.revyl-ios-treesnapshot producer. Android snapshots stayappium-source, because Revyl returns the same uiautomator page source.kill -9recovery depends on #4108.Validation
pnpm check:affected --runpassed at every pushed head. Unit tests run against a fake backend; root tests cover connect and the registry close.start_device,kill -9with fix(daemon): recover provider leases a killed daemon left rented #4108, and a failing/stopretried at lease expiry: feat(revyl): add the Revyl device-cloud provider plugin #4092 (comment) and, at 86c4c7f, feat(revyl): add the Revyl device-cloud provider plugin #4092 (comment)🤖 Generated with Claude Code