opensteer 0.9.5 → 0.9.7
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/dist/{chunk-7LQL5YUR.js → chunk-3OHKIPBD.js} +571 -738
- package/dist/chunk-3OHKIPBD.js.map +1 -0
- package/dist/chunk-52UNH5UW.js +458 -0
- package/dist/chunk-52UNH5UW.js.map +1 -0
- package/dist/{chunk-GSCQQKZZ.js → chunk-PJXN7HED.js} +334 -18
- package/dist/chunk-PJXN7HED.js.map +1 -0
- package/dist/{chunk-ZRF7WMS3.js → chunk-R33BXCMQ.js} +16 -7
- package/dist/chunk-R33BXCMQ.js.map +1 -0
- package/dist/{chunk-T5P2QGZ3.js → chunk-U4BUCIZ4.js} +153 -12
- package/dist/chunk-U4BUCIZ4.js.map +1 -0
- package/dist/cli/bin.cjs +1421 -824
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +286 -129
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +1117 -703
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -53
- package/dist/index.d.ts +58 -53
- package/dist/index.js +4 -4
- package/dist/local-view/public/assets/app.js +10 -1
- package/dist/local-view/serve-entry.cjs +6815 -1272
- package/dist/local-view/serve-entry.cjs.map +1 -1
- package/dist/local-view/serve-entry.js +2 -2
- package/dist/opensteer-CY2QUJEG.js +6 -0
- package/dist/{opensteer-T2JENADR.js.map → opensteer-CY2QUJEG.js.map} +1 -1
- package/dist/{session-control-M3JD7ZKA.js → session-control-FIP6ZJLH.js} +4 -4
- package/dist/{session-control-M3JD7ZKA.js.map → session-control-FIP6ZJLH.js.map} +1 -1
- package/package.json +7 -7
- package/dist/chunk-7D45QUZ3.js +0 -332
- package/dist/chunk-7D45QUZ3.js.map +0 -1
- package/dist/chunk-7LQL5YUR.js.map +0 -1
- package/dist/chunk-GSCQQKZZ.js.map +0 -1
- package/dist/chunk-T5P2QGZ3.js.map +0 -1
- package/dist/chunk-ZRF7WMS3.js.map +0 -1
- package/dist/opensteer-T2JENADR.js +0 -6
package/dist/cli/bin.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { runLocalViewService } from '../chunk-
|
|
3
|
-
import { createOpensteerSemanticRuntime, dispatchSemanticOperation, loadEnvironment, normalizeOpensteerProviderMode, resolveOpensteerRuntimeConfig, assertProviderSupportsEngine, resolveOpensteerProvider, requireCloudAppBaseUrl, CloudSessionProxy, FlowRecorderCollector, generateReplayScript, OpensteerCloudClient } from '../chunk-
|
|
4
|
-
import { OpensteerBrowserManager, stopLocalViewService, setLocalViewMode, ensureLocalViewServiceRunning, buildLocalViewSessionUrl, resolveOpensteerEngineName, resolveFilesystemWorkspacePath } from '../chunk-
|
|
5
|
-
import { discoverLocalCdpBrowsers, inspectCdpEndpoint, readPersistedLocalBrowserSessionRecord, isProcessRunning,
|
|
2
|
+
import { runLocalViewService } from '../chunk-R33BXCMQ.js';
|
|
3
|
+
import { createOpensteerSemanticRuntime, dispatchSemanticOperation, isBrowserCoreError, loadEnvironment, normalizeOpensteerProviderMode, resolveOpensteerRuntimeConfig, assertProviderSupportsEngine, resolveOpensteerProvider, requireCloudAppBaseUrl, CloudSessionProxy, FlowRecorderCollector, generateReplayScript, OpensteerCloudClient } from '../chunk-3OHKIPBD.js';
|
|
4
|
+
import { isOpensteerProtocolError, OpensteerBrowserManager, stopLocalViewService, setLocalViewMode, ensureLocalViewServiceRunning, buildLocalViewSessionUrl, resolveOpensteerEngineName, resolveFilesystemWorkspacePath } from '../chunk-PJXN7HED.js';
|
|
5
|
+
import { discoverLocalCdpBrowsers, inspectCdpEndpoint, readPersistedLocalBrowserSessionRecord, getPersistedLocalBrowserSessionOwnership, isAttachedLocalBrowserSessionReachable, isProcessRunning, buildLocalViewSessionIdForRecord, pathExists, readPersistedCloudSessionRecord } from '../chunk-U4BUCIZ4.js';
|
|
6
6
|
import process4 from 'process';
|
|
7
7
|
import { mkdir, writeFile } from 'fs/promises';
|
|
8
8
|
import path2 from 'path';
|
|
@@ -14,13 +14,115 @@ import { fileURLToPath } from 'url';
|
|
|
14
14
|
|
|
15
15
|
// package.json
|
|
16
16
|
var package_default = {
|
|
17
|
-
version: "0.9.
|
|
17
|
+
version: "0.9.7"};
|
|
18
18
|
|
|
19
19
|
// src/cli/env-loader.ts
|
|
20
20
|
async function loadCliEnvironment(cwd) {
|
|
21
21
|
loadEnvironment(cwd);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
// src/cli/errors.ts
|
|
25
|
+
var CliError = class extends Error {
|
|
26
|
+
type;
|
|
27
|
+
usage;
|
|
28
|
+
constructor(type, message, usage) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = "CliError";
|
|
31
|
+
this.type = type;
|
|
32
|
+
this.usage = usage;
|
|
33
|
+
}
|
|
34
|
+
format() {
|
|
35
|
+
return this.usage === void 0 ? this.message : `${this.message}
|
|
36
|
+
Usage: ${this.usage}`;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
function isCliError(value) {
|
|
40
|
+
return value instanceof CliError;
|
|
41
|
+
}
|
|
42
|
+
function formatCliErrorOutput(error) {
|
|
43
|
+
if (isCliError(error)) {
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
error: error.format(),
|
|
47
|
+
type: error.type
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (isOpensteerProtocolError(error)) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: error.message,
|
|
54
|
+
code: error.code,
|
|
55
|
+
retriable: error.retriable
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (isBrowserCoreError(error)) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
error: error.message,
|
|
62
|
+
code: error.code,
|
|
63
|
+
retriable: error.retriable
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (error instanceof Error && "opensteerError" in error) {
|
|
67
|
+
const oe = error.opensteerError;
|
|
68
|
+
return {
|
|
69
|
+
success: false,
|
|
70
|
+
error: oe.message,
|
|
71
|
+
code: oe.code,
|
|
72
|
+
retriable: oe.retriable
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (error instanceof SyntaxError) {
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
error: error.message,
|
|
79
|
+
type: "invalid_value"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
error: error instanceof Error ? error.message : String(error)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function emitWarning(warning) {
|
|
88
|
+
process.stderr.write(`${JSON.stringify({ warning })}
|
|
89
|
+
`);
|
|
90
|
+
}
|
|
91
|
+
var CLI_USAGE_HINTS = {
|
|
92
|
+
"session.open": "opensteer open <url> [--workspace <id>]",
|
|
93
|
+
"page.goto": "opensteer goto <url>",
|
|
94
|
+
"page.evaluate": "opensteer evaluate <script>",
|
|
95
|
+
"page.add-init-script": "opensteer init-script <script>",
|
|
96
|
+
"dom.click": "opensteer click <element> --persist <key>",
|
|
97
|
+
"dom.hover": "opensteer hover <element> --persist <key>",
|
|
98
|
+
"dom.input": "opensteer input <element> <text> --persist <key>",
|
|
99
|
+
"dom.scroll": "opensteer scroll <direction> <amount> --persist <key>",
|
|
100
|
+
"dom.extract": "opensteer extract <template> --persist <key>",
|
|
101
|
+
"network.detail": "opensteer network detail <recordId>",
|
|
102
|
+
"session.fetch": "opensteer fetch <url>",
|
|
103
|
+
"captcha.solve": "opensteer captcha solve --provider <name> --api-key <key>",
|
|
104
|
+
"scripts.capture": "opensteer scripts capture",
|
|
105
|
+
"scripts.beautify": "opensteer scripts beautify <artifactId>",
|
|
106
|
+
"scripts.deobfuscate": "opensteer scripts deobfuscate <artifactId>",
|
|
107
|
+
"scripts.sandbox": "opensteer scripts sandbox <artifactId>",
|
|
108
|
+
"interaction.capture": "opensteer interaction capture",
|
|
109
|
+
"interaction.get": "opensteer interaction get <traceId>",
|
|
110
|
+
"interaction.replay": "opensteer interaction replay <traceId>",
|
|
111
|
+
"interaction.diff": "opensteer interaction diff <leftTraceId> <rightTraceId>",
|
|
112
|
+
"artifact.read": "opensteer artifact read <artifactId>",
|
|
113
|
+
"computer.click": "opensteer computer click <x> <y>",
|
|
114
|
+
"computer.type": "opensteer computer type <text>",
|
|
115
|
+
"computer.key": "opensteer computer key <key>",
|
|
116
|
+
"computer.scroll": "opensteer computer scroll <x> <y> --dx <n> --dy <n>",
|
|
117
|
+
"computer.move": "opensteer computer move <x> <y>",
|
|
118
|
+
"computer.drag": "opensteer computer drag <x1> <y1> <x2> <y2>",
|
|
119
|
+
"computer.screenshot": "opensteer computer screenshot",
|
|
120
|
+
exec: "opensteer exec <expression>",
|
|
121
|
+
record: "opensteer record --url <url> --workspace <id>",
|
|
122
|
+
"browser.inspect": "opensteer browser inspect <endpoint>",
|
|
123
|
+
"browser.clone": "opensteer browser clone --source-user-data-dir <path>"
|
|
124
|
+
};
|
|
125
|
+
|
|
24
126
|
// src/cli/help.ts
|
|
25
127
|
function getHelpText() {
|
|
26
128
|
return `Opensteer CLI
|
|
@@ -279,7 +381,7 @@ function parseCommandLine(argv) {
|
|
|
279
381
|
const key = token.slice(2, separator === -1 ? void 0 : separator);
|
|
280
382
|
const spec = CLI_OPTION_SPECS[key];
|
|
281
383
|
if (spec === void 0) {
|
|
282
|
-
throw new
|
|
384
|
+
throw new CliError("unknown_option", `Unknown option: --${key}.`);
|
|
283
385
|
}
|
|
284
386
|
if (separator !== -1) {
|
|
285
387
|
rawOptions.set(key, [...rawOptions.get(key) ?? [], token.slice(separator + 1)]);
|
|
@@ -308,7 +410,8 @@ function parseCommandLine(argv) {
|
|
|
308
410
|
continue;
|
|
309
411
|
}
|
|
310
412
|
if (next === void 0 || next.startsWith("--")) {
|
|
311
|
-
throw new
|
|
413
|
+
throw new CliError(
|
|
414
|
+
"missing_arguments",
|
|
312
415
|
`Option "--${key}" requires a value.${next?.startsWith("--") === true ? ` Use "--${key}=<value>" when the value begins with "--".` : ``}`
|
|
313
416
|
);
|
|
314
417
|
}
|
|
@@ -354,10 +457,14 @@ function parseCommandLine(argv) {
|
|
|
354
457
|
const autoLocalView = readOptionalBoolean(rawOptions, "auto");
|
|
355
458
|
const noAutoLocalView = readOptionalBoolean(rawOptions, "no-auto");
|
|
356
459
|
if (autoLocalView === true && noAutoLocalView === true) {
|
|
357
|
-
throw new
|
|
460
|
+
throw new CliError("invalid_option", 'Options "--auto" and "--no-auto" cannot be combined.');
|
|
358
461
|
}
|
|
359
462
|
if (command[0] !== "view" && (autoLocalView !== void 0 || noAutoLocalView !== void 0)) {
|
|
360
|
-
throw new
|
|
463
|
+
throw new CliError(
|
|
464
|
+
"invalid_option",
|
|
465
|
+
'Options "--auto" and "--no-auto" are only supported with "view".',
|
|
466
|
+
"opensteer view --auto"
|
|
467
|
+
);
|
|
361
468
|
}
|
|
362
469
|
const global = readOptionalBoolean(rawOptions, "global");
|
|
363
470
|
const yes = readOptionalBoolean(rawOptions, "yes");
|
|
@@ -413,7 +520,7 @@ function parseKeyValueList(values) {
|
|
|
413
520
|
values.map((entry) => {
|
|
414
521
|
const separator = entry.indexOf("=");
|
|
415
522
|
if (separator <= 0) {
|
|
416
|
-
throw new
|
|
523
|
+
throw new CliError("invalid_value", `Expected NAME=VALUE, received "${entry}".`);
|
|
417
524
|
}
|
|
418
525
|
return [entry.slice(0, separator), entry.slice(separator + 1)];
|
|
419
526
|
})
|
|
@@ -444,7 +551,7 @@ function readOptionalBoolean(options, name) {
|
|
|
444
551
|
if (value === "false") {
|
|
445
552
|
return false;
|
|
446
553
|
}
|
|
447
|
-
throw new
|
|
554
|
+
throw new CliError("invalid_value", `Option "--${name}" must be true or false.`);
|
|
448
555
|
}
|
|
449
556
|
function readOptionalNumber(options, name) {
|
|
450
557
|
const value = readSingle(options, name);
|
|
@@ -453,13 +560,20 @@ function readOptionalNumber(options, name) {
|
|
|
453
560
|
}
|
|
454
561
|
const parsed = Number(value);
|
|
455
562
|
if (!Number.isFinite(parsed)) {
|
|
456
|
-
throw new
|
|
563
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a number.`);
|
|
457
564
|
}
|
|
458
565
|
return parsed;
|
|
459
566
|
}
|
|
460
567
|
function readJsonValue(options, name) {
|
|
461
568
|
const value = readSingle(options, name);
|
|
462
|
-
|
|
569
|
+
if (value === void 0) {
|
|
570
|
+
return void 0;
|
|
571
|
+
}
|
|
572
|
+
try {
|
|
573
|
+
return JSON.parse(value);
|
|
574
|
+
} catch {
|
|
575
|
+
throw new CliError("invalid_value", `Option "--${name}" contains invalid JSON.`);
|
|
576
|
+
}
|
|
463
577
|
}
|
|
464
578
|
function readJsonObject(options, name) {
|
|
465
579
|
const parsed = readJsonValue(options, name);
|
|
@@ -467,7 +581,7 @@ function readJsonObject(options, name) {
|
|
|
467
581
|
return void 0;
|
|
468
582
|
}
|
|
469
583
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
470
|
-
throw new
|
|
584
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a JSON object.`);
|
|
471
585
|
}
|
|
472
586
|
return parsed;
|
|
473
587
|
}
|
|
@@ -477,7 +591,7 @@ function readJsonArray(options, name) {
|
|
|
477
591
|
return void 0;
|
|
478
592
|
}
|
|
479
593
|
if (!Array.isArray(parsed)) {
|
|
480
|
-
throw new
|
|
594
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a JSON array.`);
|
|
481
595
|
}
|
|
482
596
|
return parsed;
|
|
483
597
|
}
|
|
@@ -497,7 +611,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
497
611
|
case "session.open": {
|
|
498
612
|
const url = parsed.rest[0];
|
|
499
613
|
if (url === void 0) {
|
|
500
|
-
throw new
|
|
614
|
+
throw new CliError("missing_arguments", "open requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
501
615
|
}
|
|
502
616
|
return {
|
|
503
617
|
url,
|
|
@@ -530,7 +644,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
530
644
|
}
|
|
531
645
|
case "page.goto": {
|
|
532
646
|
if (parsed.rest[0] === void 0) {
|
|
533
|
-
throw new
|
|
647
|
+
throw new CliError("missing_arguments", "goto requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
534
648
|
}
|
|
535
649
|
const captureNetwork = readSingle(parsed.rawOptions, "capture-network");
|
|
536
650
|
return {
|
|
@@ -542,14 +656,14 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
542
656
|
return parsed.rest[0] === void 0 ? {} : { mode: parsed.rest[0] };
|
|
543
657
|
case "page.evaluate":
|
|
544
658
|
if (parsed.rest[0] === void 0) {
|
|
545
|
-
throw new
|
|
659
|
+
throw new CliError("missing_arguments", "evaluate requires a script.", CLI_USAGE_HINTS[operation]);
|
|
546
660
|
}
|
|
547
661
|
return {
|
|
548
662
|
script: joinRest(parsed.rest, 0)
|
|
549
663
|
};
|
|
550
664
|
case "page.add-init-script":
|
|
551
665
|
if (parsed.rest[0] === void 0) {
|
|
552
|
-
throw new
|
|
666
|
+
throw new CliError("missing_arguments", "init-script requires a script.", CLI_USAGE_HINTS[operation]);
|
|
553
667
|
}
|
|
554
668
|
return {
|
|
555
669
|
script: joinRest(parsed.rest, 0)
|
|
@@ -565,7 +679,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
565
679
|
return buildElementTargetInput(parsed, "hover");
|
|
566
680
|
case "dom.input": {
|
|
567
681
|
if (parsed.rest[1] === void 0) {
|
|
568
|
-
throw new
|
|
682
|
+
throw new CliError("missing_arguments", "input requires an element number and text.", CLI_USAGE_HINTS[operation]);
|
|
569
683
|
}
|
|
570
684
|
const pressEnter = readOptionalBoolean(parsed.rawOptions, "press-enter");
|
|
571
685
|
return {
|
|
@@ -596,7 +710,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
596
710
|
}
|
|
597
711
|
case "dom.extract": {
|
|
598
712
|
if (parsed.rest[0] === void 0) {
|
|
599
|
-
throw new
|
|
713
|
+
throw new CliError("missing_arguments", "extract requires a template.", CLI_USAGE_HINTS[operation]);
|
|
600
714
|
}
|
|
601
715
|
const persist = readPersistKey(parsed, "extract");
|
|
602
716
|
return {
|
|
@@ -632,7 +746,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
632
746
|
}
|
|
633
747
|
case "network.detail": {
|
|
634
748
|
if (parsed.rest[0] === void 0) {
|
|
635
|
-
throw new
|
|
749
|
+
throw new CliError("missing_arguments", "network detail requires a record id.", CLI_USAGE_HINTS[operation]);
|
|
636
750
|
}
|
|
637
751
|
const probeFlag = readOptionalBoolean(parsed.rawOptions, "probe");
|
|
638
752
|
return {
|
|
@@ -643,7 +757,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
643
757
|
case "session.fetch": {
|
|
644
758
|
const url = parsed.rest[0];
|
|
645
759
|
if (url === void 0) {
|
|
646
|
-
throw new
|
|
760
|
+
throw new CliError("missing_arguments", "fetch requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
647
761
|
}
|
|
648
762
|
const bodyJson = readJsonValue(parsed.rawOptions, "body");
|
|
649
763
|
const bodyText = readSingle(parsed.rawOptions, "body-text");
|
|
@@ -651,7 +765,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
651
765
|
const query = parseKeyValueList(parsed.rawOptions.get("query"));
|
|
652
766
|
const headers = parseKeyValueList(parsed.rawOptions.get("header"));
|
|
653
767
|
if (bodyJson !== void 0 && bodyText !== void 0) {
|
|
654
|
-
throw new
|
|
768
|
+
throw new CliError("invalid_option", 'Use either "--body" or "--body-text", not both.');
|
|
655
769
|
}
|
|
656
770
|
const transport = readSingle(parsed.rawOptions, "transport");
|
|
657
771
|
const cookies = readOptionalBoolean(parsed.rawOptions, "cookies");
|
|
@@ -682,7 +796,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
682
796
|
const siteKey = readSingle(parsed.rawOptions, "site-key");
|
|
683
797
|
const pageUrl = readSingle(parsed.rawOptions, "page-url");
|
|
684
798
|
if (provider === void 0 || apiKey === void 0) {
|
|
685
|
-
throw new
|
|
799
|
+
throw new CliError("missing_arguments", 'captcha solve requires "--provider" and "--api-key".', CLI_USAGE_HINTS[operation]);
|
|
686
800
|
}
|
|
687
801
|
return {
|
|
688
802
|
provider: readCaptchaProvider(provider),
|
|
@@ -712,7 +826,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
712
826
|
case "scripts.beautify":
|
|
713
827
|
case "scripts.deobfuscate": {
|
|
714
828
|
if (parsed.rest[0] === void 0) {
|
|
715
|
-
throw new
|
|
829
|
+
throw new CliError("missing_arguments", `${parsed.command.join(" ")} requires an artifact id.`, CLI_USAGE_HINTS[operation]);
|
|
716
830
|
}
|
|
717
831
|
const persist = readOptionalBoolean(parsed.rawOptions, "persist");
|
|
718
832
|
return {
|
|
@@ -722,7 +836,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
722
836
|
}
|
|
723
837
|
case "scripts.sandbox":
|
|
724
838
|
if (parsed.rest[0] === void 0) {
|
|
725
|
-
throw new
|
|
839
|
+
throw new CliError("missing_arguments", "scripts sandbox requires an artifact id.", CLI_USAGE_HINTS[operation]);
|
|
726
840
|
}
|
|
727
841
|
{
|
|
728
842
|
const fidelity = readSingle(parsed.rawOptions, "fidelity");
|
|
@@ -771,14 +885,14 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
771
885
|
case "interaction.get":
|
|
772
886
|
case "interaction.replay":
|
|
773
887
|
if (parsed.rest[0] === void 0) {
|
|
774
|
-
throw new
|
|
888
|
+
throw new CliError("missing_arguments", `${parsed.command.join(" ")} requires a trace id.`, CLI_USAGE_HINTS[operation]);
|
|
775
889
|
}
|
|
776
890
|
return {
|
|
777
891
|
traceId: parsed.rest[0]
|
|
778
892
|
};
|
|
779
893
|
case "interaction.diff":
|
|
780
894
|
if (parsed.rest[0] === void 0 || parsed.rest[1] === void 0) {
|
|
781
|
-
throw new
|
|
895
|
+
throw new CliError("missing_arguments", "interaction diff requires two trace ids.", CLI_USAGE_HINTS[operation]);
|
|
782
896
|
}
|
|
783
897
|
return {
|
|
784
898
|
leftTraceId: parsed.rest[0],
|
|
@@ -786,7 +900,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
786
900
|
};
|
|
787
901
|
case "artifact.read":
|
|
788
902
|
if (parsed.rest[0] === void 0) {
|
|
789
|
-
throw new
|
|
903
|
+
throw new CliError("missing_arguments", "artifact read requires an artifact id.", CLI_USAGE_HINTS[operation]);
|
|
790
904
|
}
|
|
791
905
|
return {
|
|
792
906
|
artifactId: parsed.rest[0]
|
|
@@ -794,7 +908,8 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
794
908
|
case "session.close":
|
|
795
909
|
return {};
|
|
796
910
|
default:
|
|
797
|
-
throw new
|
|
911
|
+
throw new CliError(
|
|
912
|
+
"unsupported_operation",
|
|
798
913
|
`${operation} does not have a direct CLI input shape. Use a supported command or the SDK.`
|
|
799
914
|
);
|
|
800
915
|
}
|
|
@@ -841,7 +956,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
841
956
|
}
|
|
842
957
|
case "type":
|
|
843
958
|
if (parsed.rest[0] === void 0) {
|
|
844
|
-
throw new
|
|
959
|
+
throw new CliError("missing_arguments", "computer type requires text.");
|
|
845
960
|
}
|
|
846
961
|
return {
|
|
847
962
|
action: {
|
|
@@ -852,7 +967,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
852
967
|
};
|
|
853
968
|
case "key": {
|
|
854
969
|
if (parsed.rest[0] === void 0) {
|
|
855
|
-
throw new
|
|
970
|
+
throw new CliError("missing_arguments", "computer key requires a key.");
|
|
856
971
|
}
|
|
857
972
|
const modifiers = readKeyModifiers(readSingle(parsed.rawOptions, "modifiers"));
|
|
858
973
|
return {
|
|
@@ -868,7 +983,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
868
983
|
const dx = readOptionalNumber(parsed.rawOptions, "dx");
|
|
869
984
|
const dy = readOptionalNumber(parsed.rawOptions, "dy");
|
|
870
985
|
if (dx === void 0 || dy === void 0) {
|
|
871
|
-
throw new
|
|
986
|
+
throw new CliError("missing_arguments", 'computer scroll requires "--dx" and "--dy".');
|
|
872
987
|
}
|
|
873
988
|
return {
|
|
874
989
|
action: {
|
|
@@ -923,49 +1038,50 @@ function buildComputerExecuteInput(parsed) {
|
|
|
923
1038
|
}
|
|
924
1039
|
};
|
|
925
1040
|
default:
|
|
926
|
-
throw new
|
|
1041
|
+
throw new CliError("unknown_command", `Unknown computer command: ${parsed.command.join(" ")}`);
|
|
927
1042
|
}
|
|
928
1043
|
}
|
|
929
1044
|
async function resolvePageRefByIndex(runtime, index) {
|
|
930
1045
|
const pages = (await runtime.listPages({})).pages;
|
|
931
1046
|
const page = pages[index - 1];
|
|
932
1047
|
if (page === void 0) {
|
|
933
|
-
throw new
|
|
1048
|
+
throw new CliError("invalid_value", `tab ${String(index)} does not exist.`);
|
|
934
1049
|
}
|
|
935
1050
|
return page.pageRef;
|
|
936
1051
|
}
|
|
937
1052
|
function readRequiredPositiveInteger(value, message) {
|
|
938
1053
|
const parsed = readRequiredNumber(value, message);
|
|
939
1054
|
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
940
|
-
throw new
|
|
1055
|
+
throw new CliError("missing_arguments", message);
|
|
941
1056
|
}
|
|
942
1057
|
return parsed;
|
|
943
1058
|
}
|
|
944
1059
|
function readRequiredNumber(value, message) {
|
|
945
1060
|
if (value === void 0) {
|
|
946
|
-
throw new
|
|
1061
|
+
throw new CliError("missing_arguments", message);
|
|
947
1062
|
}
|
|
948
1063
|
const parsed = Number(value);
|
|
949
1064
|
if (!Number.isFinite(parsed)) {
|
|
950
|
-
throw new
|
|
1065
|
+
throw new CliError("missing_arguments", message);
|
|
951
1066
|
}
|
|
952
1067
|
return parsed;
|
|
953
1068
|
}
|
|
954
1069
|
function readSingleDirection(value) {
|
|
955
1070
|
if (value === void 0 || !SCROLL_DIRECTIONS.has(value)) {
|
|
956
|
-
throw new
|
|
1071
|
+
throw new CliError("missing_arguments", "scroll requires a direction: up, down, left, or right.");
|
|
957
1072
|
}
|
|
958
1073
|
return value;
|
|
959
1074
|
}
|
|
960
1075
|
function readClickButton(value) {
|
|
961
1076
|
if (value === void 0 || !CLICK_BUTTONS.has(value)) {
|
|
962
|
-
throw new
|
|
1077
|
+
throw new CliError("invalid_value", 'Expected "--button" to be one of: left, middle, right.');
|
|
963
1078
|
}
|
|
964
1079
|
return value;
|
|
965
1080
|
}
|
|
966
1081
|
function readFetchTransport(value) {
|
|
967
1082
|
if (value === void 0 || !FETCH_TRANSPORTS.has(value)) {
|
|
968
|
-
throw new
|
|
1083
|
+
throw new CliError(
|
|
1084
|
+
"invalid_value",
|
|
969
1085
|
'Expected "--transport" to be one of: auto, direct, matched-tls, context, page.'
|
|
970
1086
|
);
|
|
971
1087
|
}
|
|
@@ -973,31 +1089,31 @@ function readFetchTransport(value) {
|
|
|
973
1089
|
}
|
|
974
1090
|
function readCaptchaProvider(value) {
|
|
975
1091
|
if (value === void 0 || !CAPTCHA_PROVIDERS.has(value)) {
|
|
976
|
-
throw new
|
|
1092
|
+
throw new CliError("invalid_value", 'Expected "--provider" to be one of: 2captcha, capsolver.');
|
|
977
1093
|
}
|
|
978
1094
|
return value;
|
|
979
1095
|
}
|
|
980
1096
|
function readCaptchaType(value) {
|
|
981
1097
|
if (value === void 0 || !CAPTCHA_TYPES.has(value)) {
|
|
982
|
-
throw new
|
|
1098
|
+
throw new CliError("invalid_value", 'Expected "--type" to be one of: recaptcha-v2, hcaptcha, turnstile.');
|
|
983
1099
|
}
|
|
984
1100
|
return value;
|
|
985
1101
|
}
|
|
986
1102
|
function readSandboxFidelity(value) {
|
|
987
1103
|
if (value === void 0 || !SANDBOX_FIDELITIES.has(value)) {
|
|
988
|
-
throw new
|
|
1104
|
+
throw new CliError("invalid_value", 'Expected "--fidelity" to be one of: minimal, standard, full.');
|
|
989
1105
|
}
|
|
990
1106
|
return value;
|
|
991
1107
|
}
|
|
992
1108
|
function readSandboxClockMode(value) {
|
|
993
1109
|
if (value === void 0 || !SANDBOX_CLOCK_MODES.has(value)) {
|
|
994
|
-
throw new
|
|
1110
|
+
throw new CliError("invalid_value", 'Expected "--clock" to be one of: real, manual.');
|
|
995
1111
|
}
|
|
996
1112
|
return value;
|
|
997
1113
|
}
|
|
998
1114
|
function readScreenshotFormat(value) {
|
|
999
1115
|
if (value === void 0 || !SCREENSHOT_FORMATS.has(value)) {
|
|
1000
|
-
throw new
|
|
1116
|
+
throw new CliError("invalid_value", 'Expected "--format" to be one of: png, jpeg, webp.');
|
|
1001
1117
|
}
|
|
1002
1118
|
return value;
|
|
1003
1119
|
}
|
|
@@ -1008,7 +1124,7 @@ function readKeyModifiers(value) {
|
|
|
1008
1124
|
}
|
|
1009
1125
|
for (const modifier of modifiers) {
|
|
1010
1126
|
if (!KEY_MODIFIERS.has(modifier)) {
|
|
1011
|
-
throw new
|
|
1127
|
+
throw new CliError("invalid_value", 'Expected "--modifiers" to contain only: Shift, Control, Alt, Meta.');
|
|
1012
1128
|
}
|
|
1013
1129
|
}
|
|
1014
1130
|
return [...new Set(modifiers)];
|
|
@@ -1016,17 +1132,22 @@ function readKeyModifiers(value) {
|
|
|
1016
1132
|
function readPersistKey(parsed, verb) {
|
|
1017
1133
|
const value = readSingle(parsed.rawOptions, "persist");
|
|
1018
1134
|
if (value === void 0) {
|
|
1019
|
-
throw new
|
|
1135
|
+
throw new CliError("missing_arguments", `${verb} requires "--persist <key>".`);
|
|
1020
1136
|
}
|
|
1021
1137
|
if (value === "true" || value === "false") {
|
|
1022
|
-
throw new
|
|
1138
|
+
throw new CliError("missing_arguments", `${verb} requires "--persist <key>".`);
|
|
1023
1139
|
}
|
|
1024
1140
|
return value;
|
|
1025
1141
|
}
|
|
1026
1142
|
function parseRequiredJsonObjectArgument(value, label) {
|
|
1027
|
-
|
|
1143
|
+
let parsed;
|
|
1144
|
+
try {
|
|
1145
|
+
parsed = JSON.parse(value);
|
|
1146
|
+
} catch {
|
|
1147
|
+
throw new CliError("invalid_value", `${label} contains invalid JSON.`);
|
|
1148
|
+
}
|
|
1028
1149
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1029
|
-
throw new
|
|
1150
|
+
throw new CliError("invalid_value", `${label} must be a JSON object.`);
|
|
1030
1151
|
}
|
|
1031
1152
|
return parsed;
|
|
1032
1153
|
}
|
|
@@ -1038,6 +1159,7 @@ function joinRest(rest, startIndex) {
|
|
|
1038
1159
|
function renderOperationOutput(operation, result, input) {
|
|
1039
1160
|
switch (operation) {
|
|
1040
1161
|
case "session.open":
|
|
1162
|
+
case "page.activate":
|
|
1041
1163
|
case "page.goto":
|
|
1042
1164
|
return renderJson(formatNavigationOutput(result));
|
|
1043
1165
|
case "page.snapshot":
|
|
@@ -1046,14 +1168,14 @@ function renderOperationOutput(operation, result, input) {
|
|
|
1046
1168
|
case "dom.hover":
|
|
1047
1169
|
case "dom.input":
|
|
1048
1170
|
case "dom.scroll":
|
|
1049
|
-
return renderJson(formatActionOutput(result
|
|
1171
|
+
return renderJson(formatActionOutput(result));
|
|
1050
1172
|
case "dom.extract":
|
|
1051
1173
|
return renderJson(formatExtractOutput(result));
|
|
1052
1174
|
case "page.list":
|
|
1053
|
-
case "page.new":
|
|
1054
|
-
case "page.activate":
|
|
1055
1175
|
case "page.close":
|
|
1056
1176
|
return formatTabOutput(result);
|
|
1177
|
+
case "page.new":
|
|
1178
|
+
return renderJson(formatCreatedPageOutput(result));
|
|
1057
1179
|
case "network.query":
|
|
1058
1180
|
return formatNetworkQueryOutput(result, input);
|
|
1059
1181
|
case "network.detail":
|
|
@@ -1091,6 +1213,12 @@ function formatNavigationOutput(result) {
|
|
|
1091
1213
|
...readStringField(result, "title") === void 0 ? {} : { title: readStringField(result, "title") }
|
|
1092
1214
|
};
|
|
1093
1215
|
}
|
|
1216
|
+
function formatCreatedPageOutput(result) {
|
|
1217
|
+
return {
|
|
1218
|
+
...readStringField(result, "pageRef") === void 0 ? {} : { pageRef: readStringField(result, "pageRef") },
|
|
1219
|
+
...formatNavigationOutput(result)
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1094
1222
|
function formatSnapshotOutput(result) {
|
|
1095
1223
|
if (result !== null && typeof result === "object" && typeof result.html === "string") {
|
|
1096
1224
|
return `${result.html}
|
|
@@ -1098,36 +1226,11 @@ function formatSnapshotOutput(result) {
|
|
|
1098
1226
|
}
|
|
1099
1227
|
return renderJson(result);
|
|
1100
1228
|
}
|
|
1101
|
-
function formatActionOutput(result
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
...readStringField(
|
|
1105
|
-
...readStringField(target, "pathHint") === void 0 ? {} : { pathHint: readStringField(target, "pathHint") }
|
|
1229
|
+
function formatActionOutput(result) {
|
|
1230
|
+
return {
|
|
1231
|
+
...readStringField(result, "tagName") === void 0 ? {} : { tagName: readStringField(result, "tagName") },
|
|
1232
|
+
...readStringField(result, "persist") === void 0 ? {} : { persist: readStringField(result, "persist") }
|
|
1106
1233
|
};
|
|
1107
|
-
const point = readObjectField(result, "point");
|
|
1108
|
-
if (point !== void 0) {
|
|
1109
|
-
output.point = {
|
|
1110
|
-
...readNumberField(point, "x") === void 0 ? {} : { x: readNumberField(point, "x") },
|
|
1111
|
-
...readNumberField(point, "y") === void 0 ? {} : { y: readNumberField(point, "y") }
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
const persist = readStringField(target, "persist");
|
|
1115
|
-
if (persist !== void 0) {
|
|
1116
|
-
output.persist = persist;
|
|
1117
|
-
}
|
|
1118
|
-
const text = readStringField(input, "text");
|
|
1119
|
-
if (text !== void 0) {
|
|
1120
|
-
output.text = text;
|
|
1121
|
-
}
|
|
1122
|
-
const direction = readStringField(input, "direction");
|
|
1123
|
-
if (direction !== void 0) {
|
|
1124
|
-
output.direction = direction;
|
|
1125
|
-
}
|
|
1126
|
-
const amount = readNumberField(input, "amount");
|
|
1127
|
-
if (amount !== void 0) {
|
|
1128
|
-
output.amount = amount;
|
|
1129
|
-
}
|
|
1130
|
-
return output;
|
|
1131
1234
|
}
|
|
1132
1235
|
function formatExtractOutput(result) {
|
|
1133
1236
|
const data = readUnknownField(result, "data");
|
|
@@ -1359,20 +1462,18 @@ function formatStateOutput(result) {
|
|
|
1359
1462
|
`;
|
|
1360
1463
|
}
|
|
1361
1464
|
function formatComputerOutput(result) {
|
|
1362
|
-
const action = readObjectField(result, "action");
|
|
1363
1465
|
const screenshot = readObjectField(result, "screenshot");
|
|
1364
1466
|
const payload = readObjectField(screenshot, "payload");
|
|
1365
|
-
const timing = readObjectField(result, "timing");
|
|
1366
1467
|
return {
|
|
1367
|
-
...
|
|
1468
|
+
...readStringField(result, "url") === void 0 ? {} : { url: readStringField(result, "url") },
|
|
1469
|
+
...readStringField(result, "title") === void 0 ? {} : { title: readStringField(result, "title") },
|
|
1368
1470
|
...payload === void 0 ? {} : {
|
|
1369
1471
|
screenshot: {
|
|
1370
1472
|
...readStringField(payload, "uri") === void 0 ? {} : { uri: readStringField(payload, "uri") },
|
|
1371
1473
|
...readStringField(screenshot, "format") === void 0 ? {} : { format: readStringField(screenshot, "format") },
|
|
1372
1474
|
...readObjectField(screenshot, "size") === void 0 ? {} : { size: readObjectField(screenshot, "size") }
|
|
1373
1475
|
}
|
|
1374
|
-
}
|
|
1375
|
-
...timing === void 0 ? {} : { timingMs: timing }
|
|
1476
|
+
}
|
|
1376
1477
|
};
|
|
1377
1478
|
}
|
|
1378
1479
|
function formatScriptsCaptureOutput(result) {
|
|
@@ -2020,7 +2121,7 @@ async function collectOpensteerStatus(input) {
|
|
|
2020
2121
|
...output,
|
|
2021
2122
|
rootPath,
|
|
2022
2123
|
lanes: {
|
|
2023
|
-
local: describeLocalLane(localRecord, input.provider.mode === "local"),
|
|
2124
|
+
local: await describeLocalLane(localRecord, input.provider.mode === "local"),
|
|
2024
2125
|
cloud: await describeCloudLane({
|
|
2025
2126
|
record: cloudRecord,
|
|
2026
2127
|
current: input.provider.mode === "cloud",
|
|
@@ -2072,8 +2173,38 @@ async function readWorkspaceCloudRecord(rootPath) {
|
|
|
2072
2173
|
}
|
|
2073
2174
|
return readPersistedCloudSessionRecord(rootPath);
|
|
2074
2175
|
}
|
|
2075
|
-
function describeLocalLane(record, current) {
|
|
2076
|
-
if (record === void 0
|
|
2176
|
+
async function describeLocalLane(record, current) {
|
|
2177
|
+
if (record === void 0) {
|
|
2178
|
+
return {
|
|
2179
|
+
provider: "local",
|
|
2180
|
+
status: "idle",
|
|
2181
|
+
current,
|
|
2182
|
+
summary: "none"
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
if (getPersistedLocalBrowserSessionOwnership(record) === "attached") {
|
|
2186
|
+
if (!await isAttachedLocalBrowserSessionReachable(record)) {
|
|
2187
|
+
return {
|
|
2188
|
+
provider: "local",
|
|
2189
|
+
status: "stale",
|
|
2190
|
+
current,
|
|
2191
|
+
summary: "attached browser unavailable",
|
|
2192
|
+
detail: record.engine,
|
|
2193
|
+
engine: record.engine
|
|
2194
|
+
};
|
|
2195
|
+
}
|
|
2196
|
+
const browser2 = record.executablePath ? path2.basename(record.executablePath).replace(/\.[A-Za-z0-9]+$/u, "") : void 0;
|
|
2197
|
+
return {
|
|
2198
|
+
provider: "local",
|
|
2199
|
+
status: "active",
|
|
2200
|
+
current,
|
|
2201
|
+
summary: "attached browser",
|
|
2202
|
+
detail: browser2 ?? record.engine,
|
|
2203
|
+
engine: record.engine,
|
|
2204
|
+
...browser2 === void 0 ? {} : { browser: browser2 }
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
if (!isProcessRunning(record.pid)) {
|
|
2077
2208
|
return {
|
|
2078
2209
|
provider: "local",
|
|
2079
2210
|
status: "idle",
|
|
@@ -2182,7 +2313,7 @@ async function handleViewCommand(parsed, options = {}) {
|
|
|
2182
2313
|
return;
|
|
2183
2314
|
}
|
|
2184
2315
|
if (subcommand !== void 0) {
|
|
2185
|
-
throw new
|
|
2316
|
+
throw new CliError("unknown_command", `Unknown view command: view ${subcommand}`);
|
|
2186
2317
|
}
|
|
2187
2318
|
if (parsed.options.localViewMode !== void 0) {
|
|
2188
2319
|
const preference = await setLocalViewMode(parsed.options.localViewMode);
|
|
@@ -2219,18 +2350,27 @@ async function resolveWorkspaceSessionId(input) {
|
|
|
2219
2350
|
workspace: input.workspace
|
|
2220
2351
|
});
|
|
2221
2352
|
const live = await readPersistedLocalBrowserSessionRecord(rootPath);
|
|
2222
|
-
if (!live
|
|
2353
|
+
if (!live) {
|
|
2354
|
+
return void 0;
|
|
2355
|
+
}
|
|
2356
|
+
if (getPersistedLocalBrowserSessionOwnership(live) === "attached") {
|
|
2357
|
+
if (!await isAttachedLocalBrowserSessionReachable(live)) {
|
|
2358
|
+
return void 0;
|
|
2359
|
+
}
|
|
2360
|
+
} else if (!isProcessRunning(live.pid)) {
|
|
2223
2361
|
return void 0;
|
|
2224
2362
|
}
|
|
2225
|
-
return
|
|
2363
|
+
return buildLocalViewSessionIdForRecord({
|
|
2226
2364
|
rootPath,
|
|
2227
|
-
|
|
2228
|
-
startedAt: live.startedAt
|
|
2365
|
+
live
|
|
2229
2366
|
});
|
|
2230
2367
|
}
|
|
2231
2368
|
function assertNoViewPreferenceFlag(parsed) {
|
|
2232
2369
|
if (parsed.options.localViewMode !== void 0) {
|
|
2233
|
-
throw new
|
|
2370
|
+
throw new CliError(
|
|
2371
|
+
"invalid_option",
|
|
2372
|
+
"View preference flags cannot be combined with this subcommand."
|
|
2373
|
+
);
|
|
2234
2374
|
}
|
|
2235
2375
|
}
|
|
2236
2376
|
function writeViewOutput(parsed, value) {
|
|
@@ -2315,10 +2455,10 @@ async function main() {
|
|
|
2315
2455
|
}
|
|
2316
2456
|
const operation = resolveOperation(parsed.command);
|
|
2317
2457
|
if (!operation) {
|
|
2318
|
-
throw new
|
|
2458
|
+
throw new CliError("unknown_command", `Unknown command: ${parsed.command.join(" ")}`);
|
|
2319
2459
|
}
|
|
2320
2460
|
if (parsed.options.workspace === void 0) {
|
|
2321
|
-
throw new
|
|
2461
|
+
throw new CliError("missing_workspace", 'Stateful commands require "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
2322
2462
|
}
|
|
2323
2463
|
const { engineName, provider, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
2324
2464
|
if (operation === "session.close") {
|
|
@@ -2340,28 +2480,43 @@ async function main() {
|
|
|
2340
2480
|
let renderOperation = operation;
|
|
2341
2481
|
try {
|
|
2342
2482
|
const input = await buildOperationInput(operation, parsed, runtime);
|
|
2343
|
-
|
|
2483
|
+
const rawResult = await dispatchSemanticOperation(runtime, operation, input);
|
|
2344
2484
|
if (parsed.command[0] === "tab" && operation !== "page.list") {
|
|
2345
2485
|
renderOperation = "page.list";
|
|
2346
2486
|
result = await runtime.listPages({});
|
|
2487
|
+
} else {
|
|
2488
|
+
result = rawResult;
|
|
2489
|
+
}
|
|
2490
|
+
let warning;
|
|
2491
|
+
if (result !== null && typeof result === "object" && "warning" in result) {
|
|
2492
|
+
const { warning: w, ...rest } = result;
|
|
2493
|
+
if (typeof w === "string") {
|
|
2494
|
+
warning = w;
|
|
2495
|
+
result = rest;
|
|
2496
|
+
}
|
|
2347
2497
|
}
|
|
2348
2498
|
process4.stdout.write(renderOperationOutput(renderOperation, result, input));
|
|
2499
|
+
if (warning !== void 0) {
|
|
2500
|
+
emitWarning(warning);
|
|
2501
|
+
}
|
|
2349
2502
|
} finally {
|
|
2350
2503
|
await runtime.disconnect().catch(() => void 0);
|
|
2351
2504
|
}
|
|
2352
2505
|
}
|
|
2353
2506
|
async function handleExecCommand(parsed) {
|
|
2354
2507
|
if (parsed.options.workspace === void 0) {
|
|
2355
|
-
throw new
|
|
2508
|
+
throw new CliError("missing_workspace", 'exec requires "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
2356
2509
|
}
|
|
2357
2510
|
const expression = parsed.rest.join(" ");
|
|
2358
2511
|
if (!expression) {
|
|
2359
|
-
throw new
|
|
2360
|
-
|
|
2512
|
+
throw new CliError(
|
|
2513
|
+
"missing_arguments",
|
|
2514
|
+
"exec requires an expression.",
|
|
2515
|
+
"opensteer exec <expression>"
|
|
2361
2516
|
);
|
|
2362
2517
|
}
|
|
2363
2518
|
const { engineName, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
2364
|
-
const { Opensteer } = await import('../opensteer-
|
|
2519
|
+
const { Opensteer } = await import('../opensteer-CY2QUJEG.js');
|
|
2365
2520
|
const opensteer = new Opensteer({
|
|
2366
2521
|
workspace: parsed.options.workspace,
|
|
2367
2522
|
rootDir: process4.cwd(),
|
|
@@ -2393,8 +2548,10 @@ async function handleBrowserCommand(parsed) {
|
|
|
2393
2548
|
if (subcommand === "inspect") {
|
|
2394
2549
|
const endpoint = parsed.options.attachEndpoint ?? parsed.rest[0];
|
|
2395
2550
|
if (!endpoint) {
|
|
2396
|
-
throw new
|
|
2397
|
-
|
|
2551
|
+
throw new CliError(
|
|
2552
|
+
"missing_arguments",
|
|
2553
|
+
'browser inspect requires "--attach-endpoint <url>" or a positional endpoint.',
|
|
2554
|
+
"opensteer browser inspect <endpoint>"
|
|
2398
2555
|
);
|
|
2399
2556
|
}
|
|
2400
2557
|
const result = await inspectCdpEndpoint({
|
|
@@ -2407,7 +2564,8 @@ async function handleBrowserCommand(parsed) {
|
|
|
2407
2564
|
return;
|
|
2408
2565
|
}
|
|
2409
2566
|
if (parsed.options.workspace === void 0) {
|
|
2410
|
-
throw new
|
|
2567
|
+
throw new CliError(
|
|
2568
|
+
"missing_workspace",
|
|
2411
2569
|
'Browser workspace commands require "--workspace <id>" or OPENSTEER_WORKSPACE.'
|
|
2412
2570
|
);
|
|
2413
2571
|
}
|
|
@@ -2430,7 +2588,11 @@ async function handleBrowserCommand(parsed) {
|
|
|
2430
2588
|
case "clone": {
|
|
2431
2589
|
const sourceUserDataDir = parsed.options.sourceUserDataDir;
|
|
2432
2590
|
if (!sourceUserDataDir) {
|
|
2433
|
-
throw new
|
|
2591
|
+
throw new CliError(
|
|
2592
|
+
"missing_arguments",
|
|
2593
|
+
'browser clone requires "--source-user-data-dir <path>".',
|
|
2594
|
+
"opensteer browser clone --source-user-data-dir <path>"
|
|
2595
|
+
);
|
|
2434
2596
|
}
|
|
2435
2597
|
const result = await manager.clonePersistentBrowser({
|
|
2436
2598
|
sourceUserDataDir,
|
|
@@ -2453,7 +2615,7 @@ async function handleBrowserCommand(parsed) {
|
|
|
2453
2615
|
return;
|
|
2454
2616
|
}
|
|
2455
2617
|
default:
|
|
2456
|
-
throw new
|
|
2618
|
+
throw new CliError("unknown_command", `Unknown browser command: ${parsed.command.join(" ")}`);
|
|
2457
2619
|
}
|
|
2458
2620
|
}
|
|
2459
2621
|
async function handleCloseCommand(parsed, engineName, providerMode, runtimeProvider) {
|
|
@@ -2486,23 +2648,27 @@ async function handleCloseCommand(parsed, engineName, providerMode, runtimeProvi
|
|
|
2486
2648
|
}
|
|
2487
2649
|
async function handleRecordCommandEntry(parsed) {
|
|
2488
2650
|
if (parsed.options.workspace === void 0) {
|
|
2489
|
-
throw new
|
|
2651
|
+
throw new CliError("missing_workspace", 'record requires "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
2490
2652
|
}
|
|
2491
2653
|
const url = parsed.options.url ?? parsed.rest[0];
|
|
2492
2654
|
if (url === void 0) {
|
|
2493
|
-
throw new
|
|
2655
|
+
throw new CliError(
|
|
2656
|
+
"missing_arguments",
|
|
2657
|
+
'record requires "--url <value>" or a positional URL.',
|
|
2658
|
+
"opensteer record --url <url> --workspace <id>"
|
|
2659
|
+
);
|
|
2494
2660
|
}
|
|
2495
2661
|
const provider = resolveCliProvider(parsed);
|
|
2496
2662
|
assertCloudCliOptionsMatchProvider(parsed, provider.mode);
|
|
2497
2663
|
const engineName = resolveCliEngineName(parsed);
|
|
2498
2664
|
if (engineName !== "playwright") {
|
|
2499
|
-
throw new
|
|
2665
|
+
throw new CliError("config_conflict", "record requires engine=playwright.");
|
|
2500
2666
|
}
|
|
2501
2667
|
const rootDir = process4.cwd();
|
|
2502
2668
|
const recordBrowser = parsed.options.browser;
|
|
2503
2669
|
if (provider.mode === "cloud") {
|
|
2504
2670
|
if (typeof recordBrowser === "object") {
|
|
2505
|
-
throw new
|
|
2671
|
+
throw new CliError("config_conflict", 'record does not support browser.mode="attach".');
|
|
2506
2672
|
}
|
|
2507
2673
|
const runtimeProvider = buildCliRuntimeProvider(parsed, provider.mode);
|
|
2508
2674
|
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
@@ -2522,10 +2688,10 @@ async function handleRecordCommandEntry(parsed) {
|
|
|
2522
2688
|
return;
|
|
2523
2689
|
}
|
|
2524
2690
|
if (parsed.options.launch?.headless === true) {
|
|
2525
|
-
throw new
|
|
2691
|
+
throw new CliError("config_conflict", 'record requires a headed browser. Remove "--headless true".');
|
|
2526
2692
|
}
|
|
2527
2693
|
if (typeof recordBrowser === "object") {
|
|
2528
|
-
throw new
|
|
2694
|
+
throw new CliError("config_conflict", 'record does not support browser.mode="attach".');
|
|
2529
2695
|
}
|
|
2530
2696
|
const launch = {
|
|
2531
2697
|
...parsed.options.launch ?? {},
|
|
@@ -2594,7 +2760,7 @@ function resolveCliBootstrapAction(argv) {
|
|
|
2594
2760
|
}
|
|
2595
2761
|
function buildCliBrowserProfile(parsed) {
|
|
2596
2762
|
if (parsed.options.cloudProfileReuseIfActive === true && parsed.options.cloudProfileId === void 0) {
|
|
2597
|
-
throw new
|
|
2763
|
+
throw new CliError("invalid_option", '"--cloud-profile-reuse-if-active" requires "--cloud-profile-id <id>".');
|
|
2598
2764
|
}
|
|
2599
2765
|
return parsed.options.cloudProfileId === void 0 ? void 0 : {
|
|
2600
2766
|
profileId: parsed.options.cloudProfileId,
|
|
@@ -2655,7 +2821,8 @@ function buildCliRuntimeProvider(parsed, providerMode) {
|
|
|
2655
2821
|
}
|
|
2656
2822
|
function assertCloudCliOptionsMatchProvider(parsed, providerMode) {
|
|
2657
2823
|
if (providerMode !== "cloud" && (parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || parsed.options.cloudAppBaseUrl !== void 0 || parsed.options.cloudProfileId !== void 0 || parsed.options.cloudProfileReuseIfActive === true)) {
|
|
2658
|
-
throw new
|
|
2824
|
+
throw new CliError(
|
|
2825
|
+
"config_conflict",
|
|
2659
2826
|
'Cloud-specific options require provider=cloud. Set "--provider cloud" or OPENSTEER_PROVIDER=cloud.'
|
|
2660
2827
|
);
|
|
2661
2828
|
}
|
|
@@ -2689,17 +2856,7 @@ function printVersion() {
|
|
|
2689
2856
|
`);
|
|
2690
2857
|
}
|
|
2691
2858
|
main().catch((error) => {
|
|
2692
|
-
const payload = error
|
|
2693
|
-
error: {
|
|
2694
|
-
name: error.name,
|
|
2695
|
-
message: error.message
|
|
2696
|
-
}
|
|
2697
|
-
} : {
|
|
2698
|
-
error: {
|
|
2699
|
-
name: "Error",
|
|
2700
|
-
message: String(error)
|
|
2701
|
-
}
|
|
2702
|
-
};
|
|
2859
|
+
const payload = formatCliErrorOutput(error);
|
|
2703
2860
|
process4.stderr.write(`${JSON.stringify(payload)}
|
|
2704
2861
|
`);
|
|
2705
2862
|
process4.exitCode = 1;
|