@runalabs/rill-cli 0.1.7-beta.0 → 0.1.8
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/README.md +9 -2
- package/dist/cli.js +28 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Rill starts a local Chromium recorder. Your browser tool drives the returned CDP
|
|
|
6
6
|
|
|
7
7
|
[Getting started](https://userill.dev/docs) · [Website CLI reference](https://userill.dev/docs/cli) · [Agent instructions](https://userill.dev/docs/cli#agents)
|
|
8
8
|
|
|
9
|
-
## Cloud agent
|
|
9
|
+
## Cloud agent runs
|
|
10
10
|
|
|
11
11
|
Invited workspaces can supply a URL and prompt. Cloud runs need Node.js 22+ and a Rill login; Chrome and ffmpeg run on Rill's server.
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@ rill run cancel <run-id>
|
|
|
19
19
|
|
|
20
20
|
The first run opens Rill authorization if needed. Save optional website test accounts in Rill Settings using an account name, exact HTTPS origin, username, password, and optional login URL. Login appears in the private video, with masked password inputs; login diagnostics are omitted. MFA, CAPTCHA, external SSO, and unsupported login forms return a blocker.
|
|
21
21
|
|
|
22
|
-
Cloud recordings are private by default. Closing the terminal disconnects without cancelling. Use `--no-wait` to return after submission, and `--id <same-run-id>` with identical arguments to retry an uncertain submission.
|
|
22
|
+
Cloud recordings are private by default. Closing the terminal disconnects without cancelling. Use `--no-wait` to return after submission, and `--id <same-run-id>` with identical arguments to retry an uncertain submission. Cloud runs use run credits: Free includes 3 per calendar month and Pro includes 20. Buy additional credits from Billing.
|
|
23
23
|
|
|
24
24
|
The following local-recording instructions remain available through `record start` and `record stop`.
|
|
25
25
|
|
|
@@ -262,3 +262,10 @@ secret-tool clear service rill api-url https://userill.dev
|
|
|
262
262
|
```
|
|
263
263
|
|
|
264
264
|
Substitute your API URL if you configured another environment. These commands clear the local credential; server-side revocation is managed in Settings.
|
|
265
|
+
|
|
266
|
+
### Cloud run output
|
|
267
|
+
|
|
268
|
+
`rill record <url> -p "<prompt>"` prints the outcome, summary, and recording URL.
|
|
269
|
+
Use `--json` for a machine-readable result (`--pretty` also enables JSON formatting).
|
|
270
|
+
Provider token usage is retained internally and omitted from customer output.
|
|
271
|
+
`rill run status <run-id>` and `rill run cancel <run-id>` support the same output options.
|
package/dist/cli.js
CHANGED
|
@@ -15702,6 +15702,25 @@ function errorMessage(error51) {
|
|
|
15702
15702
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
15703
15703
|
}
|
|
15704
15704
|
|
|
15705
|
+
// src/cloud-output.ts
|
|
15706
|
+
function customerRun(run2) {
|
|
15707
|
+
if (!run2.result) return run2;
|
|
15708
|
+
const { usage: _usage, ...result } = run2.result;
|
|
15709
|
+
return { ...run2, result };
|
|
15710
|
+
}
|
|
15711
|
+
function formatCloudRun(run2) {
|
|
15712
|
+
const result = run2.result;
|
|
15713
|
+
const outcome = typeof result?.outcome === "string" ? result.outcome : void 0;
|
|
15714
|
+
const summary = typeof result?.summary === "string" ? result.summary : void 0;
|
|
15715
|
+
const publication = result?.publication;
|
|
15716
|
+
const lines = [`Run ${run2.status}${outcome ? ` \xB7 ${outcome}` : ""}`, `Run ID: ${run2.id}`];
|
|
15717
|
+
if (summary) lines.push("", summary);
|
|
15718
|
+
if (publication?.playbackUrl) lines.push("", `Recording: ${publication.playbackUrl}`);
|
|
15719
|
+
if (run2.status === "failed" && !summary) lines.push("", "The run could not finish.");
|
|
15720
|
+
if (!["completed", "failed", "cancelled"].includes(run2.status)) lines.push("", `Check progress: rill run status ${run2.id}`);
|
|
15721
|
+
return lines.join("\n") + "\n";
|
|
15722
|
+
}
|
|
15723
|
+
|
|
15705
15724
|
// src/recording-lifecycle.ts
|
|
15706
15725
|
async function startRecordingWithCompensation(remote, dependencies) {
|
|
15707
15726
|
try {
|
|
@@ -15739,7 +15758,7 @@ function controlPlaneUrl(environmentUrl) {
|
|
|
15739
15758
|
|
|
15740
15759
|
// src/cli.ts
|
|
15741
15760
|
var program = new Command();
|
|
15742
|
-
program.name("rill").description("Record, inspect, and share agent browser runs.").version(CLI_VERSION).option("--api-url <url>", "Rill control plane", controlPlaneUrl(process.env.RILL_API_URL)).option("--pretty", "Pretty-print JSON output", false);
|
|
15761
|
+
program.name("rill").description("Record, inspect, and share agent browser runs.").version(CLI_VERSION).option("--api-url <url>", "Rill control plane", controlPlaneUrl(process.env.RILL_API_URL)).option("--pretty", "Pretty-print JSON output", false).option("--json", "Output cloud run results as JSON", false);
|
|
15743
15762
|
var activeTelemetry = null;
|
|
15744
15763
|
program.command("daemon", { hidden: true }).action(() => runDaemon());
|
|
15745
15764
|
program.command("doctor").description("Validate Rill prerequisites before recording.").action(async () => {
|
|
@@ -15748,7 +15767,7 @@ program.command("doctor").description("Validate Rill prerequisites before record
|
|
|
15748
15767
|
emit(result, options.pretty);
|
|
15749
15768
|
if (result.status === "error") process.exitCode = 1;
|
|
15750
15769
|
});
|
|
15751
|
-
async function authorize() {
|
|
15770
|
+
async function authorize(quiet = false) {
|
|
15752
15771
|
const options = program.opts();
|
|
15753
15772
|
const client = new ControlPlaneClient(options.apiUrl, null);
|
|
15754
15773
|
const authorization = await client.createDeviceAuthorization({ deviceName: `${hostname3()} \xB7 ${process.platform}` });
|
|
@@ -15765,7 +15784,7 @@ async function authorize() {
|
|
|
15765
15784
|
if (result.status === "pending") continue;
|
|
15766
15785
|
if (result.status !== "approved" || !result.token) throw new Error(`Device authorization ${result.status}.`);
|
|
15767
15786
|
await saveCredential(options.apiUrl, result.token);
|
|
15768
|
-
emit({ schemaVersion: 1, status: "authenticated", expiresAt: result.expiresAt, apiUrl: options.apiUrl }, options.pretty);
|
|
15787
|
+
if (!quiet) emit({ schemaVersion: 1, status: "authenticated", expiresAt: result.expiresAt, apiUrl: options.apiUrl }, options.pretty);
|
|
15769
15788
|
return result.token;
|
|
15770
15789
|
}
|
|
15771
15790
|
throw new Error("Device authorization expired.");
|
|
@@ -15776,7 +15795,7 @@ program.command("login").description("Authorize Rill once.").action(async () =>
|
|
|
15776
15795
|
var record2 = program.command("record").description("Run a cloud browser from a URL and prompt, or manage a local recording.").argument("[url]").option("-p, --prompt <prompt>").option("--expectation <text>").option("--account <name>", "Saved website test account").option("--id <uuid>", "Retry a submission with the same run ID").option("--no-wait").action(async (url2, commandOptions) => {
|
|
15777
15796
|
if (!url2 || !commandOptions.prompt) throw new Error("Use rill record <url> -p <prompt>.");
|
|
15778
15797
|
const options = program.opts();
|
|
15779
|
-
const token = await loadCredential(options.apiUrl) ?? await authorize();
|
|
15798
|
+
const token = await loadCredential(options.apiUrl) ?? await authorize(true);
|
|
15780
15799
|
const client = new ControlPlaneClient(options.apiUrl, token);
|
|
15781
15800
|
const id = commandOptions.id ?? crypto.randomUUID();
|
|
15782
15801
|
process.stderr.write(`Run ID: ${id}
|
|
@@ -15792,14 +15811,17 @@ var record2 = program.command("record").description("Run a cloud browser from a
|
|
|
15792
15811
|
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
15793
15812
|
run2 = await client.cloudRun(id);
|
|
15794
15813
|
}
|
|
15795
|
-
emit(run2, options.pretty);
|
|
15814
|
+
if (options.json || options.pretty) emit(customerRun(run2), options.pretty);
|
|
15815
|
+
else process.stdout.write(formatCloudRun(run2));
|
|
15796
15816
|
if (run2.status === "failed") process.exitCode = 1;
|
|
15797
15817
|
});
|
|
15798
15818
|
var cloudRun = program.command("run").description("Retrieve or cancel a cloud run.");
|
|
15799
15819
|
for (const action of ["status", "cancel"]) cloudRun.command(action).argument("<run-id>").action(async (id) => {
|
|
15800
15820
|
const options = program.opts();
|
|
15801
15821
|
const client = new ControlPlaneClient(options.apiUrl, await loadCredential(options.apiUrl));
|
|
15802
|
-
|
|
15822
|
+
const run2 = await (action === "status" ? client.cloudRun(id) : client.cancelCloudRun(id));
|
|
15823
|
+
if (options.json || options.pretty) emit(customerRun(run2), options.pretty);
|
|
15824
|
+
else process.stdout.write(formatCloudRun(run2));
|
|
15803
15825
|
});
|
|
15804
15826
|
record2.command("start").option("--url <url>").option("--title <title>").option("--description <description>", "").option("--headed").option("--cdp-url <url>").option("--width <pixels>", "", "1280").option("--height <pixels>", "", "720").option("--max-duration <seconds>", "", "600").action(async (commandOptions) => {
|
|
15805
15827
|
const options = program.opts();
|