opensteer 0.9.5 → 0.9.6
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-ZRF7WMS3.js → chunk-3I3A5OLB.js} +3 -3
- package/dist/{chunk-ZRF7WMS3.js.map → chunk-3I3A5OLB.js.map} +1 -1
- package/dist/{chunk-GSCQQKZZ.js → chunk-3XBQRZZC.js} +221 -6
- package/dist/chunk-3XBQRZZC.js.map +1 -0
- package/dist/{chunk-7LQL5YUR.js → chunk-BVRIPCWA.js} +259 -277
- package/dist/chunk-BVRIPCWA.js.map +1 -0
- package/dist/chunk-L4NF74KI.js +458 -0
- package/dist/chunk-L4NF74KI.js.map +1 -0
- package/dist/cli/bin.cjs +760 -282
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +225 -84
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +527 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -3
- package/dist/index.d.ts +32 -3
- package/dist/index.js +3 -3
- package/dist/local-view/serve-entry.cjs +5354 -4
- package/dist/local-view/serve-entry.cjs.map +1 -1
- package/dist/local-view/serve-entry.js +1 -1
- package/dist/opensteer-UGA6YBRN.js +6 -0
- package/dist/{opensteer-T2JENADR.js.map → opensteer-UGA6YBRN.js.map} +1 -1
- package/dist/{session-control-M3JD7ZKA.js → session-control-U3L5H2ZI.js} +3 -3
- package/dist/{session-control-M3JD7ZKA.js.map → session-control-U3L5H2ZI.js.map} +1 -1
- package/package.json +6 -6
- 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/opensteer-T2JENADR.js +0 -6
package/dist/cli/bin.cjs
CHANGED
|
@@ -2598,10 +2598,8 @@ var init_cdp_dom_snapshot = __esm({
|
|
|
2598
2598
|
});
|
|
2599
2599
|
|
|
2600
2600
|
// ../browser-core/src/cdp-visual-stability.ts
|
|
2601
|
-
var DEFAULT_VISUAL_STABILITY_SETTLE_MS;
|
|
2602
2601
|
var init_cdp_visual_stability = __esm({
|
|
2603
2602
|
"../browser-core/src/cdp-visual-stability.ts"() {
|
|
2604
|
-
DEFAULT_VISUAL_STABILITY_SETTLE_MS = 750;
|
|
2605
2603
|
}
|
|
2606
2604
|
});
|
|
2607
2605
|
|
|
@@ -10413,7 +10411,8 @@ function normalizeOpensteerEngineName(value, source = "engine") {
|
|
|
10413
10411
|
if (normalized === "playwright" || normalized === "abp") {
|
|
10414
10412
|
return normalized;
|
|
10415
10413
|
}
|
|
10416
|
-
throw new
|
|
10414
|
+
throw new OpensteerProtocolError(
|
|
10415
|
+
"invalid-argument",
|
|
10417
10416
|
`${source} must be one of ${OPENSTEER_ENGINE_NAMES.join(", ")}; received "${value}".`
|
|
10418
10417
|
);
|
|
10419
10418
|
}
|
|
@@ -10422,7 +10421,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
10422
10421
|
return;
|
|
10423
10422
|
}
|
|
10424
10423
|
if (typeof input.browser === "object" && input.browser !== null && input.browser.mode === "attach") {
|
|
10425
|
-
throw new
|
|
10424
|
+
throw new OpensteerProtocolError(
|
|
10425
|
+
"invalid-argument",
|
|
10426
10426
|
'ABP engine does not support browser.mode="attach". Use the Playwright engine for attach flows.'
|
|
10427
10427
|
);
|
|
10428
10428
|
}
|
|
@@ -10430,7 +10430,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
10430
10430
|
if (unsupportedContextOptionNames.length === 0) {
|
|
10431
10431
|
return;
|
|
10432
10432
|
}
|
|
10433
|
-
throw new
|
|
10433
|
+
throw new OpensteerProtocolError(
|
|
10434
|
+
"invalid-argument",
|
|
10434
10435
|
`ABP engine does not support ${unsupportedContextOptionNames.join(", ")}. Supported ABP context options: context.viewport.`
|
|
10435
10436
|
);
|
|
10436
10437
|
}
|
|
@@ -10488,6 +10489,7 @@ function stripWindowSizeArgs(args) {
|
|
|
10488
10489
|
var OPENSTEER_ENGINE_NAMES, DEFAULT_OPENSTEER_ENGINE;
|
|
10489
10490
|
var init_engine_selection = __esm({
|
|
10490
10491
|
"../runtime-core/src/internal/engine-selection.ts"() {
|
|
10492
|
+
init_src2();
|
|
10491
10493
|
OPENSTEER_ENGINE_NAMES = ["playwright", "abp"];
|
|
10492
10494
|
DEFAULT_OPENSTEER_ENGINE = "playwright";
|
|
10493
10495
|
}
|
|
@@ -11472,7 +11474,8 @@ function assertProviderSupportsEngine(provider, engine) {
|
|
|
11472
11474
|
return;
|
|
11473
11475
|
}
|
|
11474
11476
|
if (provider === "cloud") {
|
|
11475
|
-
throw new
|
|
11477
|
+
throw new OpensteerProtocolError(
|
|
11478
|
+
"invalid-argument",
|
|
11476
11479
|
"ABP is not supported for provider=cloud. Cloud provider currently requires Playwright."
|
|
11477
11480
|
);
|
|
11478
11481
|
}
|
|
@@ -11482,7 +11485,8 @@ function normalizeOpensteerProviderMode(value, source = "OPENSTEER_PROVIDER") {
|
|
|
11482
11485
|
if (normalized === OPENSTEER_PROVIDER_MODES[0] || normalized === OPENSTEER_PROVIDER_MODES[1]) {
|
|
11483
11486
|
return normalized;
|
|
11484
11487
|
}
|
|
11485
|
-
throw new
|
|
11488
|
+
throw new OpensteerProtocolError(
|
|
11489
|
+
"invalid-argument",
|
|
11486
11490
|
`${source} must be one of ${OPENSTEER_PROVIDER_MODES.join(", ")}; received "${value}".`
|
|
11487
11491
|
);
|
|
11488
11492
|
}
|
|
@@ -11507,6 +11511,7 @@ function resolveOpensteerProvider(input = {}) {
|
|
|
11507
11511
|
var OPENSTEER_PROVIDER_MODES;
|
|
11508
11512
|
var init_config = __esm({
|
|
11509
11513
|
"src/provider/config.ts"() {
|
|
11514
|
+
init_src2();
|
|
11510
11515
|
OPENSTEER_PROVIDER_MODES = ["local", "cloud"];
|
|
11511
11516
|
}
|
|
11512
11517
|
});
|
|
@@ -11968,12 +11973,60 @@ function wrapCloudFetchError(error, input) {
|
|
|
11968
11973
|
wrapped.name = error.name;
|
|
11969
11974
|
return wrapped;
|
|
11970
11975
|
}
|
|
11971
|
-
|
|
11976
|
+
async function createCloudRequestError(response, input) {
|
|
11977
|
+
const payload = await readCloudErrorPayload(response);
|
|
11978
|
+
return new OpensteerCloudRequestError({
|
|
11979
|
+
statusCode: response.status,
|
|
11980
|
+
method: input.method,
|
|
11981
|
+
pathname: input.pathname,
|
|
11982
|
+
url: input.url,
|
|
11983
|
+
message: payload?.error ?? `${input.method} ${input.pathname} failed with ${String(response.status)}.`,
|
|
11984
|
+
...payload?.code === void 0 ? {} : { code: payload.code },
|
|
11985
|
+
...payload?.details === void 0 ? {} : { details: payload.details }
|
|
11986
|
+
});
|
|
11987
|
+
}
|
|
11988
|
+
async function readCloudErrorPayload(response) {
|
|
11989
|
+
try {
|
|
11990
|
+
return asCloudErrorPayload(await response.json());
|
|
11991
|
+
} catch {
|
|
11992
|
+
return void 0;
|
|
11993
|
+
}
|
|
11994
|
+
}
|
|
11995
|
+
function asCloudErrorPayload(value) {
|
|
11996
|
+
if (value === null || typeof value !== "object") {
|
|
11997
|
+
return void 0;
|
|
11998
|
+
}
|
|
11999
|
+
const payload = value;
|
|
12000
|
+
return {
|
|
12001
|
+
...typeof payload.error === "string" ? { error: payload.error } : {},
|
|
12002
|
+
...typeof payload.code === "string" ? { code: payload.code } : {},
|
|
12003
|
+
..."details" in payload ? { details: payload.details } : {}
|
|
12004
|
+
};
|
|
12005
|
+
}
|
|
12006
|
+
var CLOUD_CLOSE_TIMEOUT_MS, CLOUD_CLOSE_POLL_INTERVAL_MS, OpensteerCloudRequestError, OpensteerCloudClient;
|
|
11972
12007
|
var init_client = __esm({
|
|
11973
12008
|
"src/cloud/client.ts"() {
|
|
11974
12009
|
init_profile_sync();
|
|
11975
12010
|
CLOUD_CLOSE_TIMEOUT_MS = 6e4;
|
|
11976
12011
|
CLOUD_CLOSE_POLL_INTERVAL_MS = 250;
|
|
12012
|
+
OpensteerCloudRequestError = class extends Error {
|
|
12013
|
+
statusCode;
|
|
12014
|
+
code;
|
|
12015
|
+
details;
|
|
12016
|
+
method;
|
|
12017
|
+
pathname;
|
|
12018
|
+
url;
|
|
12019
|
+
constructor(args) {
|
|
12020
|
+
super(args.message);
|
|
12021
|
+
this.name = "OpensteerCloudRequestError";
|
|
12022
|
+
this.statusCode = args.statusCode;
|
|
12023
|
+
this.code = args.code;
|
|
12024
|
+
this.details = args.details;
|
|
12025
|
+
this.method = args.method;
|
|
12026
|
+
this.pathname = args.pathname;
|
|
12027
|
+
this.url = args.url;
|
|
12028
|
+
}
|
|
12029
|
+
};
|
|
11977
12030
|
OpensteerCloudClient = class {
|
|
11978
12031
|
constructor(config) {
|
|
11979
12032
|
this.config = config;
|
|
@@ -12149,7 +12202,11 @@ var init_client = __esm({
|
|
|
12149
12202
|
});
|
|
12150
12203
|
}
|
|
12151
12204
|
if (!response.ok) {
|
|
12152
|
-
throw
|
|
12205
|
+
throw await createCloudRequestError(response, {
|
|
12206
|
+
method: init.method,
|
|
12207
|
+
pathname,
|
|
12208
|
+
url
|
|
12209
|
+
});
|
|
12153
12210
|
}
|
|
12154
12211
|
return response;
|
|
12155
12212
|
}
|
|
@@ -12220,7 +12277,7 @@ var init_package = __esm({
|
|
|
12220
12277
|
"../runtime-core/package.json"() {
|
|
12221
12278
|
package_default2 = {
|
|
12222
12279
|
name: "@opensteer/runtime-core",
|
|
12223
|
-
version: "0.2.
|
|
12280
|
+
version: "0.2.5",
|
|
12224
12281
|
description: "Shared semantic runtime for Opensteer local and cloud execution.",
|
|
12225
12282
|
license: "MIT",
|
|
12226
12283
|
type: "module",
|
|
@@ -12372,7 +12429,7 @@ var init_errors3 = __esm({
|
|
|
12372
12429
|
function defaultPolicy() {
|
|
12373
12430
|
return DEFAULT_POLICY;
|
|
12374
12431
|
}
|
|
12375
|
-
var DEFAULT_TIMEOUTS, DEFAULT_SETTLE_DELAYS,
|
|
12432
|
+
var DEFAULT_TIMEOUTS, DEFAULT_SETTLE_DELAYS, DOM_ACTION_VISUAL_STABILITY_PROFILES, DEFAULT_DOM_ACTION_VISUAL_STABILITY_PROFILE, NAVIGATION_VISUAL_STABILITY_PROFILE, NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, defaultDomActionSettleObserver, defaultNavigationSettleObserver, DEFAULT_SETTLE_OBSERVERS, defaultTimeoutPolicy, defaultSettlePolicy, defaultRetryPolicy, defaultFallbackPolicy, DEFAULT_POLICY;
|
|
12376
12433
|
var init_defaults = __esm({
|
|
12377
12434
|
"../runtime-core/src/policy/defaults.ts"() {
|
|
12378
12435
|
init_src();
|
|
@@ -12401,21 +12458,6 @@ var init_defaults = __esm({
|
|
|
12401
12458
|
"dom-action": 100,
|
|
12402
12459
|
snapshot: 0
|
|
12403
12460
|
};
|
|
12404
|
-
defaultSnapshotSettleObserver = {
|
|
12405
|
-
async settle(input) {
|
|
12406
|
-
if (input.trigger !== "snapshot") {
|
|
12407
|
-
return false;
|
|
12408
|
-
}
|
|
12409
|
-
await input.engine.waitForVisualStability({
|
|
12410
|
-
pageRef: input.pageRef,
|
|
12411
|
-
...input.remainingMs === void 0 ? {} : { timeoutMs: input.remainingMs },
|
|
12412
|
-
settleMs: DEFAULT_VISUAL_STABILITY_SETTLE_MS,
|
|
12413
|
-
scope: "visible-frames"
|
|
12414
|
-
});
|
|
12415
|
-
return true;
|
|
12416
|
-
}
|
|
12417
|
-
};
|
|
12418
|
-
Object.freeze(defaultSnapshotSettleObserver);
|
|
12419
12461
|
DOM_ACTION_VISUAL_STABILITY_PROFILES = {
|
|
12420
12462
|
"dom.click": { settleMs: 750, scope: "visible-frames", timeoutMs: 7e3 },
|
|
12421
12463
|
"dom.input": { settleMs: 750, scope: "visible-frames", timeoutMs: 7e3 },
|
|
@@ -12494,7 +12536,6 @@ var init_defaults = __esm({
|
|
|
12494
12536
|
};
|
|
12495
12537
|
Object.freeze(defaultNavigationSettleObserver);
|
|
12496
12538
|
DEFAULT_SETTLE_OBSERVERS = Object.freeze([
|
|
12497
|
-
defaultSnapshotSettleObserver,
|
|
12498
12539
|
defaultDomActionSettleObserver,
|
|
12499
12540
|
defaultNavigationSettleObserver
|
|
12500
12541
|
]);
|
|
@@ -12982,6 +13023,9 @@ function buildClauseSelector(node, clause) {
|
|
|
12982
13023
|
if (!clause || typeof clause !== "object") {
|
|
12983
13024
|
return "";
|
|
12984
13025
|
}
|
|
13026
|
+
if (clause.kind === "text") {
|
|
13027
|
+
return "";
|
|
13028
|
+
}
|
|
12985
13029
|
if (clause.kind === "position") {
|
|
12986
13030
|
if (clause.axis === "nthOfType") {
|
|
12987
13031
|
return `:nth-of-type(${Math.max(1, Number(node.position?.nthOfType || 1))})`;
|
|
@@ -13097,7 +13141,7 @@ function resolveExtractedValueInContext(normalizedValue, options) {
|
|
|
13097
13141
|
function stripPositionClauses(nodes) {
|
|
13098
13142
|
return (nodes || []).map((node) => ({
|
|
13099
13143
|
...node,
|
|
13100
|
-
match: (node.match || []).filter((clause) => clause.kind !== "position")
|
|
13144
|
+
match: (node.match || []).filter((clause) => clause.kind !== "position" && clause.kind !== "text")
|
|
13101
13145
|
}));
|
|
13102
13146
|
}
|
|
13103
13147
|
function dedupeSelectors(selectors) {
|
|
@@ -13685,9 +13729,17 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
13685
13729
|
if (!candidates.length) {
|
|
13686
13730
|
return null;
|
|
13687
13731
|
}
|
|
13732
|
+
const lastNode = domPath[domPath.length - 1];
|
|
13733
|
+
const textClauses = lastNode?.match.filter((c) => c.kind === "text") ?? [];
|
|
13688
13734
|
let fallback = null;
|
|
13689
13735
|
for (const selector of candidates) {
|
|
13690
|
-
|
|
13736
|
+
let matches = querySelectorAllInScope(index, selector, scope);
|
|
13737
|
+
if (textClauses.length > 0 && matches.length > 1) {
|
|
13738
|
+
const filtered = matches.filter((node) => matchesTextClauses(node, textClauses));
|
|
13739
|
+
if (filtered.length > 0) {
|
|
13740
|
+
matches = filtered;
|
|
13741
|
+
}
|
|
13742
|
+
}
|
|
13691
13743
|
if (matches.length === 1) {
|
|
13692
13744
|
return {
|
|
13693
13745
|
node: matches[0],
|
|
@@ -13707,6 +13759,10 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
13707
13759
|
}
|
|
13708
13760
|
return fallback;
|
|
13709
13761
|
}
|
|
13762
|
+
function matchesTextClauses(node, clauses) {
|
|
13763
|
+
const text = (node.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
13764
|
+
return clauses.every((clause) => text.includes(clause.value));
|
|
13765
|
+
}
|
|
13710
13766
|
function queryAllDomPathInScope(index, domPath, scope) {
|
|
13711
13767
|
const selectors = buildPathCandidates(domPath);
|
|
13712
13768
|
for (const selector of selectors) {
|
|
@@ -13865,7 +13921,13 @@ function clonePathNode(node) {
|
|
|
13865
13921
|
};
|
|
13866
13922
|
}
|
|
13867
13923
|
function cloneMatchClause(clause) {
|
|
13868
|
-
|
|
13924
|
+
if (clause.kind === "position") {
|
|
13925
|
+
return { kind: "position", axis: clause.axis };
|
|
13926
|
+
}
|
|
13927
|
+
if (clause.kind === "text") {
|
|
13928
|
+
return { kind: "text", value: clause.value };
|
|
13929
|
+
}
|
|
13930
|
+
return {
|
|
13869
13931
|
kind: "attr",
|
|
13870
13932
|
key: clause.key,
|
|
13871
13933
|
...clause.op === void 0 ? {} : { op: clause.op },
|
|
@@ -13920,6 +13982,13 @@ function normalizeMatch(rawMatch, attrs, position, tag) {
|
|
|
13920
13982
|
op,
|
|
13921
13983
|
...value === void 0 ? {} : { value }
|
|
13922
13984
|
});
|
|
13985
|
+
continue;
|
|
13986
|
+
}
|
|
13987
|
+
if (record.kind === "text") {
|
|
13988
|
+
const textValue = typeof record.value === "string" ? record.value.trim() : "";
|
|
13989
|
+
if (textValue) {
|
|
13990
|
+
push({ kind: "text", value: textValue.slice(0, 80) });
|
|
13991
|
+
}
|
|
13923
13992
|
}
|
|
13924
13993
|
}
|
|
13925
13994
|
}
|
|
@@ -14334,7 +14403,7 @@ var init_executor = __esm({
|
|
|
14334
14403
|
init_action_boundary2();
|
|
14335
14404
|
init_policy();
|
|
14336
14405
|
init_bridge();
|
|
14337
|
-
MAX_DOM_ACTION_ATTEMPTS =
|
|
14406
|
+
MAX_DOM_ACTION_ATTEMPTS = 2;
|
|
14338
14407
|
DEFAULT_SCROLL_OPTIONS = {
|
|
14339
14408
|
block: "center",
|
|
14340
14409
|
inline: "center"
|
|
@@ -14821,11 +14890,12 @@ var init_executor = __esm({
|
|
|
14821
14890
|
throw this.createActionabilityError(
|
|
14822
14891
|
operation,
|
|
14823
14892
|
"obscured",
|
|
14824
|
-
`
|
|
14893
|
+
`target is obscured by ${assessment.blockingDescription ?? "another element"} at the click point`,
|
|
14825
14894
|
{
|
|
14826
14895
|
...details,
|
|
14827
14896
|
hitRelation: assessment.relation,
|
|
14828
14897
|
...assessment.ambiguous === void 0 ? {} : { hitAmbiguous: assessment.ambiguous },
|
|
14898
|
+
...assessment.blockingDescription === void 0 ? {} : { blockingDescription: assessment.blockingDescription },
|
|
14829
14899
|
...assessment.canonicalTarget === void 0 ? {} : {
|
|
14830
14900
|
canonicalNodeRef: assessment.canonicalTarget.nodeRef,
|
|
14831
14901
|
canonicalDocumentRef: assessment.canonicalTarget.documentRef,
|
|
@@ -14839,8 +14909,7 @@ var init_executor = __esm({
|
|
|
14839
14909
|
hitMissingFromSnapshot: !resolved.snapshot.nodes.some(
|
|
14840
14910
|
(node) => node.nodeRef === hit.nodeRef
|
|
14841
14911
|
)
|
|
14842
|
-
}
|
|
14843
|
-
true
|
|
14912
|
+
}
|
|
14844
14913
|
);
|
|
14845
14914
|
}
|
|
14846
14915
|
async resolveActionablePointerTarget(session, operation, resolved) {
|
|
@@ -15031,7 +15100,12 @@ var init_runtime = __esm({
|
|
|
15031
15100
|
});
|
|
15032
15101
|
}
|
|
15033
15102
|
async buildPath(input) {
|
|
15034
|
-
return sanitizeReplayElementPath(
|
|
15103
|
+
return sanitizeReplayElementPath(
|
|
15104
|
+
await this.requireBridge().buildReplayPath(
|
|
15105
|
+
input.locator,
|
|
15106
|
+
input.enableTextMatch ? { enableTextMatch: true } : void 0
|
|
15107
|
+
)
|
|
15108
|
+
);
|
|
15035
15109
|
}
|
|
15036
15110
|
async resolveTarget(input) {
|
|
15037
15111
|
return this.withSnapshotSession((session) => this.resolveTargetWithSession(session, input));
|
|
@@ -15251,7 +15325,7 @@ var init_runtime = __esm({
|
|
|
15251
15325
|
if (resolvedByLocator) {
|
|
15252
15326
|
const { snapshot, node } = resolvedByLocator;
|
|
15253
15327
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
15254
|
-
const replayPath = await this.tryBuildPathFromNode(snapshot, node);
|
|
15328
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch: true });
|
|
15255
15329
|
return this.createResolvedTarget("live", snapshot, node, anchor, {
|
|
15256
15330
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
15257
15331
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -15269,11 +15343,12 @@ var init_runtime = __esm({
|
|
|
15269
15343
|
const { snapshot, node } = resolved;
|
|
15270
15344
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
15271
15345
|
const writeDescriptor = descriptorWriter ?? ((input) => this.descriptors.write(input));
|
|
15272
|
-
const
|
|
15346
|
+
const enableTextMatch = method !== "extract";
|
|
15347
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch });
|
|
15273
15348
|
const descriptor = target.persist === void 0 ? void 0 : await writeDescriptor({
|
|
15274
15349
|
method,
|
|
15275
15350
|
persist: target.persist,
|
|
15276
|
-
path: replayPath ?? await this.buildPathForNode(snapshot, node),
|
|
15351
|
+
path: replayPath ?? await this.buildPathForNode(snapshot, node, { enableTextMatch }),
|
|
15277
15352
|
sourceUrl: snapshot.url
|
|
15278
15353
|
});
|
|
15279
15354
|
return this.createResolvedTarget("selector", snapshot, node, anchor, {
|
|
@@ -15373,7 +15448,7 @@ var init_runtime = __esm({
|
|
|
15373
15448
|
`Unable to resolve structural anchor "${buildPathSelectorHint(anchor)}" in the current session`
|
|
15374
15449
|
);
|
|
15375
15450
|
}
|
|
15376
|
-
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node);
|
|
15451
|
+
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, { enableTextMatch: true });
|
|
15377
15452
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
15378
15453
|
...persist === void 0 ? {} : { persist },
|
|
15379
15454
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -15544,19 +15619,20 @@ var init_runtime = __esm({
|
|
|
15544
15619
|
}
|
|
15545
15620
|
return this.bridge;
|
|
15546
15621
|
}
|
|
15547
|
-
async buildPathForNode(snapshot, node) {
|
|
15622
|
+
async buildPathForNode(snapshot, node, options) {
|
|
15548
15623
|
if (node.nodeRef === void 0) {
|
|
15549
15624
|
throw new Error(
|
|
15550
15625
|
`snapshot node ${String(node.snapshotNodeId)} does not expose a live node reference`
|
|
15551
15626
|
);
|
|
15552
15627
|
}
|
|
15553
15628
|
return this.buildPath({
|
|
15554
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef)
|
|
15629
|
+
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
15630
|
+
...options?.enableTextMatch ? { enableTextMatch: true } : {}
|
|
15555
15631
|
});
|
|
15556
15632
|
}
|
|
15557
|
-
async tryBuildPathFromNode(snapshot, node) {
|
|
15633
|
+
async tryBuildPathFromNode(snapshot, node, options) {
|
|
15558
15634
|
try {
|
|
15559
|
-
return await this.buildPathForNode(snapshot, node);
|
|
15635
|
+
return await this.buildPathForNode(snapshot, node, options);
|
|
15560
15636
|
} catch {
|
|
15561
15637
|
return void 0;
|
|
15562
15638
|
}
|
|
@@ -17126,6 +17202,9 @@ function relaxPathForSingleSample(path24, mode) {
|
|
|
17126
17202
|
}
|
|
17127
17203
|
return !isLast;
|
|
17128
17204
|
}
|
|
17205
|
+
if (clause.kind === "text") {
|
|
17206
|
+
return false;
|
|
17207
|
+
}
|
|
17129
17208
|
const key = String(clause.key || "").trim().toLowerCase();
|
|
17130
17209
|
if (!key || !shouldKeepAttrForSingleSample(key)) {
|
|
17131
17210
|
return false;
|
|
@@ -17228,9 +17307,11 @@ function buildNodeStructure(node) {
|
|
|
17228
17307
|
}
|
|
17229
17308
|
structuralAttrs[key] = value;
|
|
17230
17309
|
}
|
|
17231
|
-
const matchClauses = (node.match || []).map(
|
|
17232
|
-
(clause
|
|
17233
|
-
|
|
17310
|
+
const matchClauses = (node.match || []).map((clause) => {
|
|
17311
|
+
if (clause.kind === "position") return `position:${clause.axis}`;
|
|
17312
|
+
if (clause.kind === "text") return `text:${clause.value}`;
|
|
17313
|
+
return `attr:${String(clause.key || "").trim().toLowerCase()}`;
|
|
17314
|
+
}).sort();
|
|
17234
17315
|
return {
|
|
17235
17316
|
tag,
|
|
17236
17317
|
attrs: structuralAttrs,
|
|
@@ -17636,6 +17717,9 @@ function mergeMatchByMajority(matchLists, attrs, threshold, positionFlags = {
|
|
|
17636
17717
|
});
|
|
17637
17718
|
continue;
|
|
17638
17719
|
}
|
|
17720
|
+
if (clause.kind === "text") {
|
|
17721
|
+
continue;
|
|
17722
|
+
}
|
|
17639
17723
|
if (clause.axis === "nthOfType") {
|
|
17640
17724
|
if (positionFlags.hasNthOfType) {
|
|
17641
17725
|
merged.push({ kind: "position", axis: "nthOfType" });
|
|
@@ -29528,8 +29612,29 @@ function assertSupportedCloudBrowserMode(browser) {
|
|
|
29528
29612
|
}
|
|
29529
29613
|
}
|
|
29530
29614
|
function isMissingCloudSessionError(error) {
|
|
29615
|
+
if (error instanceof OpensteerCloudRequestError) {
|
|
29616
|
+
return error.statusCode === 404 && (error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND");
|
|
29617
|
+
}
|
|
29531
29618
|
return error instanceof Error && /\b404\b/.test(error.message);
|
|
29532
29619
|
}
|
|
29620
|
+
function isRecoverableCloudSessionError(error) {
|
|
29621
|
+
if (!(error instanceof OpensteerCloudRequestError)) {
|
|
29622
|
+
return false;
|
|
29623
|
+
}
|
|
29624
|
+
if (error.statusCode === 404) {
|
|
29625
|
+
return error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND";
|
|
29626
|
+
}
|
|
29627
|
+
return error.statusCode === 409 && error.code === "CLOUD_SESSION_STALE";
|
|
29628
|
+
}
|
|
29629
|
+
function isBootstrapRecoveryOperation(operation) {
|
|
29630
|
+
return operation === "session.open" || operation === "instrumentation.route" || operation === "instrumentation.intercept-script";
|
|
29631
|
+
}
|
|
29632
|
+
function isReusableCloudSessionState(session) {
|
|
29633
|
+
if (session.status === "closing" || session.status === "closed" || session.status === "failed") {
|
|
29634
|
+
return false;
|
|
29635
|
+
}
|
|
29636
|
+
return !(typeof session.expiresAt === "number" && session.expiresAt <= Date.now() + CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS);
|
|
29637
|
+
}
|
|
29533
29638
|
function isLoopbackBaseUrl(baseUrl) {
|
|
29534
29639
|
let url;
|
|
29535
29640
|
try {
|
|
@@ -29539,7 +29644,7 @@ function isLoopbackBaseUrl(baseUrl) {
|
|
|
29539
29644
|
}
|
|
29540
29645
|
return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1" || url.hostname === "[::1]";
|
|
29541
29646
|
}
|
|
29542
|
-
var TEMPORARY_CLOUD_WORKSPACE_PREFIX, CloudSessionProxy;
|
|
29647
|
+
var TEMPORARY_CLOUD_WORKSPACE_PREFIX, CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS, CloudSessionProxy;
|
|
29543
29648
|
var init_session_proxy = __esm({
|
|
29544
29649
|
"src/cloud/session-proxy.ts"() {
|
|
29545
29650
|
init_src3();
|
|
@@ -29549,8 +29654,10 @@ var init_session_proxy = __esm({
|
|
|
29549
29654
|
init_policy2();
|
|
29550
29655
|
init_semantic_rest_client();
|
|
29551
29656
|
init_automation_client();
|
|
29657
|
+
init_client();
|
|
29552
29658
|
init_workspace_sync();
|
|
29553
29659
|
TEMPORARY_CLOUD_WORKSPACE_PREFIX = "opensteer-cloud-workspace-";
|
|
29660
|
+
CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS = 1e4;
|
|
29554
29661
|
CloudSessionProxy = class {
|
|
29555
29662
|
rootPath;
|
|
29556
29663
|
workspace;
|
|
@@ -29564,6 +29671,8 @@ var init_session_proxy = __esm({
|
|
|
29564
29671
|
automation;
|
|
29565
29672
|
workspaceStore;
|
|
29566
29673
|
syncWorkspaceOnClose = false;
|
|
29674
|
+
liveSessionStateEstablished = false;
|
|
29675
|
+
storedInstrumentation = [];
|
|
29567
29676
|
constructor(cloud, options = {}) {
|
|
29568
29677
|
this.cloud = cloud;
|
|
29569
29678
|
this.workspace = options.workspace;
|
|
@@ -29593,15 +29702,12 @@ var init_session_proxy = __esm({
|
|
|
29593
29702
|
if (this.client === void 0 && this.sessionId === void 0 && persisted !== void 0 && await this.isReusableCloudSession(persisted.sessionId)) {
|
|
29594
29703
|
this.bindClient(persisted);
|
|
29595
29704
|
}
|
|
29596
|
-
|
|
29597
|
-
|
|
29598
|
-
|
|
29599
|
-
|
|
29600
|
-
|
|
29601
|
-
|
|
29602
|
-
};
|
|
29603
|
-
} catch {
|
|
29604
|
-
}
|
|
29705
|
+
const sessionInfo = this.automation ? await this.automation.getSessionInfo().catch(() => void 0) : void 0;
|
|
29706
|
+
if (sessionInfo !== void 0) {
|
|
29707
|
+
return {
|
|
29708
|
+
...sessionInfo,
|
|
29709
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace }
|
|
29710
|
+
};
|
|
29605
29711
|
}
|
|
29606
29712
|
return {
|
|
29607
29713
|
provider: {
|
|
@@ -29713,12 +29819,26 @@ var init_session_proxy = __esm({
|
|
|
29713
29819
|
return this.invokeSemanticOperation("session.cookies", input);
|
|
29714
29820
|
}
|
|
29715
29821
|
async route(input) {
|
|
29716
|
-
await this.
|
|
29717
|
-
|
|
29822
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
29823
|
+
"instrumentation.route",
|
|
29824
|
+
(automation) => automation.route(input)
|
|
29825
|
+
);
|
|
29826
|
+
this.storedInstrumentation.push({
|
|
29827
|
+
kind: "route",
|
|
29828
|
+
input
|
|
29829
|
+
});
|
|
29830
|
+
return registration;
|
|
29718
29831
|
}
|
|
29719
29832
|
async interceptScript(input) {
|
|
29720
|
-
await this.
|
|
29721
|
-
|
|
29833
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
29834
|
+
"instrumentation.intercept-script",
|
|
29835
|
+
(automation) => automation.interceptScript(input)
|
|
29836
|
+
);
|
|
29837
|
+
this.storedInstrumentation.push({
|
|
29838
|
+
kind: "intercept-script",
|
|
29839
|
+
input
|
|
29840
|
+
});
|
|
29841
|
+
return registration;
|
|
29722
29842
|
}
|
|
29723
29843
|
async getStorageSnapshot(input = {}) {
|
|
29724
29844
|
return this.invokeSemanticOperation("session.storage", input);
|
|
@@ -29766,6 +29886,8 @@ var init_session_proxy = __esm({
|
|
|
29766
29886
|
this.client = void 0;
|
|
29767
29887
|
this.sessionId = void 0;
|
|
29768
29888
|
this.semanticGrant = void 0;
|
|
29889
|
+
this.liveSessionStateEstablished = false;
|
|
29890
|
+
this.storedInstrumentation.length = 0;
|
|
29769
29891
|
if (this.cleanupRootOnClose) {
|
|
29770
29892
|
await promises.rm(this.rootPath, { recursive: true, force: true }).catch(() => void 0);
|
|
29771
29893
|
}
|
|
@@ -29793,6 +29915,8 @@ var init_session_proxy = __esm({
|
|
|
29793
29915
|
this.automation = void 0;
|
|
29794
29916
|
this.sessionId = void 0;
|
|
29795
29917
|
this.semanticGrant = void 0;
|
|
29918
|
+
this.liveSessionStateEstablished = false;
|
|
29919
|
+
this.storedInstrumentation.length = 0;
|
|
29796
29920
|
if (syncError !== void 0) {
|
|
29797
29921
|
throw syncError;
|
|
29798
29922
|
}
|
|
@@ -29840,6 +29964,7 @@ var init_session_proxy = __esm({
|
|
|
29840
29964
|
};
|
|
29841
29965
|
await this.writePersistedSession(record);
|
|
29842
29966
|
this.bindClient(record, session.initialGrants?.semantic);
|
|
29967
|
+
await this.restoreStoredInstrumentation();
|
|
29843
29968
|
}
|
|
29844
29969
|
async syncWorkspaceToCloud() {
|
|
29845
29970
|
if (this.workspace === void 0) {
|
|
@@ -29851,6 +29976,7 @@ var init_session_proxy = __esm({
|
|
|
29851
29976
|
bindClient(record, initialSemanticGrant) {
|
|
29852
29977
|
this.sessionId = record.sessionId;
|
|
29853
29978
|
this.semanticGrant = initialSemanticGrant?.kind === "semantic" ? initialSemanticGrant : void 0;
|
|
29979
|
+
this.liveSessionStateEstablished = false;
|
|
29854
29980
|
this.client = new OpensteerSemanticRestClient({
|
|
29855
29981
|
getBaseUrl: async () => (await this.ensureSemanticGrant()).url,
|
|
29856
29982
|
getAuthorizationHeader: async () => `Bearer ${(await this.ensureSemanticGrant()).token}`,
|
|
@@ -29858,6 +29984,19 @@ var init_session_proxy = __esm({
|
|
|
29858
29984
|
});
|
|
29859
29985
|
this.automation = new OpensteerCloudAutomationClient(this.cloud, record.sessionId);
|
|
29860
29986
|
}
|
|
29987
|
+
async restoreStoredInstrumentation() {
|
|
29988
|
+
if (this.storedInstrumentation.length === 0) {
|
|
29989
|
+
return;
|
|
29990
|
+
}
|
|
29991
|
+
const automation = this.requireAutomation();
|
|
29992
|
+
for (const registration of this.storedInstrumentation) {
|
|
29993
|
+
if (registration.kind === "route") {
|
|
29994
|
+
await automation.route(registration.input);
|
|
29995
|
+
} else {
|
|
29996
|
+
await automation.interceptScript(registration.input);
|
|
29997
|
+
}
|
|
29998
|
+
}
|
|
29999
|
+
}
|
|
29861
30000
|
async ensureWorkspaceStore() {
|
|
29862
30001
|
if (this.workspaceStore !== void 0) {
|
|
29863
30002
|
return this.workspaceStore;
|
|
@@ -29880,13 +30019,22 @@ var init_session_proxy = __esm({
|
|
|
29880
30019
|
async clearPersistedSession() {
|
|
29881
30020
|
await clearPersistedSessionRecord(this.rootPath, "cloud").catch(() => void 0);
|
|
29882
30021
|
}
|
|
30022
|
+
async invalidateSession() {
|
|
30023
|
+
await this.automation?.close().catch(() => void 0);
|
|
30024
|
+
this.automation = void 0;
|
|
30025
|
+
this.client = void 0;
|
|
30026
|
+
this.sessionId = void 0;
|
|
30027
|
+
this.semanticGrant = void 0;
|
|
30028
|
+
this.liveSessionStateEstablished = false;
|
|
30029
|
+
await this.clearPersistedSession();
|
|
30030
|
+
}
|
|
29883
30031
|
async isReusableCloudSession(sessionId, timeout) {
|
|
29884
30032
|
try {
|
|
29885
30033
|
const session = await this.cloud.getSession(sessionId, {
|
|
29886
30034
|
signal: timeout?.signal,
|
|
29887
30035
|
timeoutMs: timeout?.remainingMs()
|
|
29888
30036
|
});
|
|
29889
|
-
return session
|
|
30037
|
+
return isReusableCloudSessionState(session);
|
|
29890
30038
|
} catch (error) {
|
|
29891
30039
|
if (isMissingCloudSessionError(error)) {
|
|
29892
30040
|
return false;
|
|
@@ -29935,26 +30083,79 @@ var init_session_proxy = __esm({
|
|
|
29935
30083
|
try {
|
|
29936
30084
|
await this.ensureSemanticGrant(true);
|
|
29937
30085
|
return true;
|
|
29938
|
-
} catch {
|
|
30086
|
+
} catch (refreshError) {
|
|
30087
|
+
if (await this.resetStaleSession(refreshError)) {
|
|
30088
|
+
throw refreshError;
|
|
30089
|
+
}
|
|
29939
30090
|
return false;
|
|
29940
30091
|
}
|
|
29941
30092
|
}
|
|
29942
30093
|
async invokeSemanticOperation(operation, input, sessionInit = {}) {
|
|
29943
|
-
return this.
|
|
30094
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
29944
30095
|
await this.ensureSession(sessionInit, timeout);
|
|
29945
30096
|
await this.ensureSemanticGrant(false, timeout);
|
|
29946
|
-
|
|
30097
|
+
const output = await this.requireClient().invoke(operation, input, {
|
|
29947
30098
|
signal: timeout.signal,
|
|
29948
30099
|
timeoutMs: timeout.remainingMs()
|
|
29949
30100
|
});
|
|
30101
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
30102
|
+
return output;
|
|
29950
30103
|
});
|
|
29951
30104
|
}
|
|
29952
30105
|
async invokeAutomationOperation(operation, invoke, sessionInit = {}) {
|
|
29953
|
-
return this.
|
|
30106
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
29954
30107
|
await this.ensureSession(sessionInit, timeout);
|
|
29955
|
-
|
|
30108
|
+
const output = await invoke(this.requireAutomation());
|
|
30109
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
30110
|
+
return output;
|
|
29956
30111
|
});
|
|
29957
30112
|
}
|
|
30113
|
+
async invokeBootstrapInstrumentationOperation(operation, invoke) {
|
|
30114
|
+
let recovered = false;
|
|
30115
|
+
while (true) {
|
|
30116
|
+
try {
|
|
30117
|
+
await this.ensureSession();
|
|
30118
|
+
return await invoke(this.requireAutomation());
|
|
30119
|
+
} catch (error) {
|
|
30120
|
+
const stale = await this.resetStaleSession(error);
|
|
30121
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
30122
|
+
throw error;
|
|
30123
|
+
}
|
|
30124
|
+
recovered = true;
|
|
30125
|
+
}
|
|
30126
|
+
}
|
|
30127
|
+
}
|
|
30128
|
+
async runOperationWithSessionRecovery(operation, invoke) {
|
|
30129
|
+
return this.runOperationWithPolicy(operation, async (timeout) => {
|
|
30130
|
+
let recovered = false;
|
|
30131
|
+
while (true) {
|
|
30132
|
+
try {
|
|
30133
|
+
return await invoke(timeout);
|
|
30134
|
+
} catch (error) {
|
|
30135
|
+
const stale = await this.resetStaleSession(error);
|
|
30136
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
30137
|
+
throw error;
|
|
30138
|
+
}
|
|
30139
|
+
recovered = true;
|
|
30140
|
+
}
|
|
30141
|
+
}
|
|
30142
|
+
});
|
|
30143
|
+
}
|
|
30144
|
+
async resetStaleSession(error) {
|
|
30145
|
+
if (!isRecoverableCloudSessionError(error)) {
|
|
30146
|
+
return false;
|
|
30147
|
+
}
|
|
30148
|
+
await this.invalidateSession();
|
|
30149
|
+
return true;
|
|
30150
|
+
}
|
|
30151
|
+
canRecoverWithFreshSession(operation) {
|
|
30152
|
+
return !this.liveSessionStateEstablished && isBootstrapRecoveryOperation(operation);
|
|
30153
|
+
}
|
|
30154
|
+
noteSuccessfulLiveOperation(operation) {
|
|
30155
|
+
if (operation === "session.open" || operation === "page.list" || operation === "page.new" || operation === "page.activate" || operation === "page.close" || operation === "page.goto" || operation === "page.evaluate" || operation === "page.add-init-script" || operation === "page.snapshot" || operation === "dom.click" || operation === "dom.hover" || operation === "dom.input" || operation === "dom.scroll" || operation === "dom.extract" || operation === "network.query" || operation === "network.detail" || operation === "interaction.capture" || operation === "interaction.get" || operation === "interaction.diff" || operation === "interaction.replay" || operation === "scripts.capture" || operation === "artifact.read" || operation === "scripts.beautify" || operation === "scripts.deobfuscate" || operation === "scripts.sandbox" || operation === "captcha.solve" || operation === "session.cookies" || operation === "session.storage" || operation === "session.state" || operation === "session.fetch" || operation === "computer.execute") {
|
|
30156
|
+
this.liveSessionStateEstablished = true;
|
|
30157
|
+
}
|
|
30158
|
+
}
|
|
29958
30159
|
async runOperationWithPolicy(operation, invoke) {
|
|
29959
30160
|
return runWithPolicyTimeout(this.policy.timeout, { operation }, invoke);
|
|
29960
30161
|
}
|
|
@@ -30269,14 +30470,85 @@ var init_session_control = __esm({
|
|
|
30269
30470
|
}
|
|
30270
30471
|
});
|
|
30271
30472
|
|
|
30473
|
+
// src/internal/errors.ts
|
|
30474
|
+
function normalizeThrownOpensteerError2(error, fallbackMessage) {
|
|
30475
|
+
if (isOpensteerProtocolError(error)) {
|
|
30476
|
+
return toOpensteerError(error);
|
|
30477
|
+
}
|
|
30478
|
+
if (isBrowserCoreError(error)) {
|
|
30479
|
+
return createOpensteerError(error.code, error.message, {
|
|
30480
|
+
retriable: error.retriable,
|
|
30481
|
+
...error.details === void 0 ? {} : { details: error.details }
|
|
30482
|
+
});
|
|
30483
|
+
}
|
|
30484
|
+
if (error instanceof OpensteerAttachAmbiguousError) {
|
|
30485
|
+
return createOpensteerError("conflict", error.message, {
|
|
30486
|
+
details: {
|
|
30487
|
+
candidates: error.candidates,
|
|
30488
|
+
code: error.code,
|
|
30489
|
+
name: error.name
|
|
30490
|
+
}
|
|
30491
|
+
});
|
|
30492
|
+
}
|
|
30493
|
+
if (error instanceof Error && "opensteerError" in error && typeof error.opensteerError === "object" && error.opensteerError !== null) {
|
|
30494
|
+
const oe = error.opensteerError;
|
|
30495
|
+
return createOpensteerError(oe.code, oe.message, {
|
|
30496
|
+
retriable: oe.retriable,
|
|
30497
|
+
...oe.capability === void 0 ? {} : { capability: oe.capability },
|
|
30498
|
+
...oe.details === void 0 ? {} : { details: oe.details }
|
|
30499
|
+
});
|
|
30500
|
+
}
|
|
30501
|
+
if (error instanceof Error) {
|
|
30502
|
+
return createOpensteerError("operation-failed", error.message, {
|
|
30503
|
+
details: {
|
|
30504
|
+
name: error.name
|
|
30505
|
+
}
|
|
30506
|
+
});
|
|
30507
|
+
}
|
|
30508
|
+
return createOpensteerError("internal", fallbackMessage, {
|
|
30509
|
+
details: {
|
|
30510
|
+
value: error
|
|
30511
|
+
}
|
|
30512
|
+
});
|
|
30513
|
+
}
|
|
30514
|
+
var init_errors5 = __esm({
|
|
30515
|
+
"src/internal/errors.ts"() {
|
|
30516
|
+
init_src();
|
|
30517
|
+
init_src2();
|
|
30518
|
+
init_cdp_discovery();
|
|
30519
|
+
}
|
|
30520
|
+
});
|
|
30521
|
+
|
|
30272
30522
|
// src/sdk/opensteer.ts
|
|
30273
30523
|
var opensteer_exports = {};
|
|
30274
30524
|
__export(opensteer_exports, {
|
|
30275
30525
|
Opensteer: () => Opensteer
|
|
30276
30526
|
});
|
|
30527
|
+
function createSdkProtocolError(error, fallbackMessage) {
|
|
30528
|
+
const normalized = normalizeThrownOpensteerError2(error, fallbackMessage);
|
|
30529
|
+
return new OpensteerProtocolError(normalized.code, normalized.message, {
|
|
30530
|
+
cause: error,
|
|
30531
|
+
retriable: normalized.retriable,
|
|
30532
|
+
...normalized.capability === void 0 ? {} : { capability: normalized.capability },
|
|
30533
|
+
...normalized.details === void 0 ? {} : { details: normalized.details }
|
|
30534
|
+
});
|
|
30535
|
+
}
|
|
30536
|
+
async function wrapSdkError(operation, fn) {
|
|
30537
|
+
try {
|
|
30538
|
+
return await fn();
|
|
30539
|
+
} catch (error) {
|
|
30540
|
+
if (isOpensteerProtocolError(error)) {
|
|
30541
|
+
throw error;
|
|
30542
|
+
}
|
|
30543
|
+
throw createSdkProtocolError(error, `${operation} failed`);
|
|
30544
|
+
}
|
|
30545
|
+
}
|
|
30277
30546
|
function createUnsupportedBrowserController() {
|
|
30278
30547
|
const fail = async () => {
|
|
30279
|
-
throw new
|
|
30548
|
+
throw new OpensteerProtocolError(
|
|
30549
|
+
"unsupported-operation",
|
|
30550
|
+
"browser.* helpers are only available in local mode."
|
|
30551
|
+
);
|
|
30280
30552
|
};
|
|
30281
30553
|
return {
|
|
30282
30554
|
status: fail,
|
|
@@ -30289,7 +30561,10 @@ function normalizeTargetOptions(input) {
|
|
|
30289
30561
|
const hasElement = input.element !== void 0;
|
|
30290
30562
|
const hasSelector = input.selector !== void 0;
|
|
30291
30563
|
if (hasElement && hasSelector) {
|
|
30292
|
-
throw new
|
|
30564
|
+
throw new OpensteerProtocolError(
|
|
30565
|
+
"invalid-argument",
|
|
30566
|
+
"Specify exactly one of element, selector, or persist."
|
|
30567
|
+
);
|
|
30293
30568
|
}
|
|
30294
30569
|
if (hasElement) {
|
|
30295
30570
|
return {
|
|
@@ -30312,7 +30587,10 @@ function normalizeTargetOptions(input) {
|
|
|
30312
30587
|
};
|
|
30313
30588
|
}
|
|
30314
30589
|
if (input.persist === void 0) {
|
|
30315
|
-
throw new
|
|
30590
|
+
throw new OpensteerProtocolError(
|
|
30591
|
+
"invalid-argument",
|
|
30592
|
+
"Specify exactly one of element, selector, or persist."
|
|
30593
|
+
);
|
|
30316
30594
|
}
|
|
30317
30595
|
return {
|
|
30318
30596
|
target: {
|
|
@@ -30374,8 +30652,10 @@ function delay5(ms) {
|
|
|
30374
30652
|
var SessionCookieJar, Opensteer;
|
|
30375
30653
|
var init_opensteer = __esm({
|
|
30376
30654
|
"src/sdk/opensteer.ts"() {
|
|
30655
|
+
init_src2();
|
|
30377
30656
|
init_browser_manager();
|
|
30378
30657
|
init_env();
|
|
30658
|
+
init_errors5();
|
|
30379
30659
|
init_runtime_resolution();
|
|
30380
30660
|
SessionCookieJar = class {
|
|
30381
30661
|
domain;
|
|
@@ -30406,202 +30686,257 @@ var init_opensteer = __esm({
|
|
|
30406
30686
|
dom;
|
|
30407
30687
|
network;
|
|
30408
30688
|
constructor(options = {}) {
|
|
30409
|
-
|
|
30410
|
-
|
|
30411
|
-
|
|
30412
|
-
|
|
30413
|
-
environment
|
|
30414
|
-
});
|
|
30415
|
-
if (runtimeConfig.provider.mode === "cloud") {
|
|
30416
|
-
this.browserManager = void 0;
|
|
30417
|
-
this.runtime = createOpensteerSemanticRuntime({
|
|
30418
|
-
...provider === void 0 ? {} : { provider },
|
|
30419
|
-
...engineName === void 0 ? {} : { engine: engineName },
|
|
30420
|
-
environment,
|
|
30421
|
-
runtimeOptions
|
|
30422
|
-
});
|
|
30423
|
-
this.browser = createUnsupportedBrowserController();
|
|
30424
|
-
} else {
|
|
30425
|
-
this.browserManager = new OpensteerBrowserManager({
|
|
30426
|
-
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
30427
|
-
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
30428
|
-
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
30429
|
-
...engineName === void 0 ? {} : { engineName },
|
|
30430
|
-
environment,
|
|
30431
|
-
...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
|
|
30432
|
-
...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
|
|
30433
|
-
...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
|
|
30434
|
-
});
|
|
30435
|
-
this.runtime = createOpensteerSemanticRuntime({
|
|
30689
|
+
try {
|
|
30690
|
+
const environment = resolveOpensteerEnvironment(options.rootDir);
|
|
30691
|
+
const { provider, engineName, ...runtimeOptions } = options;
|
|
30692
|
+
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
30436
30693
|
...provider === void 0 ? {} : { provider },
|
|
30437
|
-
|
|
30438
|
-
environment,
|
|
30439
|
-
runtimeOptions: {
|
|
30440
|
-
...runtimeOptions,
|
|
30441
|
-
rootPath: this.browserManager.rootPath,
|
|
30442
|
-
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
30443
|
-
}
|
|
30694
|
+
environment
|
|
30444
30695
|
});
|
|
30445
|
-
|
|
30446
|
-
|
|
30447
|
-
|
|
30448
|
-
|
|
30449
|
-
|
|
30696
|
+
if (runtimeConfig.provider.mode === "cloud") {
|
|
30697
|
+
this.browserManager = void 0;
|
|
30698
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
30699
|
+
...provider === void 0 ? {} : { provider },
|
|
30700
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
30701
|
+
environment,
|
|
30702
|
+
runtimeOptions
|
|
30703
|
+
});
|
|
30704
|
+
this.browser = createUnsupportedBrowserController();
|
|
30705
|
+
} else {
|
|
30706
|
+
this.browserManager = new OpensteerBrowserManager({
|
|
30707
|
+
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
30708
|
+
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
30709
|
+
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
30710
|
+
...engineName === void 0 ? {} : { engineName },
|
|
30711
|
+
environment,
|
|
30712
|
+
...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
|
|
30713
|
+
...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
|
|
30714
|
+
...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
|
|
30715
|
+
});
|
|
30716
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
30717
|
+
...provider === void 0 ? {} : { provider },
|
|
30718
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
30719
|
+
environment,
|
|
30720
|
+
runtimeOptions: {
|
|
30721
|
+
...runtimeOptions,
|
|
30722
|
+
rootPath: this.browserManager.rootPath,
|
|
30723
|
+
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
30724
|
+
}
|
|
30725
|
+
});
|
|
30726
|
+
this.browser = {
|
|
30727
|
+
status: () => wrapSdkError("browser.status", () => this.browserManager.status()),
|
|
30728
|
+
clone: (input) => wrapSdkError("browser.clone", () => this.browserManager.clonePersistentBrowser(input)),
|
|
30729
|
+
reset: () => wrapSdkError("browser.reset", () => this.browserManager.reset()),
|
|
30730
|
+
delete: () => wrapSdkError("browser.delete", () => this.browserManager.delete())
|
|
30731
|
+
};
|
|
30732
|
+
}
|
|
30733
|
+
this.dom = {
|
|
30734
|
+
click: (input) => this.click(input),
|
|
30735
|
+
hover: (input) => this.hover(input),
|
|
30736
|
+
input: (input) => this.input(input),
|
|
30737
|
+
scroll: (input) => this.scroll(input)
|
|
30738
|
+
};
|
|
30739
|
+
this.network = {
|
|
30740
|
+
query: (input = {}) => wrapSdkError("network.query", () => this.runtime.queryNetwork(input)),
|
|
30741
|
+
detail: (recordId, options2) => wrapSdkError(
|
|
30742
|
+
"network.detail",
|
|
30743
|
+
() => this.runtime.getNetworkDetail({ recordId, ...options2 })
|
|
30744
|
+
)
|
|
30450
30745
|
};
|
|
30746
|
+
} catch (error) {
|
|
30747
|
+
if (isOpensteerProtocolError(error)) {
|
|
30748
|
+
throw error;
|
|
30749
|
+
}
|
|
30750
|
+
throw createSdkProtocolError(error, "Failed to initialize Opensteer");
|
|
30451
30751
|
}
|
|
30452
|
-
this.dom = {
|
|
30453
|
-
click: (input) => this.click(input),
|
|
30454
|
-
hover: (input) => this.hover(input),
|
|
30455
|
-
input: (input) => this.input(input),
|
|
30456
|
-
scroll: (input) => this.scroll(input)
|
|
30457
|
-
};
|
|
30458
|
-
this.network = {
|
|
30459
|
-
query: (input = {}) => this.runtime.queryNetwork(input),
|
|
30460
|
-
detail: (recordId, options2) => this.runtime.getNetworkDetail({ recordId, ...options2 })
|
|
30461
|
-
};
|
|
30462
30752
|
}
|
|
30463
30753
|
async open(input = {}) {
|
|
30464
|
-
return
|
|
30754
|
+
return wrapSdkError(
|
|
30755
|
+
"session.open",
|
|
30756
|
+
() => this.runtime.open(typeof input === "string" ? { url: input } : input)
|
|
30757
|
+
);
|
|
30465
30758
|
}
|
|
30466
30759
|
async info() {
|
|
30467
|
-
return this.runtime.info();
|
|
30760
|
+
return wrapSdkError("session.info", () => this.runtime.info());
|
|
30468
30761
|
}
|
|
30469
30762
|
async listPages(input = {}) {
|
|
30470
|
-
return this.runtime.listPages(input);
|
|
30763
|
+
return wrapSdkError("page.list", () => this.runtime.listPages(input));
|
|
30471
30764
|
}
|
|
30472
30765
|
async newPage(input = {}) {
|
|
30473
|
-
return this.runtime.newPage(input);
|
|
30766
|
+
return wrapSdkError("page.new", () => this.runtime.newPage(input));
|
|
30474
30767
|
}
|
|
30475
30768
|
async activatePage(input) {
|
|
30476
|
-
return this.runtime.activatePage(input);
|
|
30769
|
+
return wrapSdkError("page.activate", () => this.runtime.activatePage(input));
|
|
30477
30770
|
}
|
|
30478
30771
|
async closePage(input = {}) {
|
|
30479
|
-
return this.runtime.closePage(input);
|
|
30772
|
+
return wrapSdkError("page.close", () => this.runtime.closePage(input));
|
|
30480
30773
|
}
|
|
30481
30774
|
async goto(url, options = {}) {
|
|
30482
|
-
return
|
|
30483
|
-
|
|
30484
|
-
|
|
30485
|
-
|
|
30775
|
+
return wrapSdkError(
|
|
30776
|
+
"page.goto",
|
|
30777
|
+
() => this.runtime.goto({
|
|
30778
|
+
url,
|
|
30779
|
+
...options
|
|
30780
|
+
})
|
|
30781
|
+
);
|
|
30486
30782
|
}
|
|
30487
30783
|
async evaluate(input) {
|
|
30488
|
-
|
|
30489
|
-
|
|
30490
|
-
|
|
30491
|
-
|
|
30784
|
+
return wrapSdkError("page.evaluate", async () => {
|
|
30785
|
+
const normalized = typeof input === "string" ? {
|
|
30786
|
+
script: input
|
|
30787
|
+
} : input;
|
|
30788
|
+
return (await this.runtime.evaluate(normalized)).value;
|
|
30789
|
+
});
|
|
30492
30790
|
}
|
|
30493
30791
|
async addInitScript(input) {
|
|
30494
|
-
return
|
|
30495
|
-
|
|
30496
|
-
|
|
30497
|
-
|
|
30792
|
+
return wrapSdkError(
|
|
30793
|
+
"page.addInitScript",
|
|
30794
|
+
() => this.runtime.addInitScript(
|
|
30795
|
+
typeof input === "string" ? {
|
|
30796
|
+
script: input
|
|
30797
|
+
} : input
|
|
30798
|
+
)
|
|
30498
30799
|
);
|
|
30499
30800
|
}
|
|
30500
30801
|
async click(input) {
|
|
30501
|
-
|
|
30502
|
-
|
|
30503
|
-
|
|
30504
|
-
|
|
30505
|
-
|
|
30506
|
-
|
|
30802
|
+
return wrapSdkError("dom.click", () => {
|
|
30803
|
+
const { button, clickCount, modifiers, ...target } = input;
|
|
30804
|
+
return this.runtime.click({
|
|
30805
|
+
...normalizeTargetOptions(target),
|
|
30806
|
+
...button === void 0 ? {} : { button },
|
|
30807
|
+
...clickCount === void 0 ? {} : { clickCount },
|
|
30808
|
+
...modifiers === void 0 ? {} : { modifiers }
|
|
30809
|
+
});
|
|
30507
30810
|
});
|
|
30508
30811
|
}
|
|
30509
30812
|
async hover(input) {
|
|
30510
|
-
return this.runtime.hover(normalizeTargetOptions(input));
|
|
30813
|
+
return wrapSdkError("dom.hover", () => this.runtime.hover(normalizeTargetOptions(input)));
|
|
30511
30814
|
}
|
|
30512
30815
|
async input(input) {
|
|
30513
|
-
return
|
|
30514
|
-
|
|
30515
|
-
|
|
30516
|
-
|
|
30517
|
-
|
|
30816
|
+
return wrapSdkError(
|
|
30817
|
+
"dom.input",
|
|
30818
|
+
() => this.runtime.input({
|
|
30819
|
+
...normalizeTargetOptions(input),
|
|
30820
|
+
text: input.text,
|
|
30821
|
+
...input.pressEnter === void 0 ? {} : { pressEnter: input.pressEnter }
|
|
30822
|
+
})
|
|
30823
|
+
);
|
|
30518
30824
|
}
|
|
30519
30825
|
async scroll(input) {
|
|
30520
|
-
return
|
|
30521
|
-
|
|
30522
|
-
|
|
30523
|
-
|
|
30524
|
-
|
|
30826
|
+
return wrapSdkError(
|
|
30827
|
+
"dom.scroll",
|
|
30828
|
+
() => this.runtime.scroll({
|
|
30829
|
+
...normalizeTargetOptions(input),
|
|
30830
|
+
direction: input.direction,
|
|
30831
|
+
amount: input.amount
|
|
30832
|
+
})
|
|
30833
|
+
);
|
|
30525
30834
|
}
|
|
30526
30835
|
async extract(input) {
|
|
30527
|
-
return (await this.runtime.extract(input)).data;
|
|
30836
|
+
return wrapSdkError("extract", async () => (await this.runtime.extract(input)).data);
|
|
30528
30837
|
}
|
|
30529
30838
|
async waitForPage(input = {}) {
|
|
30530
|
-
|
|
30531
|
-
|
|
30532
|
-
|
|
30533
|
-
|
|
30534
|
-
|
|
30535
|
-
|
|
30536
|
-
|
|
30537
|
-
|
|
30538
|
-
|
|
30539
|
-
|
|
30839
|
+
return wrapSdkError("page.waitForPage", async () => {
|
|
30840
|
+
const baseline = new Set((await this.runtime.listPages()).pages.map((page) => page.pageRef));
|
|
30841
|
+
const timeoutAt = Date.now() + (input.timeoutMs ?? 3e4);
|
|
30842
|
+
const pollIntervalMs = input.pollIntervalMs ?? 100;
|
|
30843
|
+
while (true) {
|
|
30844
|
+
const match = (await this.runtime.listPages()).pages.find((page) => {
|
|
30845
|
+
if (baseline.has(page.pageRef)) {
|
|
30846
|
+
return false;
|
|
30847
|
+
}
|
|
30848
|
+
if (input.openerPageRef !== void 0 && page.openerPageRef !== input.openerPageRef) {
|
|
30849
|
+
return false;
|
|
30850
|
+
}
|
|
30851
|
+
if (input.urlIncludes !== void 0 && !page.url.includes(input.urlIncludes)) {
|
|
30852
|
+
return false;
|
|
30853
|
+
}
|
|
30854
|
+
return true;
|
|
30855
|
+
});
|
|
30856
|
+
if (match !== void 0) {
|
|
30857
|
+
return match;
|
|
30540
30858
|
}
|
|
30541
|
-
if (
|
|
30542
|
-
|
|
30859
|
+
if (Date.now() >= timeoutAt) {
|
|
30860
|
+
throw new OpensteerProtocolError("timeout", "waitForPage timed out");
|
|
30543
30861
|
}
|
|
30544
|
-
|
|
30545
|
-
});
|
|
30546
|
-
if (match !== void 0) {
|
|
30547
|
-
return match;
|
|
30548
|
-
}
|
|
30549
|
-
if (Date.now() >= timeoutAt) {
|
|
30550
|
-
throw new Error("waitForPage timed out");
|
|
30862
|
+
await delay5(pollIntervalMs);
|
|
30551
30863
|
}
|
|
30552
|
-
|
|
30553
|
-
}
|
|
30864
|
+
});
|
|
30554
30865
|
}
|
|
30555
30866
|
async cookies(domain) {
|
|
30556
|
-
return
|
|
30557
|
-
|
|
30867
|
+
return wrapSdkError(
|
|
30868
|
+
"session.cookies",
|
|
30869
|
+
async () => new SessionCookieJar(await this.runtime.getCookies(domain === void 0 ? {} : { domain }))
|
|
30558
30870
|
);
|
|
30559
30871
|
}
|
|
30560
30872
|
async storage(domain, type = "local") {
|
|
30561
|
-
|
|
30562
|
-
|
|
30563
|
-
|
|
30564
|
-
|
|
30565
|
-
|
|
30566
|
-
|
|
30567
|
-
|
|
30873
|
+
return wrapSdkError("session.storage", async () => {
|
|
30874
|
+
const snapshot = await this.runtime.getStorageSnapshot(
|
|
30875
|
+
domain === void 0 ? {} : { domain }
|
|
30876
|
+
);
|
|
30877
|
+
const domainSnapshot = pickStorageDomainSnapshot(snapshot, domain);
|
|
30878
|
+
if (domainSnapshot === void 0) {
|
|
30879
|
+
return {};
|
|
30880
|
+
}
|
|
30881
|
+
const entries = type === "local" ? domainSnapshot.localStorage : domainSnapshot.sessionStorage;
|
|
30882
|
+
return Object.fromEntries(entries.map((entry) => [entry.key, entry.value]));
|
|
30883
|
+
});
|
|
30568
30884
|
}
|
|
30569
30885
|
async state(domain) {
|
|
30570
|
-
return
|
|
30886
|
+
return wrapSdkError(
|
|
30887
|
+
"session.state",
|
|
30888
|
+
() => this.runtime.getBrowserState(domain === void 0 ? {} : { domain })
|
|
30889
|
+
);
|
|
30571
30890
|
}
|
|
30572
30891
|
async fetch(url, options = {}) {
|
|
30573
|
-
|
|
30574
|
-
|
|
30575
|
-
|
|
30576
|
-
|
|
30577
|
-
|
|
30578
|
-
|
|
30892
|
+
return wrapSdkError("session.fetch", async () => {
|
|
30893
|
+
const input = buildFetchInput(url, options);
|
|
30894
|
+
const result = await this.runtime.fetch(input);
|
|
30895
|
+
if (result.response === void 0) {
|
|
30896
|
+
throw new OpensteerProtocolError(
|
|
30897
|
+
"operation-failed",
|
|
30898
|
+
result.note ?? `session.fetch did not produce a response for ${url}`
|
|
30899
|
+
);
|
|
30900
|
+
}
|
|
30901
|
+
return toResponse(result.response);
|
|
30902
|
+
});
|
|
30579
30903
|
}
|
|
30580
30904
|
async computerExecute(input) {
|
|
30581
|
-
return this.runtime.computerExecute(input);
|
|
30905
|
+
return wrapSdkError("session.computerExecute", () => this.runtime.computerExecute(input));
|
|
30582
30906
|
}
|
|
30583
30907
|
async route(input) {
|
|
30584
|
-
return
|
|
30908
|
+
return wrapSdkError(
|
|
30909
|
+
"session.route",
|
|
30910
|
+
() => this.requireOwnedInstrumentationRuntime("route").route(input)
|
|
30911
|
+
);
|
|
30585
30912
|
}
|
|
30586
30913
|
async interceptScript(input) {
|
|
30587
|
-
return
|
|
30914
|
+
return wrapSdkError(
|
|
30915
|
+
"session.interceptScript",
|
|
30916
|
+
() => this.requireOwnedInstrumentationRuntime("interceptScript").interceptScript(input)
|
|
30917
|
+
);
|
|
30588
30918
|
}
|
|
30589
30919
|
async close() {
|
|
30590
|
-
|
|
30591
|
-
|
|
30592
|
-
|
|
30593
|
-
|
|
30594
|
-
|
|
30595
|
-
|
|
30920
|
+
return wrapSdkError("session.close", async () => {
|
|
30921
|
+
if (this.browserManager === void 0 || this.browserManager.mode === "temporary") {
|
|
30922
|
+
return this.runtime.close();
|
|
30923
|
+
}
|
|
30924
|
+
const output = await this.runtime.close();
|
|
30925
|
+
await this.browserManager.close();
|
|
30926
|
+
return output;
|
|
30927
|
+
});
|
|
30596
30928
|
}
|
|
30597
30929
|
async disconnect() {
|
|
30598
|
-
|
|
30930
|
+
return wrapSdkError("session.disconnect", () => this.runtime.disconnect());
|
|
30599
30931
|
}
|
|
30600
30932
|
requireOwnedInstrumentationRuntime(method) {
|
|
30601
30933
|
if (typeof this.runtime.route === "function" && typeof this.runtime.interceptScript === "function") {
|
|
30602
30934
|
return this.runtime;
|
|
30603
30935
|
}
|
|
30604
|
-
throw new
|
|
30936
|
+
throw new OpensteerProtocolError(
|
|
30937
|
+
"unsupported-operation",
|
|
30938
|
+
`${method}() is not available for this session runtime.`
|
|
30939
|
+
);
|
|
30605
30940
|
}
|
|
30606
30941
|
};
|
|
30607
30942
|
}
|
|
@@ -30609,7 +30944,7 @@ var init_opensteer = __esm({
|
|
|
30609
30944
|
|
|
30610
30945
|
// package.json
|
|
30611
30946
|
var package_default = {
|
|
30612
|
-
version: "0.9.
|
|
30947
|
+
version: "0.9.6"};
|
|
30613
30948
|
|
|
30614
30949
|
// src/cli/bin.ts
|
|
30615
30950
|
init_browser_manager();
|
|
@@ -30624,6 +30959,110 @@ async function loadCliEnvironment(cwd) {
|
|
|
30624
30959
|
loadEnvironment(cwd);
|
|
30625
30960
|
}
|
|
30626
30961
|
|
|
30962
|
+
// src/cli/errors.ts
|
|
30963
|
+
init_src();
|
|
30964
|
+
init_src2();
|
|
30965
|
+
var CliError = class extends Error {
|
|
30966
|
+
type;
|
|
30967
|
+
usage;
|
|
30968
|
+
constructor(type, message, usage) {
|
|
30969
|
+
super(message);
|
|
30970
|
+
this.name = "CliError";
|
|
30971
|
+
this.type = type;
|
|
30972
|
+
this.usage = usage;
|
|
30973
|
+
}
|
|
30974
|
+
format() {
|
|
30975
|
+
return this.usage === void 0 ? this.message : `${this.message}
|
|
30976
|
+
Usage: ${this.usage}`;
|
|
30977
|
+
}
|
|
30978
|
+
};
|
|
30979
|
+
function isCliError(value) {
|
|
30980
|
+
return value instanceof CliError;
|
|
30981
|
+
}
|
|
30982
|
+
function formatCliErrorOutput(error) {
|
|
30983
|
+
if (isCliError(error)) {
|
|
30984
|
+
return {
|
|
30985
|
+
success: false,
|
|
30986
|
+
error: error.format(),
|
|
30987
|
+
type: error.type
|
|
30988
|
+
};
|
|
30989
|
+
}
|
|
30990
|
+
if (isOpensteerProtocolError(error)) {
|
|
30991
|
+
return {
|
|
30992
|
+
success: false,
|
|
30993
|
+
error: error.message,
|
|
30994
|
+
code: error.code,
|
|
30995
|
+
retriable: error.retriable
|
|
30996
|
+
};
|
|
30997
|
+
}
|
|
30998
|
+
if (isBrowserCoreError(error)) {
|
|
30999
|
+
return {
|
|
31000
|
+
success: false,
|
|
31001
|
+
error: error.message,
|
|
31002
|
+
code: error.code,
|
|
31003
|
+
retriable: error.retriable
|
|
31004
|
+
};
|
|
31005
|
+
}
|
|
31006
|
+
if (error instanceof Error && "opensteerError" in error) {
|
|
31007
|
+
const oe = error.opensteerError;
|
|
31008
|
+
return {
|
|
31009
|
+
success: false,
|
|
31010
|
+
error: oe.message,
|
|
31011
|
+
code: oe.code,
|
|
31012
|
+
retriable: oe.retriable
|
|
31013
|
+
};
|
|
31014
|
+
}
|
|
31015
|
+
if (error instanceof SyntaxError) {
|
|
31016
|
+
return {
|
|
31017
|
+
success: false,
|
|
31018
|
+
error: error.message,
|
|
31019
|
+
type: "invalid_value"
|
|
31020
|
+
};
|
|
31021
|
+
}
|
|
31022
|
+
return {
|
|
31023
|
+
success: false,
|
|
31024
|
+
error: error instanceof Error ? error.message : String(error)
|
|
31025
|
+
};
|
|
31026
|
+
}
|
|
31027
|
+
function emitWarning(warning) {
|
|
31028
|
+
process.stderr.write(`${JSON.stringify({ warning })}
|
|
31029
|
+
`);
|
|
31030
|
+
}
|
|
31031
|
+
var CLI_USAGE_HINTS = {
|
|
31032
|
+
"session.open": "opensteer open <url> [--workspace <id>]",
|
|
31033
|
+
"page.goto": "opensteer goto <url>",
|
|
31034
|
+
"page.evaluate": "opensteer evaluate <script>",
|
|
31035
|
+
"page.add-init-script": "opensteer init-script <script>",
|
|
31036
|
+
"dom.click": "opensteer click <element> --persist <key>",
|
|
31037
|
+
"dom.hover": "opensteer hover <element> --persist <key>",
|
|
31038
|
+
"dom.input": "opensteer input <element> <text> --persist <key>",
|
|
31039
|
+
"dom.scroll": "opensteer scroll <direction> <amount> --persist <key>",
|
|
31040
|
+
"dom.extract": "opensteer extract <template> --persist <key>",
|
|
31041
|
+
"network.detail": "opensteer network detail <recordId>",
|
|
31042
|
+
"session.fetch": "opensteer fetch <url>",
|
|
31043
|
+
"captcha.solve": "opensteer captcha solve --provider <name> --api-key <key>",
|
|
31044
|
+
"scripts.capture": "opensteer scripts capture",
|
|
31045
|
+
"scripts.beautify": "opensteer scripts beautify <artifactId>",
|
|
31046
|
+
"scripts.deobfuscate": "opensteer scripts deobfuscate <artifactId>",
|
|
31047
|
+
"scripts.sandbox": "opensteer scripts sandbox <artifactId>",
|
|
31048
|
+
"interaction.capture": "opensteer interaction capture",
|
|
31049
|
+
"interaction.get": "opensteer interaction get <traceId>",
|
|
31050
|
+
"interaction.replay": "opensteer interaction replay <traceId>",
|
|
31051
|
+
"interaction.diff": "opensteer interaction diff <leftTraceId> <rightTraceId>",
|
|
31052
|
+
"artifact.read": "opensteer artifact read <artifactId>",
|
|
31053
|
+
"computer.click": "opensteer computer click <x> <y>",
|
|
31054
|
+
"computer.type": "opensteer computer type <text>",
|
|
31055
|
+
"computer.key": "opensteer computer key <key>",
|
|
31056
|
+
"computer.scroll": "opensteer computer scroll <x> <y> --dx <n> --dy <n>",
|
|
31057
|
+
"computer.move": "opensteer computer move <x> <y>",
|
|
31058
|
+
"computer.drag": "opensteer computer drag <x1> <y1> <x2> <y2>",
|
|
31059
|
+
"computer.screenshot": "opensteer computer screenshot",
|
|
31060
|
+
exec: "opensteer exec <expression>",
|
|
31061
|
+
record: "opensteer record --url <url> --workspace <id>",
|
|
31062
|
+
"browser.inspect": "opensteer browser inspect <endpoint>",
|
|
31063
|
+
"browser.clone": "opensteer browser clone --source-user-data-dir <path>"
|
|
31064
|
+
};
|
|
31065
|
+
|
|
30627
31066
|
// src/cli/help.ts
|
|
30628
31067
|
function getHelpText() {
|
|
30629
31068
|
return `Opensteer CLI
|
|
@@ -30885,7 +31324,7 @@ function parseCommandLine(argv) {
|
|
|
30885
31324
|
const key = token.slice(2, separator === -1 ? void 0 : separator);
|
|
30886
31325
|
const spec = CLI_OPTION_SPECS[key];
|
|
30887
31326
|
if (spec === void 0) {
|
|
30888
|
-
throw new
|
|
31327
|
+
throw new CliError("unknown_option", `Unknown option: --${key}.`);
|
|
30889
31328
|
}
|
|
30890
31329
|
if (separator !== -1) {
|
|
30891
31330
|
rawOptions.set(key, [...rawOptions.get(key) ?? [], token.slice(separator + 1)]);
|
|
@@ -30914,7 +31353,8 @@ function parseCommandLine(argv) {
|
|
|
30914
31353
|
continue;
|
|
30915
31354
|
}
|
|
30916
31355
|
if (next === void 0 || next.startsWith("--")) {
|
|
30917
|
-
throw new
|
|
31356
|
+
throw new CliError(
|
|
31357
|
+
"missing_arguments",
|
|
30918
31358
|
`Option "--${key}" requires a value.${next?.startsWith("--") === true ? ` Use "--${key}=<value>" when the value begins with "--".` : ``}`
|
|
30919
31359
|
);
|
|
30920
31360
|
}
|
|
@@ -30960,10 +31400,14 @@ function parseCommandLine(argv) {
|
|
|
30960
31400
|
const autoLocalView = readOptionalBoolean(rawOptions, "auto");
|
|
30961
31401
|
const noAutoLocalView = readOptionalBoolean(rawOptions, "no-auto");
|
|
30962
31402
|
if (autoLocalView === true && noAutoLocalView === true) {
|
|
30963
|
-
throw new
|
|
31403
|
+
throw new CliError("invalid_option", 'Options "--auto" and "--no-auto" cannot be combined.');
|
|
30964
31404
|
}
|
|
30965
31405
|
if (command[0] !== "view" && (autoLocalView !== void 0 || noAutoLocalView !== void 0)) {
|
|
30966
|
-
throw new
|
|
31406
|
+
throw new CliError(
|
|
31407
|
+
"invalid_option",
|
|
31408
|
+
'Options "--auto" and "--no-auto" are only supported with "view".',
|
|
31409
|
+
"opensteer view --auto"
|
|
31410
|
+
);
|
|
30967
31411
|
}
|
|
30968
31412
|
const global = readOptionalBoolean(rawOptions, "global");
|
|
30969
31413
|
const yes = readOptionalBoolean(rawOptions, "yes");
|
|
@@ -31019,7 +31463,7 @@ function parseKeyValueList(values) {
|
|
|
31019
31463
|
values.map((entry) => {
|
|
31020
31464
|
const separator = entry.indexOf("=");
|
|
31021
31465
|
if (separator <= 0) {
|
|
31022
|
-
throw new
|
|
31466
|
+
throw new CliError("invalid_value", `Expected NAME=VALUE, received "${entry}".`);
|
|
31023
31467
|
}
|
|
31024
31468
|
return [entry.slice(0, separator), entry.slice(separator + 1)];
|
|
31025
31469
|
})
|
|
@@ -31050,7 +31494,7 @@ function readOptionalBoolean(options, name) {
|
|
|
31050
31494
|
if (value === "false") {
|
|
31051
31495
|
return false;
|
|
31052
31496
|
}
|
|
31053
|
-
throw new
|
|
31497
|
+
throw new CliError("invalid_value", `Option "--${name}" must be true or false.`);
|
|
31054
31498
|
}
|
|
31055
31499
|
function readOptionalNumber(options, name) {
|
|
31056
31500
|
const value = readSingle(options, name);
|
|
@@ -31059,13 +31503,20 @@ function readOptionalNumber(options, name) {
|
|
|
31059
31503
|
}
|
|
31060
31504
|
const parsed = Number(value);
|
|
31061
31505
|
if (!Number.isFinite(parsed)) {
|
|
31062
|
-
throw new
|
|
31506
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a number.`);
|
|
31063
31507
|
}
|
|
31064
31508
|
return parsed;
|
|
31065
31509
|
}
|
|
31066
31510
|
function readJsonValue(options, name) {
|
|
31067
31511
|
const value = readSingle(options, name);
|
|
31068
|
-
|
|
31512
|
+
if (value === void 0) {
|
|
31513
|
+
return void 0;
|
|
31514
|
+
}
|
|
31515
|
+
try {
|
|
31516
|
+
return JSON.parse(value);
|
|
31517
|
+
} catch {
|
|
31518
|
+
throw new CliError("invalid_value", `Option "--${name}" contains invalid JSON.`);
|
|
31519
|
+
}
|
|
31069
31520
|
}
|
|
31070
31521
|
function readJsonObject(options, name) {
|
|
31071
31522
|
const parsed = readJsonValue(options, name);
|
|
@@ -31073,7 +31524,7 @@ function readJsonObject(options, name) {
|
|
|
31073
31524
|
return void 0;
|
|
31074
31525
|
}
|
|
31075
31526
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31076
|
-
throw new
|
|
31527
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a JSON object.`);
|
|
31077
31528
|
}
|
|
31078
31529
|
return parsed;
|
|
31079
31530
|
}
|
|
@@ -31083,7 +31534,7 @@ function readJsonArray(options, name) {
|
|
|
31083
31534
|
return void 0;
|
|
31084
31535
|
}
|
|
31085
31536
|
if (!Array.isArray(parsed)) {
|
|
31086
|
-
throw new
|
|
31537
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a JSON array.`);
|
|
31087
31538
|
}
|
|
31088
31539
|
return parsed;
|
|
31089
31540
|
}
|
|
@@ -31103,7 +31554,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31103
31554
|
case "session.open": {
|
|
31104
31555
|
const url = parsed.rest[0];
|
|
31105
31556
|
if (url === void 0) {
|
|
31106
|
-
throw new
|
|
31557
|
+
throw new CliError("missing_arguments", "open requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
31107
31558
|
}
|
|
31108
31559
|
return {
|
|
31109
31560
|
url,
|
|
@@ -31136,7 +31587,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31136
31587
|
}
|
|
31137
31588
|
case "page.goto": {
|
|
31138
31589
|
if (parsed.rest[0] === void 0) {
|
|
31139
|
-
throw new
|
|
31590
|
+
throw new CliError("missing_arguments", "goto requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
31140
31591
|
}
|
|
31141
31592
|
const captureNetwork = readSingle(parsed.rawOptions, "capture-network");
|
|
31142
31593
|
return {
|
|
@@ -31148,14 +31599,14 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31148
31599
|
return parsed.rest[0] === void 0 ? {} : { mode: parsed.rest[0] };
|
|
31149
31600
|
case "page.evaluate":
|
|
31150
31601
|
if (parsed.rest[0] === void 0) {
|
|
31151
|
-
throw new
|
|
31602
|
+
throw new CliError("missing_arguments", "evaluate requires a script.", CLI_USAGE_HINTS[operation]);
|
|
31152
31603
|
}
|
|
31153
31604
|
return {
|
|
31154
31605
|
script: joinRest(parsed.rest, 0)
|
|
31155
31606
|
};
|
|
31156
31607
|
case "page.add-init-script":
|
|
31157
31608
|
if (parsed.rest[0] === void 0) {
|
|
31158
|
-
throw new
|
|
31609
|
+
throw new CliError("missing_arguments", "init-script requires a script.", CLI_USAGE_HINTS[operation]);
|
|
31159
31610
|
}
|
|
31160
31611
|
return {
|
|
31161
31612
|
script: joinRest(parsed.rest, 0)
|
|
@@ -31171,7 +31622,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31171
31622
|
return buildElementTargetInput(parsed, "hover");
|
|
31172
31623
|
case "dom.input": {
|
|
31173
31624
|
if (parsed.rest[1] === void 0) {
|
|
31174
|
-
throw new
|
|
31625
|
+
throw new CliError("missing_arguments", "input requires an element number and text.", CLI_USAGE_HINTS[operation]);
|
|
31175
31626
|
}
|
|
31176
31627
|
const pressEnter = readOptionalBoolean(parsed.rawOptions, "press-enter");
|
|
31177
31628
|
return {
|
|
@@ -31202,7 +31653,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31202
31653
|
}
|
|
31203
31654
|
case "dom.extract": {
|
|
31204
31655
|
if (parsed.rest[0] === void 0) {
|
|
31205
|
-
throw new
|
|
31656
|
+
throw new CliError("missing_arguments", "extract requires a template.", CLI_USAGE_HINTS[operation]);
|
|
31206
31657
|
}
|
|
31207
31658
|
const persist = readPersistKey(parsed, "extract");
|
|
31208
31659
|
return {
|
|
@@ -31238,7 +31689,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31238
31689
|
}
|
|
31239
31690
|
case "network.detail": {
|
|
31240
31691
|
if (parsed.rest[0] === void 0) {
|
|
31241
|
-
throw new
|
|
31692
|
+
throw new CliError("missing_arguments", "network detail requires a record id.", CLI_USAGE_HINTS[operation]);
|
|
31242
31693
|
}
|
|
31243
31694
|
const probeFlag = readOptionalBoolean(parsed.rawOptions, "probe");
|
|
31244
31695
|
return {
|
|
@@ -31249,7 +31700,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31249
31700
|
case "session.fetch": {
|
|
31250
31701
|
const url = parsed.rest[0];
|
|
31251
31702
|
if (url === void 0) {
|
|
31252
|
-
throw new
|
|
31703
|
+
throw new CliError("missing_arguments", "fetch requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
31253
31704
|
}
|
|
31254
31705
|
const bodyJson = readJsonValue(parsed.rawOptions, "body");
|
|
31255
31706
|
const bodyText = readSingle(parsed.rawOptions, "body-text");
|
|
@@ -31257,7 +31708,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31257
31708
|
const query = parseKeyValueList(parsed.rawOptions.get("query"));
|
|
31258
31709
|
const headers = parseKeyValueList(parsed.rawOptions.get("header"));
|
|
31259
31710
|
if (bodyJson !== void 0 && bodyText !== void 0) {
|
|
31260
|
-
throw new
|
|
31711
|
+
throw new CliError("invalid_option", 'Use either "--body" or "--body-text", not both.');
|
|
31261
31712
|
}
|
|
31262
31713
|
const transport = readSingle(parsed.rawOptions, "transport");
|
|
31263
31714
|
const cookies = readOptionalBoolean(parsed.rawOptions, "cookies");
|
|
@@ -31288,7 +31739,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31288
31739
|
const siteKey = readSingle(parsed.rawOptions, "site-key");
|
|
31289
31740
|
const pageUrl = readSingle(parsed.rawOptions, "page-url");
|
|
31290
31741
|
if (provider === void 0 || apiKey === void 0) {
|
|
31291
|
-
throw new
|
|
31742
|
+
throw new CliError("missing_arguments", 'captcha solve requires "--provider" and "--api-key".', CLI_USAGE_HINTS[operation]);
|
|
31292
31743
|
}
|
|
31293
31744
|
return {
|
|
31294
31745
|
provider: readCaptchaProvider(provider),
|
|
@@ -31318,7 +31769,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31318
31769
|
case "scripts.beautify":
|
|
31319
31770
|
case "scripts.deobfuscate": {
|
|
31320
31771
|
if (parsed.rest[0] === void 0) {
|
|
31321
|
-
throw new
|
|
31772
|
+
throw new CliError("missing_arguments", `${parsed.command.join(" ")} requires an artifact id.`, CLI_USAGE_HINTS[operation]);
|
|
31322
31773
|
}
|
|
31323
31774
|
const persist = readOptionalBoolean(parsed.rawOptions, "persist");
|
|
31324
31775
|
return {
|
|
@@ -31328,7 +31779,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31328
31779
|
}
|
|
31329
31780
|
case "scripts.sandbox":
|
|
31330
31781
|
if (parsed.rest[0] === void 0) {
|
|
31331
|
-
throw new
|
|
31782
|
+
throw new CliError("missing_arguments", "scripts sandbox requires an artifact id.", CLI_USAGE_HINTS[operation]);
|
|
31332
31783
|
}
|
|
31333
31784
|
{
|
|
31334
31785
|
const fidelity = readSingle(parsed.rawOptions, "fidelity");
|
|
@@ -31377,14 +31828,14 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31377
31828
|
case "interaction.get":
|
|
31378
31829
|
case "interaction.replay":
|
|
31379
31830
|
if (parsed.rest[0] === void 0) {
|
|
31380
|
-
throw new
|
|
31831
|
+
throw new CliError("missing_arguments", `${parsed.command.join(" ")} requires a trace id.`, CLI_USAGE_HINTS[operation]);
|
|
31381
31832
|
}
|
|
31382
31833
|
return {
|
|
31383
31834
|
traceId: parsed.rest[0]
|
|
31384
31835
|
};
|
|
31385
31836
|
case "interaction.diff":
|
|
31386
31837
|
if (parsed.rest[0] === void 0 || parsed.rest[1] === void 0) {
|
|
31387
|
-
throw new
|
|
31838
|
+
throw new CliError("missing_arguments", "interaction diff requires two trace ids.", CLI_USAGE_HINTS[operation]);
|
|
31388
31839
|
}
|
|
31389
31840
|
return {
|
|
31390
31841
|
leftTraceId: parsed.rest[0],
|
|
@@ -31392,7 +31843,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31392
31843
|
};
|
|
31393
31844
|
case "artifact.read":
|
|
31394
31845
|
if (parsed.rest[0] === void 0) {
|
|
31395
|
-
throw new
|
|
31846
|
+
throw new CliError("missing_arguments", "artifact read requires an artifact id.", CLI_USAGE_HINTS[operation]);
|
|
31396
31847
|
}
|
|
31397
31848
|
return {
|
|
31398
31849
|
artifactId: parsed.rest[0]
|
|
@@ -31400,7 +31851,8 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31400
31851
|
case "session.close":
|
|
31401
31852
|
return {};
|
|
31402
31853
|
default:
|
|
31403
|
-
throw new
|
|
31854
|
+
throw new CliError(
|
|
31855
|
+
"unsupported_operation",
|
|
31404
31856
|
`${operation} does not have a direct CLI input shape. Use a supported command or the SDK.`
|
|
31405
31857
|
);
|
|
31406
31858
|
}
|
|
@@ -31447,7 +31899,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31447
31899
|
}
|
|
31448
31900
|
case "type":
|
|
31449
31901
|
if (parsed.rest[0] === void 0) {
|
|
31450
|
-
throw new
|
|
31902
|
+
throw new CliError("missing_arguments", "computer type requires text.");
|
|
31451
31903
|
}
|
|
31452
31904
|
return {
|
|
31453
31905
|
action: {
|
|
@@ -31458,7 +31910,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31458
31910
|
};
|
|
31459
31911
|
case "key": {
|
|
31460
31912
|
if (parsed.rest[0] === void 0) {
|
|
31461
|
-
throw new
|
|
31913
|
+
throw new CliError("missing_arguments", "computer key requires a key.");
|
|
31462
31914
|
}
|
|
31463
31915
|
const modifiers = readKeyModifiers(readSingle(parsed.rawOptions, "modifiers"));
|
|
31464
31916
|
return {
|
|
@@ -31474,7 +31926,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31474
31926
|
const dx = readOptionalNumber(parsed.rawOptions, "dx");
|
|
31475
31927
|
const dy = readOptionalNumber(parsed.rawOptions, "dy");
|
|
31476
31928
|
if (dx === void 0 || dy === void 0) {
|
|
31477
|
-
throw new
|
|
31929
|
+
throw new CliError("missing_arguments", 'computer scroll requires "--dx" and "--dy".');
|
|
31478
31930
|
}
|
|
31479
31931
|
return {
|
|
31480
31932
|
action: {
|
|
@@ -31529,49 +31981,50 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31529
31981
|
}
|
|
31530
31982
|
};
|
|
31531
31983
|
default:
|
|
31532
|
-
throw new
|
|
31984
|
+
throw new CliError("unknown_command", `Unknown computer command: ${parsed.command.join(" ")}`);
|
|
31533
31985
|
}
|
|
31534
31986
|
}
|
|
31535
31987
|
async function resolvePageRefByIndex(runtime, index) {
|
|
31536
31988
|
const pages = (await runtime.listPages({})).pages;
|
|
31537
31989
|
const page = pages[index - 1];
|
|
31538
31990
|
if (page === void 0) {
|
|
31539
|
-
throw new
|
|
31991
|
+
throw new CliError("invalid_value", `tab ${String(index)} does not exist.`);
|
|
31540
31992
|
}
|
|
31541
31993
|
return page.pageRef;
|
|
31542
31994
|
}
|
|
31543
31995
|
function readRequiredPositiveInteger(value, message) {
|
|
31544
31996
|
const parsed = readRequiredNumber(value, message);
|
|
31545
31997
|
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
31546
|
-
throw new
|
|
31998
|
+
throw new CliError("missing_arguments", message);
|
|
31547
31999
|
}
|
|
31548
32000
|
return parsed;
|
|
31549
32001
|
}
|
|
31550
32002
|
function readRequiredNumber(value, message) {
|
|
31551
32003
|
if (value === void 0) {
|
|
31552
|
-
throw new
|
|
32004
|
+
throw new CliError("missing_arguments", message);
|
|
31553
32005
|
}
|
|
31554
32006
|
const parsed = Number(value);
|
|
31555
32007
|
if (!Number.isFinite(parsed)) {
|
|
31556
|
-
throw new
|
|
32008
|
+
throw new CliError("missing_arguments", message);
|
|
31557
32009
|
}
|
|
31558
32010
|
return parsed;
|
|
31559
32011
|
}
|
|
31560
32012
|
function readSingleDirection(value) {
|
|
31561
32013
|
if (value === void 0 || !SCROLL_DIRECTIONS.has(value)) {
|
|
31562
|
-
throw new
|
|
32014
|
+
throw new CliError("missing_arguments", "scroll requires a direction: up, down, left, or right.");
|
|
31563
32015
|
}
|
|
31564
32016
|
return value;
|
|
31565
32017
|
}
|
|
31566
32018
|
function readClickButton(value) {
|
|
31567
32019
|
if (value === void 0 || !CLICK_BUTTONS.has(value)) {
|
|
31568
|
-
throw new
|
|
32020
|
+
throw new CliError("invalid_value", 'Expected "--button" to be one of: left, middle, right.');
|
|
31569
32021
|
}
|
|
31570
32022
|
return value;
|
|
31571
32023
|
}
|
|
31572
32024
|
function readFetchTransport(value) {
|
|
31573
32025
|
if (value === void 0 || !FETCH_TRANSPORTS.has(value)) {
|
|
31574
|
-
throw new
|
|
32026
|
+
throw new CliError(
|
|
32027
|
+
"invalid_value",
|
|
31575
32028
|
'Expected "--transport" to be one of: auto, direct, matched-tls, context, page.'
|
|
31576
32029
|
);
|
|
31577
32030
|
}
|
|
@@ -31579,31 +32032,31 @@ function readFetchTransport(value) {
|
|
|
31579
32032
|
}
|
|
31580
32033
|
function readCaptchaProvider(value) {
|
|
31581
32034
|
if (value === void 0 || !CAPTCHA_PROVIDERS.has(value)) {
|
|
31582
|
-
throw new
|
|
32035
|
+
throw new CliError("invalid_value", 'Expected "--provider" to be one of: 2captcha, capsolver.');
|
|
31583
32036
|
}
|
|
31584
32037
|
return value;
|
|
31585
32038
|
}
|
|
31586
32039
|
function readCaptchaType(value) {
|
|
31587
32040
|
if (value === void 0 || !CAPTCHA_TYPES.has(value)) {
|
|
31588
|
-
throw new
|
|
32041
|
+
throw new CliError("invalid_value", 'Expected "--type" to be one of: recaptcha-v2, hcaptcha, turnstile.');
|
|
31589
32042
|
}
|
|
31590
32043
|
return value;
|
|
31591
32044
|
}
|
|
31592
32045
|
function readSandboxFidelity(value) {
|
|
31593
32046
|
if (value === void 0 || !SANDBOX_FIDELITIES.has(value)) {
|
|
31594
|
-
throw new
|
|
32047
|
+
throw new CliError("invalid_value", 'Expected "--fidelity" to be one of: minimal, standard, full.');
|
|
31595
32048
|
}
|
|
31596
32049
|
return value;
|
|
31597
32050
|
}
|
|
31598
32051
|
function readSandboxClockMode(value) {
|
|
31599
32052
|
if (value === void 0 || !SANDBOX_CLOCK_MODES.has(value)) {
|
|
31600
|
-
throw new
|
|
32053
|
+
throw new CliError("invalid_value", 'Expected "--clock" to be one of: real, manual.');
|
|
31601
32054
|
}
|
|
31602
32055
|
return value;
|
|
31603
32056
|
}
|
|
31604
32057
|
function readScreenshotFormat(value) {
|
|
31605
32058
|
if (value === void 0 || !SCREENSHOT_FORMATS.has(value)) {
|
|
31606
|
-
throw new
|
|
32059
|
+
throw new CliError("invalid_value", 'Expected "--format" to be one of: png, jpeg, webp.');
|
|
31607
32060
|
}
|
|
31608
32061
|
return value;
|
|
31609
32062
|
}
|
|
@@ -31614,7 +32067,7 @@ function readKeyModifiers(value) {
|
|
|
31614
32067
|
}
|
|
31615
32068
|
for (const modifier of modifiers) {
|
|
31616
32069
|
if (!KEY_MODIFIERS.has(modifier)) {
|
|
31617
|
-
throw new
|
|
32070
|
+
throw new CliError("invalid_value", 'Expected "--modifiers" to contain only: Shift, Control, Alt, Meta.');
|
|
31618
32071
|
}
|
|
31619
32072
|
}
|
|
31620
32073
|
return [...new Set(modifiers)];
|
|
@@ -31622,17 +32075,22 @@ function readKeyModifiers(value) {
|
|
|
31622
32075
|
function readPersistKey(parsed, verb) {
|
|
31623
32076
|
const value = readSingle(parsed.rawOptions, "persist");
|
|
31624
32077
|
if (value === void 0) {
|
|
31625
|
-
throw new
|
|
32078
|
+
throw new CliError("missing_arguments", `${verb} requires "--persist <key>".`);
|
|
31626
32079
|
}
|
|
31627
32080
|
if (value === "true" || value === "false") {
|
|
31628
|
-
throw new
|
|
32081
|
+
throw new CliError("missing_arguments", `${verb} requires "--persist <key>".`);
|
|
31629
32082
|
}
|
|
31630
32083
|
return value;
|
|
31631
32084
|
}
|
|
31632
32085
|
function parseRequiredJsonObjectArgument(value, label) {
|
|
31633
|
-
|
|
32086
|
+
let parsed;
|
|
32087
|
+
try {
|
|
32088
|
+
parsed = JSON.parse(value);
|
|
32089
|
+
} catch {
|
|
32090
|
+
throw new CliError("invalid_value", `${label} contains invalid JSON.`);
|
|
32091
|
+
}
|
|
31634
32092
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31635
|
-
throw new
|
|
32093
|
+
throw new CliError("invalid_value", `${label} must be a JSON object.`);
|
|
31636
32094
|
}
|
|
31637
32095
|
return parsed;
|
|
31638
32096
|
}
|
|
@@ -34610,7 +35068,7 @@ async function handleViewCommand(parsed, options = {}) {
|
|
|
34610
35068
|
return;
|
|
34611
35069
|
}
|
|
34612
35070
|
if (subcommand !== void 0) {
|
|
34613
|
-
throw new
|
|
35071
|
+
throw new CliError("unknown_command", `Unknown view command: view ${subcommand}`);
|
|
34614
35072
|
}
|
|
34615
35073
|
if (parsed.options.localViewMode !== void 0) {
|
|
34616
35074
|
const preference = await setLocalViewMode(parsed.options.localViewMode);
|
|
@@ -34658,7 +35116,10 @@ async function resolveWorkspaceSessionId(input) {
|
|
|
34658
35116
|
}
|
|
34659
35117
|
function assertNoViewPreferenceFlag(parsed) {
|
|
34660
35118
|
if (parsed.options.localViewMode !== void 0) {
|
|
34661
|
-
throw new
|
|
35119
|
+
throw new CliError(
|
|
35120
|
+
"invalid_option",
|
|
35121
|
+
"View preference flags cannot be combined with this subcommand."
|
|
35122
|
+
);
|
|
34662
35123
|
}
|
|
34663
35124
|
}
|
|
34664
35125
|
function writeViewOutput(parsed, value) {
|
|
@@ -34743,10 +35204,10 @@ async function main() {
|
|
|
34743
35204
|
}
|
|
34744
35205
|
const operation = resolveOperation(parsed.command);
|
|
34745
35206
|
if (!operation) {
|
|
34746
|
-
throw new
|
|
35207
|
+
throw new CliError("unknown_command", `Unknown command: ${parsed.command.join(" ")}`);
|
|
34747
35208
|
}
|
|
34748
35209
|
if (parsed.options.workspace === void 0) {
|
|
34749
|
-
throw new
|
|
35210
|
+
throw new CliError("missing_workspace", 'Stateful commands require "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
34750
35211
|
}
|
|
34751
35212
|
const { engineName, provider, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
34752
35213
|
if (operation === "session.close") {
|
|
@@ -34768,24 +35229,39 @@ async function main() {
|
|
|
34768
35229
|
let renderOperation = operation;
|
|
34769
35230
|
try {
|
|
34770
35231
|
const input = await buildOperationInput(operation, parsed, runtime);
|
|
34771
|
-
|
|
35232
|
+
const rawResult = await dispatchSemanticOperation(runtime, operation, input);
|
|
34772
35233
|
if (parsed.command[0] === "tab" && operation !== "page.list") {
|
|
34773
35234
|
renderOperation = "page.list";
|
|
34774
35235
|
result = await runtime.listPages({});
|
|
35236
|
+
} else {
|
|
35237
|
+
result = rawResult;
|
|
35238
|
+
}
|
|
35239
|
+
let warning;
|
|
35240
|
+
if (result !== null && typeof result === "object" && "warning" in result) {
|
|
35241
|
+
const { warning: w, ...rest } = result;
|
|
35242
|
+
if (typeof w === "string") {
|
|
35243
|
+
warning = w;
|
|
35244
|
+
result = rest;
|
|
35245
|
+
}
|
|
34775
35246
|
}
|
|
34776
35247
|
process4__default.default.stdout.write(renderOperationOutput(renderOperation, result, input));
|
|
35248
|
+
if (warning !== void 0) {
|
|
35249
|
+
emitWarning(warning);
|
|
35250
|
+
}
|
|
34777
35251
|
} finally {
|
|
34778
35252
|
await runtime.disconnect().catch(() => void 0);
|
|
34779
35253
|
}
|
|
34780
35254
|
}
|
|
34781
35255
|
async function handleExecCommand(parsed) {
|
|
34782
35256
|
if (parsed.options.workspace === void 0) {
|
|
34783
|
-
throw new
|
|
35257
|
+
throw new CliError("missing_workspace", 'exec requires "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
34784
35258
|
}
|
|
34785
35259
|
const expression = parsed.rest.join(" ");
|
|
34786
35260
|
if (!expression) {
|
|
34787
|
-
throw new
|
|
34788
|
-
|
|
35261
|
+
throw new CliError(
|
|
35262
|
+
"missing_arguments",
|
|
35263
|
+
"exec requires an expression.",
|
|
35264
|
+
"opensteer exec <expression>"
|
|
34789
35265
|
);
|
|
34790
35266
|
}
|
|
34791
35267
|
const { engineName, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
@@ -34821,8 +35297,10 @@ async function handleBrowserCommand(parsed) {
|
|
|
34821
35297
|
if (subcommand === "inspect") {
|
|
34822
35298
|
const endpoint = parsed.options.attachEndpoint ?? parsed.rest[0];
|
|
34823
35299
|
if (!endpoint) {
|
|
34824
|
-
throw new
|
|
34825
|
-
|
|
35300
|
+
throw new CliError(
|
|
35301
|
+
"missing_arguments",
|
|
35302
|
+
'browser inspect requires "--attach-endpoint <url>" or a positional endpoint.',
|
|
35303
|
+
"opensteer browser inspect <endpoint>"
|
|
34826
35304
|
);
|
|
34827
35305
|
}
|
|
34828
35306
|
const result = await inspectCdpEndpoint({
|
|
@@ -34835,7 +35313,8 @@ async function handleBrowserCommand(parsed) {
|
|
|
34835
35313
|
return;
|
|
34836
35314
|
}
|
|
34837
35315
|
if (parsed.options.workspace === void 0) {
|
|
34838
|
-
throw new
|
|
35316
|
+
throw new CliError(
|
|
35317
|
+
"missing_workspace",
|
|
34839
35318
|
'Browser workspace commands require "--workspace <id>" or OPENSTEER_WORKSPACE.'
|
|
34840
35319
|
);
|
|
34841
35320
|
}
|
|
@@ -34858,7 +35337,11 @@ async function handleBrowserCommand(parsed) {
|
|
|
34858
35337
|
case "clone": {
|
|
34859
35338
|
const sourceUserDataDir = parsed.options.sourceUserDataDir;
|
|
34860
35339
|
if (!sourceUserDataDir) {
|
|
34861
|
-
throw new
|
|
35340
|
+
throw new CliError(
|
|
35341
|
+
"missing_arguments",
|
|
35342
|
+
'browser clone requires "--source-user-data-dir <path>".',
|
|
35343
|
+
"opensteer browser clone --source-user-data-dir <path>"
|
|
35344
|
+
);
|
|
34862
35345
|
}
|
|
34863
35346
|
const result = await manager.clonePersistentBrowser({
|
|
34864
35347
|
sourceUserDataDir,
|
|
@@ -34881,7 +35364,7 @@ async function handleBrowserCommand(parsed) {
|
|
|
34881
35364
|
return;
|
|
34882
35365
|
}
|
|
34883
35366
|
default:
|
|
34884
|
-
throw new
|
|
35367
|
+
throw new CliError("unknown_command", `Unknown browser command: ${parsed.command.join(" ")}`);
|
|
34885
35368
|
}
|
|
34886
35369
|
}
|
|
34887
35370
|
async function handleCloseCommand(parsed, engineName, providerMode, runtimeProvider) {
|
|
@@ -34914,23 +35397,27 @@ async function handleCloseCommand(parsed, engineName, providerMode, runtimeProvi
|
|
|
34914
35397
|
}
|
|
34915
35398
|
async function handleRecordCommandEntry(parsed) {
|
|
34916
35399
|
if (parsed.options.workspace === void 0) {
|
|
34917
|
-
throw new
|
|
35400
|
+
throw new CliError("missing_workspace", 'record requires "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
34918
35401
|
}
|
|
34919
35402
|
const url = parsed.options.url ?? parsed.rest[0];
|
|
34920
35403
|
if (url === void 0) {
|
|
34921
|
-
throw new
|
|
35404
|
+
throw new CliError(
|
|
35405
|
+
"missing_arguments",
|
|
35406
|
+
'record requires "--url <value>" or a positional URL.',
|
|
35407
|
+
"opensteer record --url <url> --workspace <id>"
|
|
35408
|
+
);
|
|
34922
35409
|
}
|
|
34923
35410
|
const provider = resolveCliProvider(parsed);
|
|
34924
35411
|
assertCloudCliOptionsMatchProvider(parsed, provider.mode);
|
|
34925
35412
|
const engineName = resolveCliEngineName(parsed);
|
|
34926
35413
|
if (engineName !== "playwright") {
|
|
34927
|
-
throw new
|
|
35414
|
+
throw new CliError("config_conflict", "record requires engine=playwright.");
|
|
34928
35415
|
}
|
|
34929
35416
|
const rootDir = process4__default.default.cwd();
|
|
34930
35417
|
const recordBrowser = parsed.options.browser;
|
|
34931
35418
|
if (provider.mode === "cloud") {
|
|
34932
35419
|
if (typeof recordBrowser === "object") {
|
|
34933
|
-
throw new
|
|
35420
|
+
throw new CliError("config_conflict", 'record does not support browser.mode="attach".');
|
|
34934
35421
|
}
|
|
34935
35422
|
const runtimeProvider = buildCliRuntimeProvider(parsed, provider.mode);
|
|
34936
35423
|
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
@@ -34950,10 +35437,10 @@ async function handleRecordCommandEntry(parsed) {
|
|
|
34950
35437
|
return;
|
|
34951
35438
|
}
|
|
34952
35439
|
if (parsed.options.launch?.headless === true) {
|
|
34953
|
-
throw new
|
|
35440
|
+
throw new CliError("config_conflict", 'record requires a headed browser. Remove "--headless true".');
|
|
34954
35441
|
}
|
|
34955
35442
|
if (typeof recordBrowser === "object") {
|
|
34956
|
-
throw new
|
|
35443
|
+
throw new CliError("config_conflict", 'record does not support browser.mode="attach".');
|
|
34957
35444
|
}
|
|
34958
35445
|
const launch = {
|
|
34959
35446
|
...parsed.options.launch ?? {},
|
|
@@ -35022,7 +35509,7 @@ function resolveCliBootstrapAction(argv) {
|
|
|
35022
35509
|
}
|
|
35023
35510
|
function buildCliBrowserProfile(parsed) {
|
|
35024
35511
|
if (parsed.options.cloudProfileReuseIfActive === true && parsed.options.cloudProfileId === void 0) {
|
|
35025
|
-
throw new
|
|
35512
|
+
throw new CliError("invalid_option", '"--cloud-profile-reuse-if-active" requires "--cloud-profile-id <id>".');
|
|
35026
35513
|
}
|
|
35027
35514
|
return parsed.options.cloudProfileId === void 0 ? void 0 : {
|
|
35028
35515
|
profileId: parsed.options.cloudProfileId,
|
|
@@ -35083,7 +35570,8 @@ function buildCliRuntimeProvider(parsed, providerMode) {
|
|
|
35083
35570
|
}
|
|
35084
35571
|
function assertCloudCliOptionsMatchProvider(parsed, providerMode) {
|
|
35085
35572
|
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)) {
|
|
35086
|
-
throw new
|
|
35573
|
+
throw new CliError(
|
|
35574
|
+
"config_conflict",
|
|
35087
35575
|
'Cloud-specific options require provider=cloud. Set "--provider cloud" or OPENSTEER_PROVIDER=cloud.'
|
|
35088
35576
|
);
|
|
35089
35577
|
}
|
|
@@ -35117,17 +35605,7 @@ function printVersion() {
|
|
|
35117
35605
|
`);
|
|
35118
35606
|
}
|
|
35119
35607
|
main().catch((error) => {
|
|
35120
|
-
const payload = error
|
|
35121
|
-
error: {
|
|
35122
|
-
name: error.name,
|
|
35123
|
-
message: error.message
|
|
35124
|
-
}
|
|
35125
|
-
} : {
|
|
35126
|
-
error: {
|
|
35127
|
-
name: "Error",
|
|
35128
|
-
message: String(error)
|
|
35129
|
-
}
|
|
35130
|
-
};
|
|
35608
|
+
const payload = formatCliErrorOutput(error);
|
|
35131
35609
|
process4__default.default.stderr.write(`${JSON.stringify(payload)}
|
|
35132
35610
|
`);
|
|
35133
35611
|
process4__default.default.exitCode = 1;
|