@revyl/verify 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -5
- package/README.md +103 -69
- package/dist/api/client.d.ts +6 -4
- package/dist/api/client.js +64 -14
- package/dist/api/types.d.ts +1 -0
- package/dist/cli/install.d.ts +2 -0
- package/dist/cli/install.js +64 -0
- package/dist/cli/login.d.ts +6 -0
- package/dist/cli/login.js +200 -0
- package/dist/cli/main.js +45 -11
- package/dist/computer-session.d.ts +14 -4
- package/dist/computer-session.js +106 -23
- package/dist/config.d.ts +7 -0
- package/dist/config.js +16 -2
- package/dist/errors.d.ts +6 -1
- package/dist/errors.js +4 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1 -1
- package/dist/open.d.ts +10 -2
- package/dist/open.js +35 -6
- package/dist/session.d.ts +21 -2
- package/dist/session.js +134 -13
- package/docs/README.md +0 -1
- package/docs/agents.md +2 -2
- package/docs/api.md +65 -3
- package/docs/ci.md +1 -1
- package/docs/computers.md +14 -13
- package/docs/configuration.md +8 -7
- package/docs/end-to-end.md +3 -3
- package/docs/errors.md +27 -2
- package/docs/getting-started.md +33 -15
- package/docs/llms.txt +4 -5
- package/docs/web.md +3 -1
- package/package.json +1 -1
- package/docs/linux-computers-contract.md +0 -53
package/docs/computers.md
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
# Mac and Linux computers (early access)
|
|
2
2
|
|
|
3
|
-
Verify opens a Revyl cloud macOS or Linux computer for commands, files, processes, and screenshots. It does not open an assigned physical computer. Both operating systems are
|
|
4
|
-
|
|
5
|
-
Get the backend and matching app endpoints from Revyl, then set `REVYL_BACKEND_URL` and `REVYL_APP_URL` for your approved early-access environment before running:
|
|
3
|
+
Verify opens a Revyl cloud macOS or Linux computer for commands, files, processes, and screenshots. It does not open an assigned physical computer. Both operating systems are **early access**. Ask [support@revyl.ai](mailto:support@revyl.ai) about access.
|
|
6
4
|
|
|
7
5
|
```bash
|
|
8
|
-
export REVYL_API_KEY=...
|
|
6
|
+
export REVYL_API_KEY=...
|
|
9
7
|
npx @revyl/verify init --platform mac
|
|
10
|
-
npm install --save-dev @revyl/verify
|
|
11
8
|
node verify/example.ts
|
|
12
9
|
```
|
|
13
10
|
|
|
14
|
-
`init`
|
|
15
|
-
|
|
16
|
-
`REVYL_BACKEND_URL` is an optional environment override for Verify generally, but currently required for computer early access on staging. Production origins remain the defaults; never mix credentials between environments.
|
|
11
|
+
`init` installs the package and checks credentials. Running the script starts a paid computer. No app id, build, device selector, image selector, or local Mac is needed. The generated script checks commands and a file round trip without agent steps.
|
|
17
12
|
|
|
18
13
|
`init` intentionally generates only Mac computer projects. For Linux, install the package and use `open({ platform: 'linux' })` inline, or add `linux: { platform: 'linux' }` to the `targets` in `verify.config.ts`. The methods below are shared by both operating systems; installed tools, paths, resources, and desktop dimensions are not fixed SDK guarantees.
|
|
19
14
|
|
|
@@ -60,7 +55,7 @@ The HTTPS URL is signed and short-lived. Keep it private, including its query st
|
|
|
60
55
|
|
|
61
56
|
## Availability and errors
|
|
62
57
|
|
|
63
|
-
Mac and Linux computers are early access
|
|
58
|
+
Mac and Linux computers are early access. A `503 runtime_unavailable` or typed `computer_not_enabled` becomes `NOT_AVAILABLE_ON_PLATFORM` with this availability guidance. A `429 computer_limit` becomes `COMPUTER_LIMIT`: queued work (including iOS) or the concurrency limit can cause it, and the response does not identify which. Verify does not retry the create or send a stop after these definite admission refusals. `operation_limit` remains `SESSION_BUSY`. Availability is determined by the server.
|
|
64
59
|
|
|
65
60
|
The default `startTimeout` remains 600000 ms; override it explicitly if needed. An unclaimed start can transition to `failed` with `failure_reason: 'no_host'` after 120 seconds from create. Verify stops readiness polling and throws `SESSION_START_FAILED` with that context, then attempts bounded cleanup. This is not a 120-second timeout for every start: claimed guests may take longer. `device_limit` also yields `SESSION_START_FAILED`, with queued-work/concurrency context. A start timeout or unconfirmed close does not prove resources were released. Inspect the session and contact support rather than blindly repeating a start or stop.
|
|
66
61
|
|
|
@@ -68,16 +63,22 @@ The default `startTimeout` remains 600000 ms; override it explicitly if needed.
|
|
|
68
63
|
|
|
69
64
|
For the first 30 seconds after a computer becomes active, `screenshot()` retries exact structured `screen_unavailable` responses (HTTP 409 or 503) and `screen_starting` (HTTP 409). Backoff starts at 500 ms and doubles up to 2 seconds; the fixed window does not restart on each call. Cancellation, close, expiry, and the observation deadline still bound the wait. Exhausting that window yields `SESSION_BUSY` with a desktop-not-ready message, rather than requiring a caller sleep. Authentication failures, unrelated errors, malformed responses, and transport failures are not replayed. Commands and other mutations are never retried by this screenshot behavior.
|
|
70
65
|
|
|
71
|
-
Linux named and inline targets use the same computer surface as Mac. `init --platform linux` is intentionally unavailable; use an inline target or write its config entry.
|
|
66
|
+
Linux named and inline targets use the same computer surface as Mac. `init --platform linux` is intentionally unavailable; use an inline target or write its config entry.
|
|
72
67
|
|
|
73
68
|
Missing files and access denials throw `NOT_FOUND` and `ACCESS_DENIED`. An operation timeout with confirmed termination throws `TIMEOUT`; unconfirmed termination or execution throws `ACTION_UNCERTAIN`. Neither implies rollback. Execution outcome, evidence recording, and physical release are independent: an observed successful command can return its result while logging pending/failed report evidence. Do not repeat a mutation merely because its response was lost. Check the computer in Revyl before deciding what to do next. See [errors.md](errors.md).
|
|
74
69
|
|
|
75
70
|
## Lifecycle and transport
|
|
76
71
|
|
|
77
|
-
|
|
72
|
+
Use `attach(computerId)` to take cleanup ownership of an existing active computer without creating one. `computer.open(target)` starts Web/iOS children on Mac and Android on Linux; Web on Linux depends on runtime availability and currently has a runtime limitation. A child requires an existing app/build pair and inherits the parent's client and expiry. Parent close attempts child cleanup for at most five seconds before requesting computer release; the server also stops remaining children. See [the hosted API](api.md#computeropentarget) for arguments, localhost navigation, and cleanup semantics. These are app sessions, not natural-language control of the computer desktop itself.
|
|
73
|
+
|
|
74
|
+
For a computer owned by another caller, such as a CI runner, use `attach(computerId, { stopOnClose: false })`. It is not registered for automatic cleanup. Explicit close still cancels pending child starts and closes hosted children within the five-second cleanup phase, but never sends a stop for the computer. The computer's owner is responsible for releasing it; a child-cleanup failure does not authorize stopping the parent.
|
|
75
|
+
|
|
76
|
+
Verify mints a session UUID, creates `/api/v1/computer-runs` with `os: 'macos'` for `platform: 'mac'` or `os: 'linux'` for `platform: 'linux'`, then polls `GET /computer-runs/{id}/report` until `state: 'active'`, which means it is ready. `starting` alone is not readiness. The public Mac target spelling is `mac`, not `macos`.
|
|
77
|
+
|
|
78
|
+
Each command is submitted once to `/computer-runs/{id}/operations` with its own UUID `request_id` and `Prefer: respond-async`. The operation id is UUIDv5 with the computer UUID as namespace and the request UUID string as name. A `202` response has JSON `null`; Verify reads the operation by id until it settles instead of submitting it again.
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
**Breaking wire change:** Verify 0.3.0 requires the encoded-only backend, which is already live on revyl.ai. Computer arguments use `argv_b64`, one padded URL-safe base64 string per UTF-8 argument, and file paths use `path_b64`; the request omits raw `argv` and `path`. Public APIs and decoded input limits are unchanged. Existing `stdin` and file `data` fields remain standard base64, and process commands are unchanged. This encoding is not encryption. Screenshot uses standard base64 PNG.
|
|
80
81
|
|
|
81
82
|
Verify bounds operation observation to the earlier of 310 seconds or the returned expiry, and explicit stop requests to 310 seconds independently of expiry. This is separate from the command's `timeout`: the backend may hold the async submission for 60 seconds before returning `202`. Automatic process-exit cleanup has a shorter 15-second budget and is best effort; use explicit `await close()` in `finally` to observe confirmed release.
|
|
82
83
|
|
|
83
|
-
`close()` posts `/computer-runs/{id}/stop
|
|
84
|
+
For an owning attachment, `close()` posts `/computer-runs/{id}/stop`, and the same automatic process cleanup as other sessions applies. A non-owning attachment never sends that stop. Always close in `finally` or use `await using` so hosted children are cleaned up. A terminal state alone is not confirmed physical release. Keep computer output and screenshots private: they can contain application data and credentials. Verify does not log file contents, argv, stdin, or command output automatically.
|
package/docs/configuration.md
CHANGED
|
@@ -7,7 +7,7 @@ import { defineConfig } from '@revyl/verify';
|
|
|
7
7
|
|
|
8
8
|
export default defineConfig({
|
|
9
9
|
targets: {
|
|
10
|
-
web: { platform: 'web', app: { appId: '…', url: 'https://
|
|
10
|
+
web: { platform: 'web', app: { appId: '…', url: 'https://example.com' }, viewport: { width: 1280, height: 800 } },
|
|
11
11
|
ios: { platform: 'ios', app: { appId: '…' }, device: { model: 'iPhone 16', osVersion: '18.5' } },
|
|
12
12
|
pixel: { platform: 'android', app: { buildId: '…' }, device: { model: 'Pixel 8' } },
|
|
13
13
|
mac: { platform: 'mac' },
|
|
@@ -20,7 +20,7 @@ Unknown keys are rejected, so a typo fails loudly instead of being ignored.
|
|
|
20
20
|
|
|
21
21
|
## Top-level options
|
|
22
22
|
|
|
23
|
-
Mac and Linux targets
|
|
23
|
+
Mac and Linux targets are early access. Ask support@revyl.ai about access. See [computer availability](computers.md#availability-and-errors).
|
|
24
24
|
|
|
25
25
|
| Option | Default | Meaning |
|
|
26
26
|
| --- | --- | --- |
|
|
@@ -62,7 +62,7 @@ Give exactly one of `appId`, `buildId`, `artifactUrl`, or `bundleId`.
|
|
|
62
62
|
| --- | --- |
|
|
63
63
|
| `platform: 'mac'` | A cloud macOS computer, without `app` or `device` configuration |
|
|
64
64
|
| `platform: 'linux'` | A cloud Linux computer with the same SDK methods as Mac, without `app` or `device` configuration |
|
|
65
|
-
| `startTimeout` | Milliseconds to wait for
|
|
65
|
+
| `startTimeout` | Milliseconds to wait for the computer to become active; default 600000, range 10000..1800000 |
|
|
66
66
|
|
|
67
67
|
Computers do not accept `idleTimeoutSeconds`, image, provider, cwd, or lifetime selectors. The server bounds a run to one hour; per-operation timeout defaults to 30000 ms and accepts 1..300000 ms. See [computers.md](computers.md).
|
|
68
68
|
|
|
@@ -71,15 +71,15 @@ Computers do not accept `idleTimeoutSeconds`, image, provider, cwd, or lifetime
|
|
|
71
71
|
| Variable | Meaning |
|
|
72
72
|
| --- | --- |
|
|
73
73
|
| `REVYL_API_KEY` | API key. Wins over a stored CLI login unless that login is usable and marked `local_auth_override`. Without an environment key, a usable stored login is used; expired access tokens fall back to a stored API key. |
|
|
74
|
-
| `REVYL_BACKEND_URL` | Optional API origin override; production is the default. Get the endpoint for your approved early-access environment from Revyl and use matching credentials. |
|
|
75
|
-
| `REVYL_APP_URL` | Optional session-link origin override; production is the default. Get the matching app endpoint from Revyl. |
|
|
76
74
|
|
|
77
75
|
## Command line
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
Hosted children use `computer.open(target)` rather than named config targets. Unlike ordinary mobile targets, they require an existing app/build pair and use the computer's fixed device profile. See [the hosted API](api.md#computeropentarget).
|
|
78
|
+
|
|
79
|
+
Use the explicitly scoped package command below. Installing `@revyl/verify` provides the `verify` and `revyl-verify` bins. The separate `revyl-verify` npm alias also provides `npx revyl-verify` with the same behavior; bare `npx verify` can fetch an unrelated package. Scripts run with `node`, not through the CLI.
|
|
80
80
|
|
|
81
81
|
```text
|
|
82
|
-
npx @revyl/verify init [--platform web|ios|android|mac] [--app-id <id>] [--url <https-url>] [--force]
|
|
82
|
+
npx @revyl/verify init [--platform web|ios|android|mac] [--app-id <id>] [--url <https-url>] [--force] [--yes] [--no-install]
|
|
83
83
|
npx @revyl/verify whoami
|
|
84
84
|
npx @revyl/verify --help
|
|
85
85
|
npx @revyl/verify --version
|
|
@@ -87,6 +87,7 @@ npx @revyl/verify --version
|
|
|
87
87
|
|
|
88
88
|
- `init` writes `verify.config.ts` and `verify/example.ts`, and adds `.verify/` to `.gitignore`. Without `--platform` it asks its questions interactively. It never overwrites files unless you pass `--force`.
|
|
89
89
|
- `npx @revyl/verify init --platform mac` needs no app id and generates a command/file script. `--app-id` is rejected for Mac, `--url` applies only to web, and Linux init is intentionally unavailable. Use `open({ platform: 'linux' })` or a Linux config target instead.
|
|
90
|
+
- `init` installs Verify from the project's lockfile when needed and signs in through the Revyl CLI's browser approval flow when no credentials are available. Use `--yes` or `--no-install` to control installation. Non-interactive runs do not prompt or open a browser and require `REVYL_API_KEY`.
|
|
90
91
|
- `whoami` prints the Revyl account and organization your credentials belong to.
|
|
91
92
|
|
|
92
93
|
Exit codes: `0` success, `1` a Revyl or file error, `2` a usage or authentication problem.
|
package/docs/end-to-end.md
CHANGED
|
@@ -6,7 +6,7 @@ Only reviewed public scripts, sanitized transcripts, result projections, and two
|
|
|
6
6
|
|
|
7
7
|
## Baseline live results
|
|
8
8
|
|
|
9
|
-
Web, iOS,
|
|
9
|
+
Web, iOS, Android, Mac, and Linux ran on Revyl. Computers are early access; ask support@revyl.ai about access. Durations below are observed script wall times, not performance targets.
|
|
10
10
|
|
|
11
11
|
| SDK | Platform and workload | Result | Total time | Cleanup |
|
|
12
12
|
| --- | --- | --- | --- | --- |
|
|
@@ -70,7 +70,7 @@ The iOS check ran `init --platform ios` in a fresh tarball-install project and c
|
|
|
70
70
|
|
|
71
71
|
The Go Android instruction was `Open About phone or About device, then scroll as needed and open Android version so the operating system version number is visible on screen.` The validation was `The screen shows the operating system version.` Both returned `passed: true`; the report independently recorded zero effective failed steps and one passing validation.
|
|
72
72
|
|
|
73
|
-
Both Linux attempts were admission refusals, **not an SDK screenshot failure or a successful retry proof**. The script had no manual sleep/retry, but never reached its screenshot call. The new retry behavior remains tests-only, and Linux remains
|
|
73
|
+
Both Linux attempts were admission refusals, **not an SDK screenshot failure or a successful retry proof**. The script had no manual sleep/retry, but never reached its screenshot call. The new retry behavior remains tests-only, and Linux remains early access. No further live attempt was authorized. The original 0.1.0 iOS failures, offscreen Android failure, and immediate Linux screenshot failure above remain part of the evidence.
|
|
74
74
|
|
|
75
75
|
## Reading the verdict
|
|
76
76
|
|
|
@@ -98,7 +98,7 @@ npm run build
|
|
|
98
98
|
|
|
99
99
|
For Go, pin the same baseline with `go get github.com/RevylAI/verify/go@6029513369f13e73914b550d0cd26ece615b4e13` in your own module. Use the [TypeScript API](getting-started.md) or [Go API](https://github.com/RevylAI/verify/tree/main/go) to open the target, run an instruction, validate the visible outcome, capture a screenshot, and close in `finally` or a bounded deferred cleanup context. The web workload uses `https://demo.playwright.dev/todomvc` and a Revyl web app ID supplied privately through `REVYL_WEB_APP_ID`.
|
|
100
100
|
|
|
101
|
-
Do not use the baseline's blank-screen initializer or offscreen Android assertion as a recommended recipe. To test the fixes, use the reviewed new source revision rather than the baseline commit or the older npm package. Ask
|
|
101
|
+
Do not use the baseline's blank-screen initializer or offscreen Android assertion as a recommended recipe. To test the fixes, use the reviewed new source revision rather than the baseline commit or the older npm package. Ask support@revyl.ai about computer access; never place credentials in argv or publish signed recording URLs.
|
|
102
102
|
|
|
103
103
|
## Limits
|
|
104
104
|
|
package/docs/errors.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Errors
|
|
2
2
|
|
|
3
|
+
## Structured refusal reasons
|
|
4
|
+
|
|
5
|
+
`VerifyError.reason` is an optional typed `RefusalReason` and `httpStatus` is the HTTP status when available. They supplement, rather than replace, the existing `code`. Only recognized server codes are retained; raw error messages and unknown payloads are not exposed as reasons. Starts and navigation are never replayed automatically.
|
|
6
|
+
|
|
7
|
+
| Start refusal | Existing `code` | `reason` |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Web HTTP 409 capacity/availability | `API_ERROR` | `web_runtime_unavailable` |
|
|
10
|
+
| Computer HTTP 429 admission | `COMPUTER_LIMIT` | `computer_limit` |
|
|
11
|
+
| Computer HTTP 503 runtime availability | `NOT_AVAILABLE_ON_PLATFORM` | `runtime_unavailable` |
|
|
12
|
+
| Hosted child capacity | `COMPUTER_LIMIT` | `computer_at_capacity` |
|
|
13
|
+
| Hosted runtime/capability | `NOT_AVAILABLE_ON_PLATFORM` | `computer_runtime_unavailable` / `computer_cannot_host_platform` / `web_runtime_not_configured` |
|
|
14
|
+
| Hosted parent no longer running | `SESSION_ENDED` | `computer_not_running` |
|
|
15
|
+
| Hosted parent inaccessible | `NOT_FOUND` | `computer_not_found` |
|
|
16
|
+
| Hosted build input | `INVALID_ARGUMENT` | `web_build_required`, `web_build_not_supported`, or corresponding `ios_` / `android_` codes |
|
|
17
|
+
| Hosted identity conflict | `SESSION_BUSY` | `web_session_conflict`, `ios_session_conflict`, `android_session_conflict` |
|
|
18
|
+
|
|
19
|
+
`web_runtime_unavailable` does not distinguish full capacity from an unavailable runtime. `computer_limit` does not distinguish queued work from concurrency exhaustion. Inspect these fields to classify refusal without parsing prose; do not infer a specific cause or automatically start a replacement session.
|
|
20
|
+
|
|
21
|
+
Ordinary start errors retain recognized safe server diagnostic codes such as `web_app_required` in the message even when they are not typed refusal reasons. Arbitrary server messages and payloads are not copied into startup diagnostics.
|
|
22
|
+
|
|
23
|
+
Web navigation timeouts expose `reason: 'request_timeout'` with HTTP 504 and `code: 'ACTION_UNCERTAIN'`: the action budget expired before navigation was confirmed, but the request may still commit and the session remains open. A normalized `protocol_error` also preserves uncertainty and its HTTP status. Neither error causes Verify to replay navigation or close the session. Inspect the live page before deciding whether to navigate again.
|
|
24
|
+
|
|
3
25
|
Everything Verify throws on purpose is a `VerifyError` with a stable `code`. Messages name the problem and, for step failures, end with the session link.
|
|
4
26
|
|
|
5
27
|
```ts
|
|
@@ -20,12 +42,13 @@ try {
|
|
|
20
42
|
| `CONFIG_INVALID` | The config failed validation or did not load | The message names the exact option and the rule |
|
|
21
43
|
| `AUTH_MISSING` | No `REVYL_API_KEY` and no Revyl CLI login | Set `REVYL_API_KEY` or run `revyl auth login` |
|
|
22
44
|
| `AUTH_REJECTED` | Revyl rejected the credentials | Create a new API key, or log in again |
|
|
45
|
+
| `EDGE_BLOCKED` | An HTTP 403 has a `text/html` content type and nonempty `cf-ray`, without a valid JSON body | Check network access or contact support; Verify does not retry the request |
|
|
23
46
|
| `API_ERROR` | Revyl returned an unexpected response | Try again; if it persists, report it with the session link |
|
|
24
47
|
| `SESSION_START_FAILED` | The browser, device, or computer did not start | Computer `no_host` reports the 120-second unclaimed-start context; `device_limit` reports queued-work/concurrency context. Inspect the session and cleanup before starting again. |
|
|
25
48
|
| `SESSION_ENDED` | The session was closed, stopped, or expired | Close explicitly; computer expiry does not prove release |
|
|
26
49
|
| `SESSION_BUSY` | A step conflict, computer operation limit, or recording requested before terminal state and confirmed release | Inspect the state before another call; a terminal computer alone does not prove release |
|
|
27
50
|
| `COMPUTER_LIMIT` | Computer admission was refused due to queued work (including iOS) or the concurrency limit | Wait for capacity; Verify does not retry or stop a definitely refused start |
|
|
28
|
-
| `NOT_AVAILABLE_ON_PLATFORM` | The call is unavailable: computer agent steps, device shell/file/recording methods, computer
|
|
51
|
+
| `NOT_AVAILABLE_ON_PLATFORM` | The call is unavailable: computer agent steps, device shell/file/recording methods, computer access or runtime unavailable, or a backend without web steps | See [web.md](web.md) and [computers.md](computers.md#availability-and-errors) |
|
|
29
52
|
| `COMMAND_FAILED` | A computer command exited nonzero | Read its reason; use `exec(argv, { check: false })` to inspect the exit code and output instead |
|
|
30
53
|
| `NOT_FOUND` | A computer file or resource was not found | Check the workspace-relative path |
|
|
31
54
|
| `ACCESS_DENIED` | The computer refused access | Check permissions; do not assume host/root access |
|
|
@@ -34,6 +57,8 @@ try {
|
|
|
34
57
|
| `INSTRUCTION_FAILED` | Revyl's agent could not do what the instruction asked | Make the instruction more specific, or split it into smaller steps |
|
|
35
58
|
| `VALIDATION_FAILED` | The validation did not hold | The message has Revyl's reason; watch the recording at the session link |
|
|
36
59
|
| `STEP_FAILED` | Revyl could not run the step to an outcome: it errored, it was cancelled on Revyl, or a validation came back without a verdict. This says nothing about your app, and `soft` does not cover it. | Watch the session at the link, then run the step again |
|
|
37
|
-
| `TIMEOUT` | A step, a session start, or a request ran out of time | Inspect the session before retrying
|
|
60
|
+
| `TIMEOUT` | A step, a session start, or a request ran out of time | Inspect the session before retrying. The default 10-minute start timeout is separate from the 120-second unclaimed-start failure. See [computer availability](computers.md#availability-and-errors). |
|
|
61
|
+
|
|
62
|
+
`EDGE_BLOCKED` does not require Cloudflare branding in the HTML body. A `cf-ray` header alone is not proof of a block: any syntactically valid JSON body retains its existing error mapping, even if the content type is incorrectly `text/html`. HTTP 401 is unchanged. Edge-block errors include `httpStatus` but never copy the response body or ray ID into the error.
|
|
38
63
|
|
|
39
64
|
Computer operations use `TIMEOUT` for bounded runtime with confirmed termination, and `ACTION_UNCERTAIN` when termination, execution, or cleanup is unconfirmed. An observed successful operation can return its result while logging pending/failed evidence. Timeout never proves rollback, and failed evidence does not prove the command never ran. Never automatically retry a mutation with a fresh request id; inspect the computer first. See [computers.md](computers.md).
|
package/docs/getting-started.md
CHANGED
|
@@ -2,32 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
Verify needs Node.js 22.18 or later, which runs TypeScript files directly, and a Revyl account.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install and run
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
8
|
+
npm install @revyl/verify
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Save this as `verify/check.mts` and use an inline target when you do not need a named config:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { open } from '@revyl/verify';
|
|
15
|
+
|
|
16
|
+
const session = await open({ platform: 'ios', app: { bundleId: 'com.apple.Preferences' } });
|
|
17
|
+
try {
|
|
18
|
+
await session.instruction('Open General, then About');
|
|
19
|
+
await session.validation('The screen shows the operating system version');
|
|
20
|
+
} finally {
|
|
21
|
+
await session.close();
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use `appId` when you want to target your own uploaded app.
|
|
26
|
+
|
|
27
|
+
Run it with `node verify/check.mts`. Web targets need Web enabled for your organization; new self-serve organizations don't have it yet. `revyl app create --platform web` reports `Web is not enabled for this organization`; contact Revyl to enable it.
|
|
28
|
+
|
|
29
|
+
On the first interactive run, Verify opens the Revyl browser approval flow once and saves the shared CLI login. It prints a live session link, then ordered step results. In CI, it never prompts or opens a browser; set `REVYL_API_KEY` as a secret. Python and Go use an existing CLI login or API key; their SDKs do not open the browser themselves.
|
|
30
|
+
|
|
31
|
+
## Scaffold a config (optional)
|
|
32
|
+
|
|
33
|
+
Use `init` when you want named targets in `verify.config.ts` and a generated example script. It adds Verify with the package manager selected by its lockfile, asks what you want to open, and adds `.verify/` to `.gitignore`:
|
|
12
34
|
|
|
13
35
|
- `verify.config.ts`: the targets `open()` can start, by name
|
|
14
36
|
- `verify/example.ts`: a script that opens the target, runs steps and takes a screenshot (web/mobile) or checks commands and files (Mac), and closes
|
|
15
37
|
|
|
16
|
-
In scripts and CI, pass the answers as flags:
|
|
38
|
+
In scripts and CI, pass the answers as flags. Non-interactive runs never prompt or open a browser; provide `REVYL_API_KEY` as a secret:
|
|
17
39
|
|
|
18
40
|
```bash
|
|
19
|
-
npx @revyl/verify init --platform web --app-id <revyl-app-id> --url https://
|
|
41
|
+
npx @revyl/verify init --platform web --app-id <revyl-app-id> --url https://example.com
|
|
20
42
|
npx @revyl/verify init --platform ios --app-id <revyl-app-id>
|
|
21
43
|
npx @revyl/verify init --platform mac
|
|
22
44
|
```
|
|
23
45
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npm install --save-dev @revyl/verify
|
|
28
|
-
```
|
|
46
|
+
Use `--yes` to accept installation without a prompt, or `--no-install` when Verify is already installed.
|
|
29
47
|
|
|
30
|
-
##
|
|
48
|
+
## Manual setup
|
|
31
49
|
|
|
32
50
|
Verify uses the same credential precedence as the Revyl CLI:
|
|
33
51
|
|
|
@@ -40,15 +58,15 @@ export REVYL_API_KEY=... # or: revyl auth login
|
|
|
40
58
|
npx @revyl/verify whoami # checks the credentials without starting a session
|
|
41
59
|
```
|
|
42
60
|
|
|
43
|
-
##
|
|
61
|
+
## Point the config at your app
|
|
44
62
|
|
|
45
63
|
Web and mobile targets need an app. Open the app in Revyl and copy its id into `app.appId`, or set `REVYL_APP_ID`, which the generated config reads. Mac and Linux targets need no app id. Linux init is intentionally unavailable; use `open({ platform: 'linux' })` or add a Linux config target.
|
|
46
64
|
|
|
47
|
-
- **Web:** set `app.url` to a public HTTPS URL
|
|
65
|
+
- **Web:** set `app.url` to a public HTTPS URL. Revyl's cloud browser cannot reach `localhost`. See [web.md](web.md).
|
|
48
66
|
- **iOS and Android:** upload a build to the app in Revyl, for example with `revyl build upload`; each session installs the newest one. See [mobile.md](mobile.md).
|
|
49
|
-
- **Mac and Linux:** early access
|
|
67
|
+
- **Mac and Linux:** computers are early access; ask support@revyl.ai about access. Agent instruction/validation are unavailable. See [computers.md](computers.md#availability-and-errors).
|
|
50
68
|
|
|
51
|
-
##
|
|
69
|
+
## Run the script
|
|
52
70
|
|
|
53
71
|
```bash
|
|
54
72
|
node verify/example.ts
|
package/docs/llms.txt
CHANGED
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
## Docs
|
|
6
6
|
|
|
7
|
-
Both computer operating systems are early access
|
|
7
|
+
Both computer operating systems are early access; ask support@revyl.ai about access. Linux init remains intentionally unavailable; use an inline target or config entry. See computers.md#availability-and-errors.
|
|
8
8
|
|
|
9
9
|
- [Getting started](getting-started.md): install, authenticate, init, run a script
|
|
10
|
-
- [API](api.md): open(), agent steps, screenshot(), exec(), file/process methods, close()
|
|
10
|
+
- [API](api.md): open(), attach(), hosted children, navigate(), report(), agent steps, screenshot(), exec(), file/process methods, close()
|
|
11
11
|
- [Configuration](configuration.md): verify.config.ts targets, environment variables, the init and whoami commands
|
|
12
|
-
- [Web](web.md): Revyl web sessions, URLs and builds, sign-in,
|
|
12
|
+
- [Web](web.md): Revyl web sessions, URLs and builds, sign-in, and steps
|
|
13
13
|
- [Mobile](mobile.md): iOS and Android devices and installing apps
|
|
14
|
-
- [Computers](computers.md#availability-and-errors):
|
|
14
|
+
- [Computers](computers.md#availability-and-errors): Mac/Linux early access, expiry, capacity errors, recording metadata, and confirmed release
|
|
15
15
|
- [Verify working end to end](end-to-end.md): live verification scope, observed outcomes, and limits of the evidence
|
|
16
|
-
- [Linux contract](linux-computers-contract.md): implemented shared requests/responses, readiness, errors, and uncertainty
|
|
17
16
|
- [CI and test runners](ci.md): GitHub Actions, node:test, Vitest, Jest, Playwright Test
|
|
18
17
|
- [Errors](errors.md): every error code and what to do about it
|
|
19
18
|
- [For coding agents](agents.md): the workflow and rules for agents using Verify
|
package/docs/web.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A web target opens your app in a Revyl cloud browser.
|
|
4
4
|
|
|
5
|
+
Web targets need Web enabled for your organization; new self-serve organizations don't have it yet. `revyl app create --platform web` reports `Web is not enabled for this organization`; contact Revyl to enable it.
|
|
6
|
+
|
|
5
7
|
```ts
|
|
6
8
|
{
|
|
7
9
|
platform: 'web',
|
|
@@ -30,7 +32,7 @@ signIn: { path: '/__test/sign-in', secret: 'E2E_SIGN_IN_TOKEN', persona: 'admin'
|
|
|
30
32
|
|
|
31
33
|
`instruction` and `validation` use the same Revyl endpoints on web as on iOS and Android, and each step shows up in the session's report.
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
The default Revyl service is used for normal setup. Authenticate with a matching API key or CLI login.
|
|
34
36
|
|
|
35
37
|
A Revyl backend that does not run steps on web yet answers with `step_output_not_available`, which Verify reports as `NOT_AVAILABLE_ON_PLATFORM`. The same script works there with no change once it does. `open`, `screenshot`, `viewerUrl`, and `close` work on web everywhere.
|
|
36
38
|
|
package/package.json
CHANGED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Linux computers: implemented shared contract
|
|
2
|
-
|
|
3
|
-
Verify 0.2.0 enables Linux named and inline targets with the same computer API as Mac. Both operating systems are **early access on staging for organizations enabled for the requested OS, not yet available in production**. Server admission decides availability; SDK support is not a guarantee that capacity is available. No live Linux run was performed for this SDK change.
|
|
4
|
-
|
|
5
|
-
Use `open({ platform: 'linux', startTimeout: 600_000 })`, or add `linux: { platform: 'linux' }` under `targets` in `verify.config.ts`. There is no app, image, provider, cwd, TTL, or device selector. `init --platform linux` remains intentionally unavailable; it does not block inline or named Linux SDK targets. See [computers.md](computers.md) for staging setup and usage.
|
|
6
|
-
|
|
7
|
-
## Public surface
|
|
8
|
-
|
|
9
|
-
- `exec(argv, { timeout?, stdin?, check? }?)` returns `{ exitCode, stdout, stderr }`. There is no implicit shell. Nonzero exit throws `COMMAND_FAILED` unless `check: false`.
|
|
10
|
-
- `readFile`, `writeFile`, and `stat` use workspace-relative paths and preserve binary bytes.
|
|
11
|
-
- `processes` and `terminate` use run-owned handles, never OS PIDs.
|
|
12
|
-
- `screenshot({ path? }?)` returns PNG bytes with dimensions from the response; screenshot readiness is independent of command readiness. The SDK retries only structured startup screen-not-ready responses within its fixed 30-second window after active readiness; [computer docs](computers.md) describe the bounds and typed exhaustion error.
|
|
13
|
-
- `close()` succeeds only on terminal state and confirmed physical release.
|
|
14
|
-
- `recording()` returns private recording metadata or null after terminal state and confirmed release, and works after close. It does not wait or download.
|
|
15
|
-
- `expiresAt` exposes a validated API timestamp as a `Date`, or is undefined on older APIs. The hard lifetime is 60 minutes from create, not readiness or activity. Expired operations are rejected, pending observations are bounded by expiry, and close remains possible.
|
|
16
|
-
|
|
17
|
-
`instruction` and `validation` are rejected locally on both computer operating systems. There is no computer agent-step endpoint. The assigned-physical-computer `shell-sessions` API is not part of this contract. Installed tools, guest paths, resources, architecture, and screen dimensions are not SDK guarantees; use portable commands or inspect what the selected guest provides.
|
|
18
|
-
|
|
19
|
-
## Requests and readiness
|
|
20
|
-
|
|
21
|
-
All routes use `/api/v1/computer-runs`, the selected `REVYL_BACKEND_URL`, bearer authentication, `X-Revyl-Client: verify`, and Verify's versioned user agent. Ownership is enforced by the server; possession of a UUID grants no access. `REVYL_APP_URL` controls UI links.
|
|
22
|
-
|
|
23
|
-
| Request | Contract |
|
|
24
|
-
| --- | --- |
|
|
25
|
-
| `POST /computer-runs` | `{ computer_session_id: C1, os: 'linux' }`; Mac sends `os: 'macos'`. Mint C1 once, never replay an uncertain create. |
|
|
26
|
-
| `GET /computer-runs/C1/report` | Validate C1 and lifecycle state. Poll while starting, resolve on active, fail on other states. `failed/no_host` means an unclaimed start reached the 120-second window, not that all starts must finish within it. The default client start timeout stays 10 minutes. |
|
|
27
|
-
| `POST /computer-runs/C1/operations` | `{ computer_session_id: C1, request_id: R1, command }`, with `Prefer: respond-async`. Response is a command result or `202` with exact JSON null. |
|
|
28
|
-
| `GET /computer-runs/C1/operations/O1` | Read the retained result, or `202`/null while running. O1 is UUIDv5(namespace=C1, name=R1 string). Poll reads without replaying mutations. |
|
|
29
|
-
| `POST /computer-runs/C1/stop` | Report state and release separately. Close requires `stopped`, `failed`, or `owner_lost` plus `release: 'confirmed'`. |
|
|
30
|
-
| `GET /computer-runs/C1/recording` | After a separate report confirms terminal state and release: `{ url, duration_seconds?, started_at? }`, or `404 { error: 'recording_unavailable' }`. Optional fields may be null. No URL is carried by the normal report. |
|
|
31
|
-
|
|
32
|
-
Recording URLs must be HTTPS and are signed, short-lived, and private, including the query string. Duration must be finite and nonnegative, and timestamps must include a timezone. Malformed responses produce a generic error that does not echo the URL. The SDK never fetches that URL. A pre-release recording request throws `SESSION_BUSY`; missing recording returns null without automatic waiting.
|
|
33
|
-
|
|
34
|
-
## Commands and uncertainty
|
|
35
|
-
|
|
36
|
-
Commands retain the shared limits: 30-second default / 5-minute maximum timeout, 256 operations per run, 64 argv entries, 16,384 bytes of argv plus stdin, first 1 MiB combined stdout/stderr, 1 MiB reads, 64 KiB writes, and 64 listed handles. File paths must be workspace-relative without traversal. See [computers.md](computers.md) for complete validation rules.
|
|
37
|
-
|
|
38
|
-
Operation responses identify C1 and O1 and separate `execution` from `evidence: 'recorded' | 'pending' | 'failed'`. Successful execution can return a result even when report evidence is pending or failed. An observed nonzero exec result is distinct from transport failure. Unknown outcome, unconfirmed timeout termination, and lost mutation responses produce `ACTION_UNCERTAIN` and never authorize replay. Terminal lifecycle, physical release, and recording availability are independent.
|
|
39
|
-
|
|
40
|
-
| Condition | Verify code |
|
|
41
|
-
| --- | --- |
|
|
42
|
-
| `computer_not_enabled`, or `503 runtime_unavailable` | `NOT_AVAILABLE_ON_PLATFORM` |
|
|
43
|
-
| `429 computer_limit` | `COMPUTER_LIMIT`: queued work (including iOS) or concurrency limit; no automatic start retry or stop after definite admission refusal |
|
|
44
|
-
| `operation_limit`, other conflict refusals | `SESSION_BUSY` |
|
|
45
|
-
| `failed/no_host`, `failed/device_limit`, `start_failed` | `SESSION_START_FAILED`; safe no-host or queued-work/concurrency context when known |
|
|
46
|
-
| `run_closed`, or local expiry | `SESSION_ENDED` |
|
|
47
|
-
| `inaccessible`, `invalid_handle`, operation `not_found` | `NOT_FOUND` |
|
|
48
|
-
| Operation `access_denied` | `ACCESS_DENIED` |
|
|
49
|
-
| Operation `exec_nonzero` | `COMMAND_FAILED` unless `check: false` |
|
|
50
|
-
| Unknown execution, operation unavailable, uncertain mutation or release | `ACTION_UNCERTAIN` |
|
|
51
|
-
| Confirmed operation timeout | `TIMEOUT` |
|
|
52
|
-
|
|
53
|
-
Other HTTP errors retain the shared authentication, input, or API classifications described in [errors.md](errors.md). Do not infer a capacity cause from `computer_limit` alone or expose arbitrary failure text, command data, credentials, or recording URLs in diagnostics.
|