@runalabs/rill-cli 0.1.7 → 0.1.9
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 +7 -0
- package/dist/cli.js +36 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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
|
@@ -15448,6 +15448,9 @@ var ControlPlaneClient = class {
|
|
|
15448
15448
|
// src/analytics.ts
|
|
15449
15449
|
var commandCategories = /* @__PURE__ */ new Map([
|
|
15450
15450
|
["doctor", "doctor"],
|
|
15451
|
+
["record", "cloud_record"],
|
|
15452
|
+
["run status", "cloud_run_status"],
|
|
15453
|
+
["run cancel", "cloud_run_cancel"],
|
|
15451
15454
|
["record start", "record_start"],
|
|
15452
15455
|
["record stop", "record_stop"],
|
|
15453
15456
|
["record status", "record_status"],
|
|
@@ -15702,6 +15705,25 @@ function errorMessage(error51) {
|
|
|
15702
15705
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
15703
15706
|
}
|
|
15704
15707
|
|
|
15708
|
+
// src/cloud-output.ts
|
|
15709
|
+
function customerRun(run2) {
|
|
15710
|
+
if (!run2.result) return run2;
|
|
15711
|
+
const { usage: _usage, ...result } = run2.result;
|
|
15712
|
+
return { ...run2, result };
|
|
15713
|
+
}
|
|
15714
|
+
function formatCloudRun(run2) {
|
|
15715
|
+
const result = run2.result;
|
|
15716
|
+
const outcome = typeof result?.outcome === "string" ? result.outcome : void 0;
|
|
15717
|
+
const summary = typeof result?.summary === "string" ? result.summary : void 0;
|
|
15718
|
+
const publication = result?.publication;
|
|
15719
|
+
const lines = [`Run ${run2.status}${outcome ? ` \xB7 ${outcome}` : ""}`, `Run ID: ${run2.id}`];
|
|
15720
|
+
if (summary) lines.push("", summary);
|
|
15721
|
+
if (publication?.playbackUrl) lines.push("", `Recording: ${publication.playbackUrl}`);
|
|
15722
|
+
if (run2.status === "failed" && !summary) lines.push("", "The run could not finish.");
|
|
15723
|
+
if (!["completed", "failed", "cancelled"].includes(run2.status)) lines.push("", `Check progress: rill run status ${run2.id}`);
|
|
15724
|
+
return lines.join("\n") + "\n";
|
|
15725
|
+
}
|
|
15726
|
+
|
|
15705
15727
|
// src/recording-lifecycle.ts
|
|
15706
15728
|
async function startRecordingWithCompensation(remote, dependencies) {
|
|
15707
15729
|
try {
|
|
@@ -15739,7 +15761,7 @@ function controlPlaneUrl(environmentUrl) {
|
|
|
15739
15761
|
|
|
15740
15762
|
// src/cli.ts
|
|
15741
15763
|
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);
|
|
15764
|
+
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
15765
|
var activeTelemetry = null;
|
|
15744
15766
|
program.command("daemon", { hidden: true }).action(() => runDaemon());
|
|
15745
15767
|
program.command("doctor").description("Validate Rill prerequisites before recording.").action(async () => {
|
|
@@ -15748,7 +15770,7 @@ program.command("doctor").description("Validate Rill prerequisites before record
|
|
|
15748
15770
|
emit(result, options.pretty);
|
|
15749
15771
|
if (result.status === "error") process.exitCode = 1;
|
|
15750
15772
|
});
|
|
15751
|
-
async function authorize() {
|
|
15773
|
+
async function authorize(quiet = false) {
|
|
15752
15774
|
const options = program.opts();
|
|
15753
15775
|
const client = new ControlPlaneClient(options.apiUrl, null);
|
|
15754
15776
|
const authorization = await client.createDeviceAuthorization({ deviceName: `${hostname3()} \xB7 ${process.platform}` });
|
|
@@ -15765,7 +15787,7 @@ async function authorize() {
|
|
|
15765
15787
|
if (result.status === "pending") continue;
|
|
15766
15788
|
if (result.status !== "approved" || !result.token) throw new Error(`Device authorization ${result.status}.`);
|
|
15767
15789
|
await saveCredential(options.apiUrl, result.token);
|
|
15768
|
-
emit({ schemaVersion: 1, status: "authenticated", expiresAt: result.expiresAt, apiUrl: options.apiUrl }, options.pretty);
|
|
15790
|
+
if (!quiet) emit({ schemaVersion: 1, status: "authenticated", expiresAt: result.expiresAt, apiUrl: options.apiUrl }, options.pretty);
|
|
15769
15791
|
return result.token;
|
|
15770
15792
|
}
|
|
15771
15793
|
throw new Error("Device authorization expired.");
|
|
@@ -15776,8 +15798,9 @@ program.command("login").description("Authorize Rill once.").action(async () =>
|
|
|
15776
15798
|
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
15799
|
if (!url2 || !commandOptions.prompt) throw new Error("Use rill record <url> -p <prompt>.");
|
|
15778
15800
|
const options = program.opts();
|
|
15779
|
-
const token = await loadCredential(options.apiUrl) ?? await authorize();
|
|
15801
|
+
const token = await loadCredential(options.apiUrl) ?? await authorize(true);
|
|
15780
15802
|
const client = new ControlPlaneClient(options.apiUrl, token);
|
|
15803
|
+
if (!activeTelemetry) await startCliTelemetry(client, "cloud_record");
|
|
15781
15804
|
const id = commandOptions.id ?? crypto.randomUUID();
|
|
15782
15805
|
process.stderr.write(`Run ID: ${id}
|
|
15783
15806
|
`);
|
|
@@ -15792,14 +15815,17 @@ var record2 = program.command("record").description("Run a cloud browser from a
|
|
|
15792
15815
|
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
15793
15816
|
run2 = await client.cloudRun(id);
|
|
15794
15817
|
}
|
|
15795
|
-
emit(run2, options.pretty);
|
|
15818
|
+
if (options.json || options.pretty) emit(customerRun(run2), options.pretty);
|
|
15819
|
+
else process.stdout.write(formatCloudRun(run2));
|
|
15796
15820
|
if (run2.status === "failed") process.exitCode = 1;
|
|
15797
15821
|
});
|
|
15798
15822
|
var cloudRun = program.command("run").description("Retrieve or cancel a cloud run.");
|
|
15799
15823
|
for (const action of ["status", "cancel"]) cloudRun.command(action).argument("<run-id>").action(async (id) => {
|
|
15800
15824
|
const options = program.opts();
|
|
15801
15825
|
const client = new ControlPlaneClient(options.apiUrl, await loadCredential(options.apiUrl));
|
|
15802
|
-
|
|
15826
|
+
const run2 = await (action === "status" ? client.cloudRun(id) : client.cancelCloudRun(id));
|
|
15827
|
+
if (options.json || options.pretty) emit(customerRun(run2), options.pretty);
|
|
15828
|
+
else process.stdout.write(formatCloudRun(run2));
|
|
15803
15829
|
});
|
|
15804
15830
|
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
15831
|
const options = program.opts();
|
|
@@ -15939,11 +15965,14 @@ program.hook("preAction", async (_command, actionCommand) => {
|
|
|
15939
15965
|
const token = await loadCredential(options.apiUrl).catch(() => null);
|
|
15940
15966
|
if (!token) return;
|
|
15941
15967
|
const client = new ControlPlaneClient(options.apiUrl, token);
|
|
15968
|
+
await startCliTelemetry(client, command);
|
|
15969
|
+
});
|
|
15970
|
+
async function startCliTelemetry(client, command) {
|
|
15942
15971
|
const session = await client.agentSession().catch(() => null);
|
|
15943
15972
|
if (!session?.analyticsEnabled) return;
|
|
15944
15973
|
activeTelemetry = { client, command, startedAt: Date.now() };
|
|
15945
15974
|
await client.reportCliCommand({ phase: "started", command, cliVersion: CLI_VERSION, os: process.platform, arch: process.arch }).catch(() => void 0);
|
|
15946
|
-
}
|
|
15975
|
+
}
|
|
15947
15976
|
program.hook("postAction", async () => {
|
|
15948
15977
|
await finishCliTelemetry(process.exitCode ? new Error("command_reported_failure: Command returned a failure status.") : null);
|
|
15949
15978
|
});
|