opensteer 0.8.14 → 0.8.16
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 +1 -1
- package/dist/{chunk-BRUJHMWO.js → chunk-KBO7DDPF.js} +233 -299
- package/dist/chunk-KBO7DDPF.js.map +1 -0
- package/dist/chunk-KCINASQC.js +3 -0
- package/dist/chunk-KCINASQC.js.map +1 -0
- package/dist/chunk-Y3ULLNOS.js +359 -0
- package/dist/chunk-Y3ULLNOS.js.map +1 -0
- package/dist/cli/bin.cjs +25883 -23428
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +133 -103
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +152 -205
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -39
- package/dist/index.d.ts +34 -39
- package/dist/index.js +3 -345
- package/dist/index.js.map +1 -1
- package/dist/opensteer-3Q3LR5XM.js +4 -0
- package/dist/opensteer-3Q3LR5XM.js.map +1 -0
- package/package.json +5 -5
- package/skills/opensteer/SKILL.md +76 -77
- package/dist/chunk-BRUJHMWO.js.map +0 -1
- package/skills/opensteer/references/cli-reference.md +0 -117
- package/skills/opensteer/references/request-workflow.md +0 -153
- package/skills/opensteer/references/sdk-reference.md +0 -158
package/dist/cli/bin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import '../chunk-KCINASQC.js';
|
|
3
|
+
import { createOpensteerSemanticRuntime, dispatchSemanticOperation, loadEnvironment, normalizeOpensteerProviderMode, discoverLocalCdpBrowsers, inspectCdpEndpoint, OpensteerBrowserManager, resolveOpensteerRuntimeConfig, assertProviderSupportsEngine, resolveOpensteerEngineName, resolveOpensteerProvider, resolveFilesystemWorkspacePath, requireCloudAppBaseUrl, CloudSessionProxy, FlowRecorderCollector, generateReplayScript, pathExists, readPersistedLocalBrowserSessionRecord, readPersistedCloudSessionRecord, OpensteerCloudClient, isProcessRunning } from '../chunk-KBO7DDPF.js';
|
|
3
4
|
import process4 from 'process';
|
|
4
5
|
import { mkdir, writeFile } from 'fs/promises';
|
|
5
6
|
import path2 from 'path';
|
|
@@ -11,7 +12,7 @@ import { fileURLToPath } from 'url';
|
|
|
11
12
|
|
|
12
13
|
// package.json
|
|
13
14
|
var package_default = {
|
|
14
|
-
version: "0.8.
|
|
15
|
+
version: "0.8.16"};
|
|
15
16
|
|
|
16
17
|
// src/cli/env-loader.ts
|
|
17
18
|
async function loadCliEnvironment(cwd) {
|
|
@@ -32,11 +33,11 @@ Navigation:
|
|
|
32
33
|
|
|
33
34
|
DOM:
|
|
34
35
|
snapshot [action|extraction]
|
|
35
|
-
click <element> [--button left|middle|right] [--persist <
|
|
36
|
-
hover <element> [--persist <
|
|
37
|
-
input <element> <text> [--press-enter] [--persist <
|
|
38
|
-
scroll <direction> <amount> [--element <n>] [--persist <
|
|
39
|
-
extract <schema> [--persist <
|
|
36
|
+
click <element> [--button left|middle|right] [--persist <key>] [--capture-network <label>]
|
|
37
|
+
hover <element> [--persist <key>] [--capture-network <label>]
|
|
38
|
+
input <element> <text> [--press-enter] [--persist <key>] [--capture-network <label>]
|
|
39
|
+
scroll <direction> <amount> [--element <n>] [--persist <key>] [--capture-network <label>]
|
|
40
|
+
extract <schema> [--persist <key>]
|
|
40
41
|
evaluate <script>
|
|
41
42
|
init-script <script>
|
|
42
43
|
|
|
@@ -49,15 +50,15 @@ Tabs:
|
|
|
49
50
|
Network:
|
|
50
51
|
network query [--capture <label>] [--url <pattern>] [--hostname <host>] [--path <path>] [--method <m>] [--status <code>] [--type <resourceType>] [--json] [--before <id>] [--after <id>] [--limit <n>]
|
|
51
52
|
--json filters to JSON and GraphQL responses only
|
|
52
|
-
network detail <recordId>
|
|
53
|
-
replay <recordId> [--query key=value ...] [--header key=value ...] [--body <json>] [--variables <json>]
|
|
53
|
+
network detail <recordId> [--probe]
|
|
54
54
|
fetch <url> [--method <m>] [--header key=value ...] [--query key=value ...] [--body <json>] [--body-text <text>] [--transport auto|direct|matched-tls|page] [--cookies] [--follow-redirects]
|
|
55
55
|
|
|
56
56
|
Browser State:
|
|
57
|
-
cookies [domain]
|
|
58
|
-
storage [domain]
|
|
59
57
|
state [domain]
|
|
60
58
|
|
|
59
|
+
SDK:
|
|
60
|
+
exec <expression> Run JS with the Opensteer SDK as 'this'. Supports await.
|
|
61
|
+
|
|
61
62
|
Computer:
|
|
62
63
|
computer click <x> <y> [--button left|right|middle] [--count <n>] [--modifiers Shift,Control,Alt,Meta] [--capture-network <label>]
|
|
63
64
|
computer type <text> [--capture-network <label>]
|
|
@@ -106,10 +107,7 @@ var OPERATION_ALIASES = /* @__PURE__ */ new Map([
|
|
|
106
107
|
["tab close", "page.close"],
|
|
107
108
|
["network query", "network.query"],
|
|
108
109
|
["network detail", "network.detail"],
|
|
109
|
-
["replay", "network.replay"],
|
|
110
110
|
["fetch", "session.fetch"],
|
|
111
|
-
["cookies", "session.cookies"],
|
|
112
|
-
["storage", "session.storage"],
|
|
113
111
|
["state", "session.state"],
|
|
114
112
|
["computer click", "computer.execute"],
|
|
115
113
|
["computer type", "computer.execute"],
|
|
@@ -150,7 +148,7 @@ function resolveCommandLength(tokens) {
|
|
|
150
148
|
if (tokens[0] === "skills") {
|
|
151
149
|
return Math.min(tokens.length, 2);
|
|
152
150
|
}
|
|
153
|
-
if (tokens[0] === "status" || tokens[0] === "record") {
|
|
151
|
+
if (tokens[0] === "status" || tokens[0] === "record" || tokens[0] === "exec") {
|
|
154
152
|
return 1;
|
|
155
153
|
}
|
|
156
154
|
for (let length = Math.min(3, tokens.length); length >= 1; length -= 1) {
|
|
@@ -219,6 +217,7 @@ var CLI_OPTION_SPECS = {
|
|
|
219
217
|
transport: { kind: "value" },
|
|
220
218
|
cookies: { kind: "optional-value" },
|
|
221
219
|
"follow-redirects": { kind: "boolean" },
|
|
220
|
+
probe: { kind: "boolean" },
|
|
222
221
|
"api-key": { kind: "value" },
|
|
223
222
|
"site-key": { kind: "value" },
|
|
224
223
|
"page-url": { kind: "value" },
|
|
@@ -334,7 +333,10 @@ function parseCommandLine(argv) {
|
|
|
334
333
|
const cloudApiKey = readSingle(rawOptions, "cloud-api-key");
|
|
335
334
|
const cloudAppBaseUrl = readSingle(rawOptions, "cloud-app-base-url");
|
|
336
335
|
const cloudProfileId = readSingle(rawOptions, "cloud-profile-id");
|
|
337
|
-
const cloudProfileReuseIfActive = readOptionalBoolean(
|
|
336
|
+
const cloudProfileReuseIfActive = readOptionalBoolean(
|
|
337
|
+
rawOptions,
|
|
338
|
+
"cloud-profile-reuse-if-active"
|
|
339
|
+
);
|
|
338
340
|
const json = readOptionalBoolean(rawOptions, "json");
|
|
339
341
|
const agents = rawOptions.get("agent");
|
|
340
342
|
const skills = rawOptions.get("skill");
|
|
@@ -556,7 +558,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
556
558
|
const direction = readSingleDirection(parsed.rest[0]);
|
|
557
559
|
const amount = readRequiredPositiveInteger(parsed.rest[1], "scroll requires an amount.");
|
|
558
560
|
const element = readOptionalNumber(parsed.rawOptions, "element");
|
|
559
|
-
const persist =
|
|
561
|
+
const persist = readPersistKey(parsed, "scroll");
|
|
560
562
|
const captureNetwork = readSingle(parsed.rawOptions, "capture-network");
|
|
561
563
|
return {
|
|
562
564
|
target: element === void 0 ? {
|
|
@@ -576,7 +578,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
576
578
|
if (parsed.rest[0] === void 0) {
|
|
577
579
|
throw new Error("extract requires a schema.");
|
|
578
580
|
}
|
|
579
|
-
const persist =
|
|
581
|
+
const persist = readExtractPersistKey(parsed);
|
|
580
582
|
return {
|
|
581
583
|
schema: parseRequiredJsonObjectArgument(joinRest(parsed.rest, 0), "extract schema"),
|
|
582
584
|
...persist === void 0 ? {} : { persist }
|
|
@@ -608,27 +610,14 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
608
610
|
...limit === void 0 ? {} : { limit }
|
|
609
611
|
};
|
|
610
612
|
}
|
|
611
|
-
case "network.detail":
|
|
613
|
+
case "network.detail": {
|
|
612
614
|
if (parsed.rest[0] === void 0) {
|
|
613
615
|
throw new Error("network detail requires a record id.");
|
|
614
616
|
}
|
|
615
|
-
|
|
616
|
-
recordId: parsed.rest[0]
|
|
617
|
-
};
|
|
618
|
-
case "network.replay": {
|
|
619
|
-
if (parsed.rest[0] === void 0) {
|
|
620
|
-
throw new Error("replay requires a record id.");
|
|
621
|
-
}
|
|
622
|
-
const query = parseKeyValueList(parsed.rawOptions.get("query"));
|
|
623
|
-
const headers = parseKeyValueList(parsed.rawOptions.get("header"));
|
|
624
|
-
const bodyJson = readJsonValue(parsed.rawOptions, "body");
|
|
625
|
-
const variables = readJsonObject(parsed.rawOptions, "variables");
|
|
617
|
+
const probeFlag = readOptionalBoolean(parsed.rawOptions, "probe");
|
|
626
618
|
return {
|
|
627
619
|
recordId: parsed.rest[0],
|
|
628
|
-
...
|
|
629
|
-
...headers === void 0 ? {} : { headers },
|
|
630
|
-
...bodyJson === void 0 ? {} : { body: { json: bodyJson } },
|
|
631
|
-
...variables === void 0 ? {} : { variables }
|
|
620
|
+
...probeFlag === void 0 ? {} : { probe: probeFlag }
|
|
632
621
|
};
|
|
633
622
|
}
|
|
634
623
|
case "session.fetch": {
|
|
@@ -795,7 +784,7 @@ function buildElementTargetInput(parsed, verb) {
|
|
|
795
784
|
parsed.rest[0],
|
|
796
785
|
`${verb} requires an element number.`
|
|
797
786
|
);
|
|
798
|
-
const persist =
|
|
787
|
+
const persist = readPersistKey(parsed, verb);
|
|
799
788
|
const captureNetwork = readSingle(parsed.rawOptions, "capture-network");
|
|
800
789
|
return {
|
|
801
790
|
target: {
|
|
@@ -968,9 +957,7 @@ function readCaptchaProvider(value) {
|
|
|
968
957
|
}
|
|
969
958
|
function readCaptchaType(value) {
|
|
970
959
|
if (value === void 0 || !CAPTCHA_TYPES.has(value)) {
|
|
971
|
-
throw new Error(
|
|
972
|
-
'Expected "--type" to be one of: recaptcha-v2, hcaptcha, turnstile.'
|
|
973
|
-
);
|
|
960
|
+
throw new Error('Expected "--type" to be one of: recaptcha-v2, hcaptcha, turnstile.');
|
|
974
961
|
}
|
|
975
962
|
return value;
|
|
976
963
|
}
|
|
@@ -1004,26 +991,26 @@ function readKeyModifiers(value) {
|
|
|
1004
991
|
}
|
|
1005
992
|
return [...new Set(modifiers)];
|
|
1006
993
|
}
|
|
1007
|
-
function
|
|
994
|
+
function readPersistKey(parsed, verb) {
|
|
1008
995
|
const value = readSingle(parsed.rawOptions, "persist");
|
|
1009
996
|
if (value === void 0) {
|
|
1010
997
|
return void 0;
|
|
1011
998
|
}
|
|
1012
999
|
if (value === "true" || value === "false") {
|
|
1013
|
-
throw new Error(`${verb} requires "--persist <
|
|
1000
|
+
throw new Error(`${verb} requires "--persist <key>" when using --persist.`);
|
|
1014
1001
|
}
|
|
1015
1002
|
if (verb === "scroll" && readOptionalNumber(parsed.rawOptions, "element") === void 0) {
|
|
1016
|
-
throw new Error('scroll requires "--element <n>" when using "--persist <
|
|
1003
|
+
throw new Error('scroll requires "--element <n>" when using "--persist <key>".');
|
|
1017
1004
|
}
|
|
1018
1005
|
return value;
|
|
1019
1006
|
}
|
|
1020
|
-
function
|
|
1007
|
+
function readExtractPersistKey(parsed) {
|
|
1021
1008
|
const value = readSingle(parsed.rawOptions, "persist");
|
|
1022
1009
|
if (value === void 0) {
|
|
1023
1010
|
return void 0;
|
|
1024
1011
|
}
|
|
1025
1012
|
if (value === "true" || value === "false") {
|
|
1026
|
-
throw new Error('extract requires "--persist <
|
|
1013
|
+
throw new Error('extract requires "--persist <key>" when using --persist.');
|
|
1027
1014
|
}
|
|
1028
1015
|
return value;
|
|
1029
1016
|
}
|
|
@@ -1062,13 +1049,8 @@ function renderOperationOutput(operation, result, input) {
|
|
|
1062
1049
|
return formatNetworkQueryOutput(result, input);
|
|
1063
1050
|
case "network.detail":
|
|
1064
1051
|
return formatNetworkDetailOutput(result);
|
|
1065
|
-
case "network.replay":
|
|
1066
1052
|
case "session.fetch":
|
|
1067
|
-
return renderJson(formatTransportOutput(result
|
|
1068
|
-
case "session.cookies":
|
|
1069
|
-
return formatCookiesOutput(result);
|
|
1070
|
-
case "session.storage":
|
|
1071
|
-
return formatStorageOutput(result);
|
|
1053
|
+
return renderJson(formatTransportOutput(result));
|
|
1072
1054
|
case "session.state":
|
|
1073
1055
|
return formatStateOutput(result);
|
|
1074
1056
|
case "computer.execute":
|
|
@@ -1120,9 +1102,9 @@ function formatActionOutput(result, input) {
|
|
|
1120
1102
|
...readNumberField(point, "y") === void 0 ? {} : { y: readNumberField(point, "y") }
|
|
1121
1103
|
};
|
|
1122
1104
|
}
|
|
1123
|
-
const
|
|
1124
|
-
if (
|
|
1125
|
-
output.
|
|
1105
|
+
const persist = readStringField(target, "persist");
|
|
1106
|
+
if (persist !== void 0) {
|
|
1107
|
+
output.persist = persist;
|
|
1126
1108
|
}
|
|
1127
1109
|
const text = readStringField(input, "text");
|
|
1128
1110
|
if (text !== void 0) {
|
|
@@ -1240,7 +1222,10 @@ function formatNetworkDetailOutput(result) {
|
|
|
1240
1222
|
}
|
|
1241
1223
|
const redirectChain = readArrayField(result, "redirectChain");
|
|
1242
1224
|
if (redirectChain.length > 0) {
|
|
1243
|
-
lines.push(
|
|
1225
|
+
lines.push(
|
|
1226
|
+
"",
|
|
1227
|
+
`Redirect chain (${redirectChain.length} hop${redirectChain.length === 1 ? "" : "s"}):`
|
|
1228
|
+
);
|
|
1244
1229
|
redirectChain.forEach((hop, index) => {
|
|
1245
1230
|
const location = readStringField(hop, "location");
|
|
1246
1231
|
lines.push(
|
|
@@ -1248,6 +1233,32 @@ function formatNetworkDetailOutput(result) {
|
|
|
1248
1233
|
);
|
|
1249
1234
|
});
|
|
1250
1235
|
}
|
|
1236
|
+
const transportProbe = readObjectField(result, "transportProbe");
|
|
1237
|
+
if (transportProbe !== void 0) {
|
|
1238
|
+
const recommended = readStringField(transportProbe, "recommended");
|
|
1239
|
+
const probeAttempts = readArrayField(transportProbe, "attempts");
|
|
1240
|
+
lines.push(
|
|
1241
|
+
"",
|
|
1242
|
+
`Transport probe${recommended === void 0 ? "" : ` (recommended: ${recommended})`}:`
|
|
1243
|
+
);
|
|
1244
|
+
for (const attempt of probeAttempts) {
|
|
1245
|
+
const transport = readStringField(attempt, "transport") ?? "?";
|
|
1246
|
+
const ok = readBooleanField(attempt, "ok") === true;
|
|
1247
|
+
const status = readNumberField(attempt, "status");
|
|
1248
|
+
const durationMs = readNumberField(attempt, "durationMs");
|
|
1249
|
+
const error = readStringField(attempt, "error");
|
|
1250
|
+
const marker = ok ? "ok" : "fail";
|
|
1251
|
+
lines.push(
|
|
1252
|
+
` ${transport}: ${marker}${status === void 0 ? "" : ` ${String(status)}`}${durationMs === void 0 ? "" : ` (${String(durationMs)}ms)`}${error === void 0 ? "" : ` - ${error}`}`
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
if (recommended !== void 0) {
|
|
1256
|
+
const summary2 = readObjectField(result, "summary");
|
|
1257
|
+
const method = readStringField(summary2, "method") ?? "GET";
|
|
1258
|
+
const url = readStringField(summary2, "url") ?? "";
|
|
1259
|
+
lines.push("", `-> SDK: await this.fetch("${url}", { method: "${method}" })`);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1251
1262
|
const notes = readArrayField(result, "notes").map((entry) => typeof entry === "string" ? entry : void 0).filter((entry) => entry !== void 0);
|
|
1252
1263
|
if (notes.length > 0) {
|
|
1253
1264
|
lines.push("", ...notes.map((note) => `Note: ${note}`));
|
|
@@ -1270,7 +1281,6 @@ function formatTransportOutput(result, operation) {
|
|
|
1270
1281
|
const body = readObjectField(response, "body");
|
|
1271
1282
|
const bodySize = body === void 0 ? void 0 : readNumberField(body, "originalByteLength") ?? readNumberField(body, "capturedByteLength");
|
|
1272
1283
|
const output = {
|
|
1273
|
-
...operation === "network.replay" && readStringField(result, "recordId") !== void 0 ? { recordId: readStringField(result, "recordId") } : {},
|
|
1274
1284
|
...readStringField(result, "transport") === void 0 ? {} : { transport: readStringField(result, "transport") },
|
|
1275
1285
|
...response === void 0 ? {} : { status: readNumberField(response, "status") },
|
|
1276
1286
|
...contentType === void 0 ? {} : { contentType },
|
|
@@ -1292,45 +1302,6 @@ function formatTransportOutput(result, operation) {
|
|
|
1292
1302
|
}
|
|
1293
1303
|
return output;
|
|
1294
1304
|
}
|
|
1295
|
-
function formatCookiesOutput(result) {
|
|
1296
|
-
if (result === null || typeof result !== "object") {
|
|
1297
|
-
return renderJson(result);
|
|
1298
|
-
}
|
|
1299
|
-
const cookies = readArrayField(result, "cookies");
|
|
1300
|
-
const domain = readStringField(result, "domain");
|
|
1301
|
-
const lines = [`[cookies] ${cookies.length} cookie${cookies.length === 1 ? "" : "s"}${domain === void 0 ? "" : ` for ${domain}`}`];
|
|
1302
|
-
for (const cookie of cookies) {
|
|
1303
|
-
const flags = [
|
|
1304
|
-
readBooleanField(cookie, "session") === true ? "session" : void 0,
|
|
1305
|
-
readBooleanField(cookie, "httpOnly") === true ? "httpOnly" : void 0,
|
|
1306
|
-
readBooleanField(cookie, "secure") === true ? "secure" : void 0,
|
|
1307
|
-
readStringField(cookie, "expiresAt")
|
|
1308
|
-
].filter((value) => value !== void 0);
|
|
1309
|
-
lines.push(
|
|
1310
|
-
` ${padRight(readStringField(cookie, "name") ?? "cookie", 20)} ${truncateInline(readStringField(cookie, "value") ?? "", 48)}${flags.length === 0 ? "" : ` ${flags.join(" ")}`}`
|
|
1311
|
-
);
|
|
1312
|
-
}
|
|
1313
|
-
return `${lines.join("\n")}
|
|
1314
|
-
`;
|
|
1315
|
-
}
|
|
1316
|
-
function formatStorageOutput(result) {
|
|
1317
|
-
if (result === null || typeof result !== "object") {
|
|
1318
|
-
return renderJson(result);
|
|
1319
|
-
}
|
|
1320
|
-
const domains = readArrayField(result, "domains");
|
|
1321
|
-
const lines = [];
|
|
1322
|
-
for (const domain of domains) {
|
|
1323
|
-
const domainName = readStringField(domain, "domain") ?? "unknown";
|
|
1324
|
-
const localStorage = readArrayField(domain, "localStorage");
|
|
1325
|
-
const sessionStorage = readArrayField(domain, "sessionStorage");
|
|
1326
|
-
lines.push(`[storage] localStorage for ${domainName} (${localStorage.length} key${localStorage.length === 1 ? "" : "s"})`, "");
|
|
1327
|
-
lines.push(...localStorage.map((entry) => formatStorageEntry(entry)));
|
|
1328
|
-
lines.push("", `[storage] sessionStorage for ${domainName} (${sessionStorage.length} key${sessionStorage.length === 1 ? "" : "s"})`, "");
|
|
1329
|
-
lines.push(...sessionStorage.map((entry) => formatStorageEntry(entry)), "");
|
|
1330
|
-
}
|
|
1331
|
-
return `${lines.join("\n").trimEnd()}
|
|
1332
|
-
`;
|
|
1333
|
-
}
|
|
1334
1305
|
function formatStateOutput(result) {
|
|
1335
1306
|
if (result === null || typeof result !== "object") {
|
|
1336
1307
|
return renderJson(result);
|
|
@@ -1355,10 +1326,16 @@ function formatStateOutput(result) {
|
|
|
1355
1326
|
)
|
|
1356
1327
|
);
|
|
1357
1328
|
const localStorage = readArrayField(domain, "localStorage");
|
|
1358
|
-
lines.push(
|
|
1329
|
+
lines.push(
|
|
1330
|
+
"",
|
|
1331
|
+
`localStorage (${localStorage.length} key${localStorage.length === 1 ? "" : "s"}):`
|
|
1332
|
+
);
|
|
1359
1333
|
lines.push(...localStorage.map((entry) => formatStorageEntry(entry)));
|
|
1360
1334
|
const sessionStorage = readArrayField(domain, "sessionStorage");
|
|
1361
|
-
lines.push(
|
|
1335
|
+
lines.push(
|
|
1336
|
+
"",
|
|
1337
|
+
`sessionStorage (${sessionStorage.length} key${sessionStorage.length === 1 ? "" : "s"}):`
|
|
1338
|
+
);
|
|
1362
1339
|
lines.push(...sessionStorage.map((entry) => formatStorageEntry(entry)));
|
|
1363
1340
|
const globals = readObjectField(domain, "globals");
|
|
1364
1341
|
if (globals !== void 0) {
|
|
@@ -2154,6 +2131,19 @@ function formatLaneRow(input) {
|
|
|
2154
2131
|
return `${input.marker} ${provider} ${status} ${summary}${input.detail ?? ""}`.trimEnd();
|
|
2155
2132
|
}
|
|
2156
2133
|
|
|
2134
|
+
// src/cli/exec.ts
|
|
2135
|
+
async function runExecExpression(context, expression) {
|
|
2136
|
+
const AsyncFunction = Object.getPrototypeOf(async function() {
|
|
2137
|
+
}).constructor;
|
|
2138
|
+
let fn;
|
|
2139
|
+
try {
|
|
2140
|
+
fn = new AsyncFunction(`return (${expression})`);
|
|
2141
|
+
} catch {
|
|
2142
|
+
fn = new AsyncFunction(expression);
|
|
2143
|
+
}
|
|
2144
|
+
return fn.call(context);
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2157
2147
|
// src/cli/bin.ts
|
|
2158
2148
|
var emitProcessWarning = process4.emitWarning.bind(process4);
|
|
2159
2149
|
process4.emitWarning = ((warning, ...args) => {
|
|
@@ -2204,20 +2194,18 @@ async function main() {
|
|
|
2204
2194
|
await handleRecordCommandEntry(parsed);
|
|
2205
2195
|
return;
|
|
2206
2196
|
}
|
|
2197
|
+
if (parsed.command[0] === "exec") {
|
|
2198
|
+
await handleExecCommand(parsed);
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2207
2201
|
const operation = resolveOperation(parsed.command);
|
|
2208
2202
|
if (!operation) {
|
|
2209
2203
|
throw new Error(`Unknown command: ${parsed.command.join(" ")}`);
|
|
2210
2204
|
}
|
|
2211
2205
|
if (parsed.options.workspace === void 0) {
|
|
2212
|
-
throw new Error(
|
|
2213
|
-
'Stateful commands require "--workspace <id>" or OPENSTEER_WORKSPACE.'
|
|
2214
|
-
);
|
|
2206
|
+
throw new Error('Stateful commands require "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
2215
2207
|
}
|
|
2216
|
-
const engineName =
|
|
2217
|
-
const provider = resolveCliProvider(parsed);
|
|
2218
|
-
assertProviderSupportsEngine(provider.mode, engineName);
|
|
2219
|
-
assertCloudCliOptionsMatchProvider(parsed, provider.mode);
|
|
2220
|
-
const runtimeProvider = buildCliRuntimeProvider(parsed, provider.mode);
|
|
2208
|
+
const { engineName, provider, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
2221
2209
|
if (operation === "session.close") {
|
|
2222
2210
|
await handleCloseCommand(parsed, engineName, provider.mode, runtimeProvider);
|
|
2223
2211
|
return;
|
|
@@ -2247,6 +2235,36 @@ async function main() {
|
|
|
2247
2235
|
await runtime.disconnect().catch(() => void 0);
|
|
2248
2236
|
}
|
|
2249
2237
|
}
|
|
2238
|
+
async function handleExecCommand(parsed) {
|
|
2239
|
+
if (parsed.options.workspace === void 0) {
|
|
2240
|
+
throw new Error('exec requires "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
2241
|
+
}
|
|
2242
|
+
const expression = parsed.rest.join(" ");
|
|
2243
|
+
if (!expression) {
|
|
2244
|
+
throw new Error(
|
|
2245
|
+
`exec requires an expression. Example: exec "await this.evaluate('document.title')"`
|
|
2246
|
+
);
|
|
2247
|
+
}
|
|
2248
|
+
const { engineName, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
2249
|
+
const { Opensteer } = await import('../opensteer-3Q3LR5XM.js');
|
|
2250
|
+
const opensteer = new Opensteer({
|
|
2251
|
+
workspace: parsed.options.workspace,
|
|
2252
|
+
rootDir: process4.cwd(),
|
|
2253
|
+
...runtimeProvider === void 0 ? {} : { provider: runtimeProvider },
|
|
2254
|
+
engineName,
|
|
2255
|
+
...parsed.options.browser === void 0 ? {} : { browser: parsed.options.browser },
|
|
2256
|
+
...parsed.options.launch === void 0 ? {} : { launch: parsed.options.launch },
|
|
2257
|
+
...parsed.options.context === void 0 ? {} : { context: parsed.options.context }
|
|
2258
|
+
});
|
|
2259
|
+
try {
|
|
2260
|
+
const result = await runExecExpression(opensteer, expression);
|
|
2261
|
+
if (result !== void 0) {
|
|
2262
|
+
process4.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
2263
|
+
}
|
|
2264
|
+
} finally {
|
|
2265
|
+
await opensteer.disconnect().catch(() => void 0);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2250
2268
|
async function handleBrowserCommand(parsed) {
|
|
2251
2269
|
const subcommand = parsed.command[1];
|
|
2252
2270
|
if (subcommand === "discover") {
|
|
@@ -2477,6 +2495,18 @@ function buildCliExplicitProvider(parsed) {
|
|
|
2477
2495
|
}
|
|
2478
2496
|
return void 0;
|
|
2479
2497
|
}
|
|
2498
|
+
function resolveCliRuntimeSelection(parsed) {
|
|
2499
|
+
const engineName = resolveCliEngineName(parsed);
|
|
2500
|
+
const provider = resolveCliProvider(parsed);
|
|
2501
|
+
assertProviderSupportsEngine(provider.mode, engineName);
|
|
2502
|
+
assertCloudCliOptionsMatchProvider(parsed, provider.mode);
|
|
2503
|
+
const runtimeProvider = buildCliRuntimeProvider(parsed, provider.mode);
|
|
2504
|
+
return {
|
|
2505
|
+
engineName,
|
|
2506
|
+
provider,
|
|
2507
|
+
runtimeProvider
|
|
2508
|
+
};
|
|
2509
|
+
}
|
|
2480
2510
|
function resolveCliEngineName(parsed) {
|
|
2481
2511
|
return resolveOpensteerEngineName({
|
|
2482
2512
|
...parsed.options.requestedEngineName === void 0 ? {} : { requested: parsed.options.requestedEngineName },
|