opensteer 0.9.5 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7LQL5YUR.js → chunk-3OHKIPBD.js} +571 -738
- package/dist/chunk-3OHKIPBD.js.map +1 -0
- package/dist/chunk-52UNH5UW.js +458 -0
- package/dist/chunk-52UNH5UW.js.map +1 -0
- package/dist/{chunk-GSCQQKZZ.js → chunk-PJXN7HED.js} +334 -18
- package/dist/chunk-PJXN7HED.js.map +1 -0
- package/dist/{chunk-ZRF7WMS3.js → chunk-R33BXCMQ.js} +16 -7
- package/dist/chunk-R33BXCMQ.js.map +1 -0
- package/dist/{chunk-T5P2QGZ3.js → chunk-U4BUCIZ4.js} +153 -12
- package/dist/chunk-U4BUCIZ4.js.map +1 -0
- package/dist/cli/bin.cjs +1421 -824
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +286 -129
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +1117 -703
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -53
- package/dist/index.d.ts +58 -53
- package/dist/index.js +4 -4
- package/dist/local-view/public/assets/app.js +10 -1
- package/dist/local-view/serve-entry.cjs +6815 -1272
- package/dist/local-view/serve-entry.cjs.map +1 -1
- package/dist/local-view/serve-entry.js +2 -2
- package/dist/opensteer-CY2QUJEG.js +6 -0
- package/dist/{opensteer-T2JENADR.js.map → opensteer-CY2QUJEG.js.map} +1 -1
- package/dist/{session-control-M3JD7ZKA.js → session-control-FIP6ZJLH.js} +4 -4
- package/dist/{session-control-M3JD7ZKA.js.map → session-control-FIP6ZJLH.js.map} +1 -1
- package/package.json +7 -7
- package/dist/chunk-7D45QUZ3.js +0 -332
- package/dist/chunk-7D45QUZ3.js.map +0 -1
- package/dist/chunk-7LQL5YUR.js.map +0 -1
- package/dist/chunk-GSCQQKZZ.js.map +0 -1
- package/dist/chunk-T5P2QGZ3.js.map +0 -1
- package/dist/chunk-ZRF7WMS3.js.map +0 -1
- package/dist/opensteer-T2JENADR.js +0 -6
package/dist/cli/bin.cjs
CHANGED
|
@@ -1662,31 +1662,131 @@ function isAlreadyExistsError(error) {
|
|
|
1662
1662
|
}
|
|
1663
1663
|
async function withFilesystemLock(lockPath, task) {
|
|
1664
1664
|
await ensureDirectory(path10__default.default.dirname(lockPath));
|
|
1665
|
+
const ownerToken = crypto.randomUUID();
|
|
1665
1666
|
let attempt = 0;
|
|
1666
1667
|
while (true) {
|
|
1667
1668
|
try {
|
|
1668
1669
|
await promises.mkdir(lockPath);
|
|
1670
|
+
const acquiredAt = Date.now();
|
|
1671
|
+
await writeLockMetadata(lockPath, {
|
|
1672
|
+
version: LOCK_METADATA_VERSION,
|
|
1673
|
+
ownerToken,
|
|
1674
|
+
pid: process.pid,
|
|
1675
|
+
acquiredAt,
|
|
1676
|
+
heartbeatAt: acquiredAt
|
|
1677
|
+
});
|
|
1669
1678
|
break;
|
|
1670
1679
|
} catch (error) {
|
|
1671
1680
|
if (!isAlreadyExistsError(error)) {
|
|
1672
1681
|
throw error;
|
|
1673
1682
|
}
|
|
1683
|
+
if (await tryRecoverFilesystemLock(lockPath)) {
|
|
1684
|
+
attempt = 0;
|
|
1685
|
+
continue;
|
|
1686
|
+
}
|
|
1674
1687
|
const delayMs = LOCK_RETRY_DELAYS_MS[Math.min(attempt, LOCK_RETRY_DELAYS_MS.length - 1)];
|
|
1675
1688
|
attempt += 1;
|
|
1676
1689
|
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
1677
1690
|
}
|
|
1678
1691
|
}
|
|
1692
|
+
const heartbeatTimer = setInterval(() => {
|
|
1693
|
+
void touchLockMetadata(lockPath, ownerToken);
|
|
1694
|
+
}, LOCK_HEARTBEAT_INTERVAL_MS);
|
|
1695
|
+
heartbeatTimer.unref?.();
|
|
1679
1696
|
try {
|
|
1680
1697
|
return await task();
|
|
1681
1698
|
} finally {
|
|
1682
|
-
|
|
1699
|
+
clearInterval(heartbeatTimer);
|
|
1700
|
+
const metadata = await readLockMetadata(lockPath);
|
|
1701
|
+
if (metadata?.ownerToken === ownerToken) {
|
|
1702
|
+
await promises.rm(lockPath, { recursive: true, force: true });
|
|
1703
|
+
}
|
|
1683
1704
|
}
|
|
1684
1705
|
}
|
|
1685
|
-
|
|
1706
|
+
async function tryRecoverFilesystemLock(lockPath) {
|
|
1707
|
+
if (!await shouldRecoverFilesystemLock(lockPath)) {
|
|
1708
|
+
return false;
|
|
1709
|
+
}
|
|
1710
|
+
await promises.rm(lockPath, { recursive: true, force: true });
|
|
1711
|
+
return true;
|
|
1712
|
+
}
|
|
1713
|
+
async function shouldRecoverFilesystemLock(lockPath) {
|
|
1714
|
+
const metadata = await readLockMetadata(lockPath);
|
|
1715
|
+
if (metadata !== void 0) {
|
|
1716
|
+
if (isProcessRunning2(metadata.pid)) {
|
|
1717
|
+
return false;
|
|
1718
|
+
}
|
|
1719
|
+
return Date.now() - metadata.heartbeatAt >= LOCK_ORPHAN_GRACE_MS;
|
|
1720
|
+
}
|
|
1721
|
+
const lockStat = await promises.stat(lockPath).catch(() => void 0);
|
|
1722
|
+
if (lockStat === void 0) {
|
|
1723
|
+
return false;
|
|
1724
|
+
}
|
|
1725
|
+
return Date.now() - lockStat.mtimeMs >= LOCK_METADATALESS_STALE_MS;
|
|
1726
|
+
}
|
|
1727
|
+
async function readLockMetadata(lockPath) {
|
|
1728
|
+
const metadataPath = path10__default.default.join(lockPath, LOCK_METADATA_FILENAME);
|
|
1729
|
+
if (!await pathExists(metadataPath)) {
|
|
1730
|
+
return void 0;
|
|
1731
|
+
}
|
|
1732
|
+
try {
|
|
1733
|
+
const parsed = await readJsonFile(metadataPath);
|
|
1734
|
+
const pid = parsed.pid;
|
|
1735
|
+
const acquiredAt = parsed.acquiredAt;
|
|
1736
|
+
const heartbeatAt = parsed.heartbeatAt;
|
|
1737
|
+
if (parsed.version !== LOCK_METADATA_VERSION || typeof parsed.ownerToken !== "string" || parsed.ownerToken.length === 0 || typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0 || typeof acquiredAt !== "number" || !Number.isFinite(acquiredAt) || typeof heartbeatAt !== "number" || !Number.isFinite(heartbeatAt)) {
|
|
1738
|
+
return void 0;
|
|
1739
|
+
}
|
|
1740
|
+
return {
|
|
1741
|
+
version: LOCK_METADATA_VERSION,
|
|
1742
|
+
ownerToken: parsed.ownerToken,
|
|
1743
|
+
pid,
|
|
1744
|
+
acquiredAt,
|
|
1745
|
+
heartbeatAt
|
|
1746
|
+
};
|
|
1747
|
+
} catch {
|
|
1748
|
+
return void 0;
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
async function writeLockMetadata(lockPath, metadata) {
|
|
1752
|
+
try {
|
|
1753
|
+
await writeJsonFileAtomic(path10__default.default.join(lockPath, LOCK_METADATA_FILENAME), metadata);
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
await promises.rm(lockPath, { recursive: true, force: true }).catch(() => void 0);
|
|
1756
|
+
throw error;
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
async function touchLockMetadata(lockPath, ownerToken) {
|
|
1760
|
+
const metadata = await readLockMetadata(lockPath);
|
|
1761
|
+
if (metadata === void 0 || metadata.ownerToken !== ownerToken) {
|
|
1762
|
+
return;
|
|
1763
|
+
}
|
|
1764
|
+
await writeJsonFileAtomic(path10__default.default.join(lockPath, LOCK_METADATA_FILENAME), {
|
|
1765
|
+
...metadata,
|
|
1766
|
+
heartbeatAt: Date.now()
|
|
1767
|
+
}).catch(() => void 0);
|
|
1768
|
+
}
|
|
1769
|
+
function isProcessRunning2(pid) {
|
|
1770
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
1771
|
+
return false;
|
|
1772
|
+
}
|
|
1773
|
+
try {
|
|
1774
|
+
process.kill(pid, 0);
|
|
1775
|
+
return true;
|
|
1776
|
+
} catch (error) {
|
|
1777
|
+
return error?.code === "EPERM";
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
var LOCK_RETRY_DELAYS_MS, LOCK_METADATA_FILENAME, LOCK_METADATA_VERSION, LOCK_HEARTBEAT_INTERVAL_MS, LOCK_ORPHAN_GRACE_MS, LOCK_METADATALESS_STALE_MS;
|
|
1686
1781
|
var init_filesystem = __esm({
|
|
1687
1782
|
"../runtime-core/src/internal/filesystem.ts"() {
|
|
1688
1783
|
init_json();
|
|
1689
1784
|
LOCK_RETRY_DELAYS_MS = [1, 2, 5, 10, 20, 50];
|
|
1785
|
+
LOCK_METADATA_FILENAME = "owner.json";
|
|
1786
|
+
LOCK_METADATA_VERSION = 1;
|
|
1787
|
+
LOCK_HEARTBEAT_INTERVAL_MS = 1e3;
|
|
1788
|
+
LOCK_ORPHAN_GRACE_MS = 2e3;
|
|
1789
|
+
LOCK_METADATALESS_STALE_MS = 3e4;
|
|
1690
1790
|
}
|
|
1691
1791
|
});
|
|
1692
1792
|
function normalizeScope(scope) {
|
|
@@ -2294,7 +2394,7 @@ var init_version = __esm({
|
|
|
2294
2394
|
"../protocol/src/version.ts"() {
|
|
2295
2395
|
init_json2();
|
|
2296
2396
|
OPENSTEER_PROTOCOL_NAME = "opensteer";
|
|
2297
|
-
OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION =
|
|
2397
|
+
OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION = 3;
|
|
2298
2398
|
OPENSTEER_PROTOCOL_VERSION = `0.${OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION}.0`;
|
|
2299
2399
|
OPENSTEER_PROTOCOL_MEDIA_TYPE = `application/vnd.${OPENSTEER_PROTOCOL_NAME}+json;version=${OPENSTEER_PROTOCOL_VERSION}`;
|
|
2300
2400
|
OPENSTEER_PROTOCOL_REST_BASE_PATH = `/api/v${OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION}`;
|
|
@@ -2598,10 +2698,8 @@ var init_cdp_dom_snapshot = __esm({
|
|
|
2598
2698
|
});
|
|
2599
2699
|
|
|
2600
2700
|
// ../browser-core/src/cdp-visual-stability.ts
|
|
2601
|
-
var DEFAULT_VISUAL_STABILITY_SETTLE_MS;
|
|
2602
2701
|
var init_cdp_visual_stability = __esm({
|
|
2603
2702
|
"../browser-core/src/cdp-visual-stability.ts"() {
|
|
2604
|
-
DEFAULT_VISUAL_STABILITY_SETTLE_MS = 750;
|
|
2605
2703
|
}
|
|
2606
2704
|
});
|
|
2607
2705
|
|
|
@@ -6679,15 +6777,15 @@ function assertValidSemanticOperationInput(name, input) {
|
|
|
6679
6777
|
}
|
|
6680
6778
|
);
|
|
6681
6779
|
}
|
|
6682
|
-
var opensteerComputerAnnotationNames, opensteerExposedSemanticOperationNames, opensteerPackageRunnableSemanticOperationNames, snapshotModeSchema, viewportSchema, opensteerBrowserLaunchOptionsSchema, attachBrowserOptionsSchema, opensteerBrowserOptionsSchema, opensteerBrowserContextOptionsSchema, targetByElementSchema2, targetByPersistSchema2, targetBySelectorSchema2, opensteerTargetInputSchema,
|
|
6780
|
+
var opensteerComputerAnnotationNames, opensteerExposedSemanticOperationNames, opensteerPackageRunnableSemanticOperationNames, snapshotModeSchema, viewportSchema, opensteerBrowserLaunchOptionsSchema, attachBrowserOptionsSchema, opensteerBrowserOptionsSchema, opensteerBrowserContextOptionsSchema, targetByElementSchema2, targetByPersistSchema2, targetBySelectorSchema2, opensteerTargetInputSchema, opensteerActionResultSchema, opensteerSnapshotCounterSchema, opensteerNavigationSummarySchema, opensteerOpenInputSchema, opensteerPageListInputSchema, opensteerPageListOutputSchema, opensteerPageNewInputSchema, opensteerPageActivateInputSchema, opensteerPageCloseInputSchema, opensteerPageCloseOutputSchema, opensteerPageNewOutputSchema, opensteerPageGotoInputSchema, opensteerPageEvaluateInputSchema, opensteerPageEvaluateOutputSchema, opensteerAddInitScriptInputSchema, opensteerAddInitScriptOutputSchema, opensteerCapturedScriptSchema, opensteerCaptureScriptsInputSchema, opensteerCaptureScriptsOutputSchema, opensteerPageSnapshotInputSchema, opensteerPageSnapshotOutputSchema, opensteerComputerMouseButtonSchema, opensteerComputerKeyModifierSchema, opensteerDomClickInputSchema, opensteerDomHoverInputSchema, opensteerDomInputInputSchema, opensteerDomScrollInputSchema, opensteerExtractTemplateSchema, opensteerDomExtractInputSchema, jsonValueSchema2, opensteerDomExtractOutputSchema, opensteerSessionCloseInputSchema, opensteerSessionCloseOutputSchema, opensteerComputerAnnotationSchema, opensteerComputerClickActionSchema, opensteerComputerMoveActionSchema, opensteerComputerScrollActionSchema, opensteerComputerTypeActionSchema, opensteerComputerKeyActionSchema, opensteerComputerDragActionSchema, opensteerComputerScreenshotActionSchema, opensteerComputerWaitActionSchema, opensteerComputerActionSchema, opensteerComputerScreenshotOptionsSchema, opensteerComputerExecuteInputSchema, opensteerScreenshotSummarySchema, opensteerComputerExecuteOutputSchema, opensteerSemanticOperationSpecificationsBase, exposedSemanticOperationNameSet, opensteerSemanticOperationSpecificationsInternal, opensteerSemanticOperationSpecifications, opensteerSemanticOperationSpecificationMap, semanticRestBasePath, opensteerSemanticRestEndpoints;
|
|
6683
6781
|
var init_semantic = __esm({
|
|
6684
6782
|
"../protocol/src/semantic.ts"() {
|
|
6685
6783
|
init_json2();
|
|
6686
6784
|
init_errors2();
|
|
6785
|
+
init_binary_location();
|
|
6687
6786
|
init_identity2();
|
|
6688
6787
|
init_geometry2();
|
|
6689
6788
|
init_metadata2();
|
|
6690
|
-
init_events2();
|
|
6691
6789
|
init_envelopes();
|
|
6692
6790
|
init_snapshots2();
|
|
6693
6791
|
init_artifacts2();
|
|
@@ -6911,39 +7009,14 @@ var init_semantic = __esm({
|
|
|
6911
7009
|
title: "OpensteerTargetInput"
|
|
6912
7010
|
}
|
|
6913
7011
|
);
|
|
6914
|
-
opensteerResolvedTargetSchema = objectSchema(
|
|
6915
|
-
{
|
|
6916
|
-
pageRef: pageRefSchema,
|
|
6917
|
-
frameRef: frameRefSchema,
|
|
6918
|
-
documentRef: documentRefSchema,
|
|
6919
|
-
documentEpoch: documentEpochSchema,
|
|
6920
|
-
nodeRef: nodeRefSchema,
|
|
6921
|
-
tagName: stringSchema(),
|
|
6922
|
-
pathHint: stringSchema(),
|
|
6923
|
-
persist: stringSchema(),
|
|
6924
|
-
selectorUsed: stringSchema()
|
|
6925
|
-
},
|
|
6926
|
-
{
|
|
6927
|
-
title: "OpensteerResolvedTarget",
|
|
6928
|
-
required: [
|
|
6929
|
-
"pageRef",
|
|
6930
|
-
"frameRef",
|
|
6931
|
-
"documentRef",
|
|
6932
|
-
"documentEpoch",
|
|
6933
|
-
"nodeRef",
|
|
6934
|
-
"tagName",
|
|
6935
|
-
"pathHint"
|
|
6936
|
-
]
|
|
6937
|
-
}
|
|
6938
|
-
);
|
|
6939
7012
|
opensteerActionResultSchema = objectSchema(
|
|
6940
7013
|
{
|
|
6941
|
-
|
|
6942
|
-
|
|
7014
|
+
tagName: stringSchema({ minLength: 1 }),
|
|
7015
|
+
persist: stringSchema({ minLength: 1 })
|
|
6943
7016
|
},
|
|
6944
7017
|
{
|
|
6945
7018
|
title: "OpensteerActionResult",
|
|
6946
|
-
required: ["
|
|
7019
|
+
required: ["tagName"]
|
|
6947
7020
|
}
|
|
6948
7021
|
);
|
|
6949
7022
|
opensteerSnapshotCounterSchema = objectSchema(
|
|
@@ -6989,16 +7062,14 @@ var init_semantic = __esm({
|
|
|
6989
7062
|
]
|
|
6990
7063
|
}
|
|
6991
7064
|
);
|
|
6992
|
-
|
|
7065
|
+
opensteerNavigationSummarySchema = objectSchema(
|
|
6993
7066
|
{
|
|
6994
|
-
sessionRef: sessionRefSchema,
|
|
6995
|
-
pageRef: pageRefSchema,
|
|
6996
7067
|
url: stringSchema(),
|
|
6997
7068
|
title: stringSchema()
|
|
6998
7069
|
},
|
|
6999
7070
|
{
|
|
7000
|
-
title: "
|
|
7001
|
-
required: ["
|
|
7071
|
+
title: "OpensteerNavigationSummary",
|
|
7072
|
+
required: ["url", "title"]
|
|
7002
7073
|
}
|
|
7003
7074
|
);
|
|
7004
7075
|
opensteerOpenInputSchema = objectSchema(
|
|
@@ -7066,6 +7137,17 @@ var init_semantic = __esm({
|
|
|
7066
7137
|
required: ["closedPageRef", "pages"]
|
|
7067
7138
|
}
|
|
7068
7139
|
);
|
|
7140
|
+
opensteerPageNewOutputSchema = objectSchema(
|
|
7141
|
+
{
|
|
7142
|
+
pageRef: pageRefSchema,
|
|
7143
|
+
url: stringSchema(),
|
|
7144
|
+
title: stringSchema()
|
|
7145
|
+
},
|
|
7146
|
+
{
|
|
7147
|
+
title: "OpensteerPageNewOutput",
|
|
7148
|
+
required: ["pageRef", "url", "title"]
|
|
7149
|
+
}
|
|
7150
|
+
);
|
|
7069
7151
|
opensteerPageGotoInputSchema = objectSchema(
|
|
7070
7152
|
{
|
|
7071
7153
|
url: stringSchema(),
|
|
@@ -7452,72 +7534,28 @@ var init_semantic = __esm({
|
|
|
7452
7534
|
required: ["action"]
|
|
7453
7535
|
}
|
|
7454
7536
|
);
|
|
7455
|
-
|
|
7456
|
-
{
|
|
7457
|
-
role: enumSchema(["point", "start", "end"]),
|
|
7458
|
-
point: pointSchema,
|
|
7459
|
-
hitTest: hitTestResultSchema,
|
|
7460
|
-
target: opensteerResolvedTargetSchema
|
|
7461
|
-
},
|
|
7462
|
-
{
|
|
7463
|
-
title: "OpensteerComputerTracePoint",
|
|
7464
|
-
required: ["role", "point"]
|
|
7465
|
-
}
|
|
7466
|
-
);
|
|
7467
|
-
opensteerComputerTraceEnrichmentSchema = objectSchema(
|
|
7537
|
+
opensteerScreenshotSummarySchema = objectSchema(
|
|
7468
7538
|
{
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
}
|
|
7475
|
-
);
|
|
7476
|
-
opensteerComputerExecuteTimingSchema = objectSchema(
|
|
7477
|
-
{
|
|
7478
|
-
actionMs: integerSchema({ minimum: 0 }),
|
|
7479
|
-
waitMs: integerSchema({ minimum: 0 }),
|
|
7480
|
-
totalMs: integerSchema({ minimum: 0 })
|
|
7481
|
-
},
|
|
7482
|
-
{
|
|
7483
|
-
title: "OpensteerComputerExecuteTiming",
|
|
7484
|
-
required: ["actionMs", "waitMs", "totalMs"]
|
|
7485
|
-
}
|
|
7486
|
-
);
|
|
7487
|
-
opensteerComputerDisplayScaleSchema = objectSchema(
|
|
7488
|
-
{
|
|
7489
|
-
x: numberSchema({ exclusiveMinimum: 0 }),
|
|
7490
|
-
y: numberSchema({ exclusiveMinimum: 0 })
|
|
7539
|
+
payload: externalBinaryLocationSchema,
|
|
7540
|
+
format: screenshotFormatSchema,
|
|
7541
|
+
size: sizeSchema,
|
|
7542
|
+
coordinateSpace: coordinateSpaceSchema,
|
|
7543
|
+
clip: rectSchema
|
|
7491
7544
|
},
|
|
7492
7545
|
{
|
|
7493
|
-
title: "
|
|
7494
|
-
required: ["
|
|
7546
|
+
title: "OpensteerScreenshotSummary",
|
|
7547
|
+
required: ["payload", "format", "size", "coordinateSpace"]
|
|
7495
7548
|
}
|
|
7496
7549
|
);
|
|
7497
7550
|
opensteerComputerExecuteOutputSchema = objectSchema(
|
|
7498
7551
|
{
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
screenshot:
|
|
7502
|
-
displayViewport: viewportMetricsSchema,
|
|
7503
|
-
nativeViewport: viewportMetricsSchema,
|
|
7504
|
-
displayScale: opensteerComputerDisplayScaleSchema,
|
|
7505
|
-
events: arraySchema(opensteerEventSchema),
|
|
7506
|
-
timing: opensteerComputerExecuteTimingSchema,
|
|
7507
|
-
trace: opensteerComputerTraceEnrichmentSchema
|
|
7552
|
+
url: stringSchema(),
|
|
7553
|
+
title: stringSchema(),
|
|
7554
|
+
screenshot: opensteerScreenshotSummarySchema
|
|
7508
7555
|
},
|
|
7509
7556
|
{
|
|
7510
7557
|
title: "OpensteerComputerExecuteOutput",
|
|
7511
|
-
required: [
|
|
7512
|
-
"action",
|
|
7513
|
-
"pageRef",
|
|
7514
|
-
"screenshot",
|
|
7515
|
-
"displayViewport",
|
|
7516
|
-
"nativeViewport",
|
|
7517
|
-
"displayScale",
|
|
7518
|
-
"events",
|
|
7519
|
-
"timing"
|
|
7520
|
-
]
|
|
7558
|
+
required: ["url", "title", "screenshot"]
|
|
7521
7559
|
}
|
|
7522
7560
|
);
|
|
7523
7561
|
opensteerSemanticOperationSpecificationsBase = [
|
|
@@ -7525,7 +7563,7 @@ var init_semantic = __esm({
|
|
|
7525
7563
|
name: "session.open",
|
|
7526
7564
|
description: "Open or resume the current Opensteer session and primary page.",
|
|
7527
7565
|
inputSchema: opensteerOpenInputSchema,
|
|
7528
|
-
outputSchema:
|
|
7566
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
7529
7567
|
requiredCapabilities: ["sessions.manage", "pages.manage"],
|
|
7530
7568
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["sessions.manage", "pages.manage"] : ["sessions.manage", "pages.manage", "pages.navigate"]
|
|
7531
7569
|
}),
|
|
@@ -7540,7 +7578,7 @@ var init_semantic = __esm({
|
|
|
7540
7578
|
name: "page.new",
|
|
7541
7579
|
description: "Create and optionally navigate a new top-level page in the current session.",
|
|
7542
7580
|
inputSchema: opensteerPageNewInputSchema,
|
|
7543
|
-
outputSchema:
|
|
7581
|
+
outputSchema: opensteerPageNewOutputSchema,
|
|
7544
7582
|
requiredCapabilities: ["pages.manage"],
|
|
7545
7583
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["pages.manage"] : ["pages.manage", "pages.navigate"]
|
|
7546
7584
|
}),
|
|
@@ -7548,7 +7586,7 @@ var init_semantic = __esm({
|
|
|
7548
7586
|
name: "page.activate",
|
|
7549
7587
|
description: "Activate an existing top-level page in the current session.",
|
|
7550
7588
|
inputSchema: opensteerPageActivateInputSchema,
|
|
7551
|
-
outputSchema:
|
|
7589
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
7552
7590
|
requiredCapabilities: ["pages.manage", "inspect.pages"]
|
|
7553
7591
|
}),
|
|
7554
7592
|
defineSemanticOperationSpec({
|
|
@@ -7562,7 +7600,7 @@ var init_semantic = __esm({
|
|
|
7562
7600
|
name: "page.goto",
|
|
7563
7601
|
description: "Navigate the current Opensteer page to a new URL.",
|
|
7564
7602
|
inputSchema: opensteerPageGotoInputSchema,
|
|
7565
|
-
outputSchema:
|
|
7603
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
7566
7604
|
requiredCapabilities: ["pages.navigate"]
|
|
7567
7605
|
}),
|
|
7568
7606
|
defineSemanticOperationSpec({
|
|
@@ -9804,16 +9842,37 @@ async function writePersistedSessionRecord(rootPath, record) {
|
|
|
9804
9842
|
async function clearPersistedSessionRecord(rootPath, provider) {
|
|
9805
9843
|
await promises.rm(resolveLiveSessionRecordPath(rootPath, provider), { force: true });
|
|
9806
9844
|
}
|
|
9845
|
+
function getPersistedLocalBrowserSessionOwnership(record) {
|
|
9846
|
+
return record.ownership === "attached" ? "attached" : "owned";
|
|
9847
|
+
}
|
|
9848
|
+
async function isAttachedLocalBrowserSessionReachable(record) {
|
|
9849
|
+
if (getPersistedLocalBrowserSessionOwnership(record) !== "attached") {
|
|
9850
|
+
return false;
|
|
9851
|
+
}
|
|
9852
|
+
if (record.engine !== "playwright" || record.endpoint === void 0) {
|
|
9853
|
+
return false;
|
|
9854
|
+
}
|
|
9855
|
+
try {
|
|
9856
|
+
await inspectCdpEndpoint({
|
|
9857
|
+
endpoint: record.endpoint,
|
|
9858
|
+
timeoutMs: 1500
|
|
9859
|
+
});
|
|
9860
|
+
return true;
|
|
9861
|
+
} catch {
|
|
9862
|
+
return false;
|
|
9863
|
+
}
|
|
9864
|
+
}
|
|
9807
9865
|
function isPersistedCloudSessionRecord(value) {
|
|
9808
9866
|
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "cloud" && typeof value.sessionId === "string" && value.sessionId.length > 0 && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
|
|
9809
9867
|
}
|
|
9810
9868
|
function isPersistedLocalBrowserSessionRecord(value) {
|
|
9811
|
-
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "local" && (value.engine === "playwright" || value.engine === "abp") && typeof value.pid === "number" && Number.isFinite(value.pid) && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) && typeof value.userDataDir === "string" && value.userDataDir.length > 0;
|
|
9869
|
+
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "local" && (value.engine === "playwright" || value.engine === "abp") && (value.ownership === void 0 || value.ownership === "owned" || value.ownership === "attached") && typeof value.pid === "number" && Number.isFinite(value.pid) && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) && typeof value.userDataDir === "string" && value.userDataDir.length > 0;
|
|
9812
9870
|
}
|
|
9813
9871
|
var OPENSTEER_LIVE_SESSION_LAYOUT, OPENSTEER_LIVE_SESSION_VERSION;
|
|
9814
9872
|
var init_live_session = __esm({
|
|
9815
9873
|
"src/live-session.ts"() {
|
|
9816
9874
|
init_filesystem2();
|
|
9875
|
+
init_cdp_discovery();
|
|
9817
9876
|
OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
|
|
9818
9877
|
OPENSTEER_LIVE_SESSION_VERSION = 1;
|
|
9819
9878
|
}
|
|
@@ -10302,19 +10361,40 @@ var init_service = __esm({
|
|
|
10302
10361
|
}
|
|
10303
10362
|
});
|
|
10304
10363
|
function buildLocalViewSessionId(input) {
|
|
10364
|
+
const ownership = input.ownership ?? "owned";
|
|
10365
|
+
const identity = ownership === "attached" ? input.endpoint ?? input.remoteDebuggingUrl ?? input.baseUrl ?? "attached" : `pid:${String(input.pid ?? 0)}`;
|
|
10305
10366
|
const hash = crypto.createHash("sha256").update(`${input.rootPath}
|
|
10306
|
-
${
|
|
10367
|
+
${ownership}
|
|
10368
|
+
${identity}
|
|
10307
10369
|
${String(input.startedAt)}`).digest("hex");
|
|
10308
10370
|
return `local_${hash.slice(0, 24)}`;
|
|
10309
10371
|
}
|
|
10372
|
+
function buildLocalViewSessionIdForRecord(input) {
|
|
10373
|
+
const ownership = getPersistedLocalBrowserSessionOwnership(input.live);
|
|
10374
|
+
if (ownership === "attached") {
|
|
10375
|
+
return buildLocalViewSessionId({
|
|
10376
|
+
rootPath: input.rootPath,
|
|
10377
|
+
ownership,
|
|
10378
|
+
startedAt: input.live.startedAt,
|
|
10379
|
+
...input.live.endpoint === void 0 ? {} : { endpoint: input.live.endpoint },
|
|
10380
|
+
...input.live.baseUrl === void 0 ? {} : { baseUrl: input.live.baseUrl },
|
|
10381
|
+
...input.live.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: input.live.remoteDebuggingUrl }
|
|
10382
|
+
});
|
|
10383
|
+
}
|
|
10384
|
+
return buildLocalViewSessionId({
|
|
10385
|
+
rootPath: input.rootPath,
|
|
10386
|
+
ownership,
|
|
10387
|
+
startedAt: input.live.startedAt,
|
|
10388
|
+
pid: input.live.pid
|
|
10389
|
+
});
|
|
10390
|
+
}
|
|
10310
10391
|
function createLocalViewSessionManifest(input) {
|
|
10311
10392
|
return {
|
|
10312
10393
|
layout: OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT,
|
|
10313
10394
|
version: OPENSTEER_LOCAL_VIEW_SESSION_VERSION,
|
|
10314
|
-
sessionId:
|
|
10395
|
+
sessionId: buildLocalViewSessionIdForRecord({
|
|
10315
10396
|
rootPath: input.rootPath,
|
|
10316
|
-
|
|
10317
|
-
startedAt: input.live.startedAt
|
|
10397
|
+
live: input.live
|
|
10318
10398
|
}),
|
|
10319
10399
|
rootPath: input.rootPath,
|
|
10320
10400
|
...input.workspace === void 0 ? {} : { workspace: input.workspace },
|
|
@@ -10365,6 +10445,7 @@ var OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT, OPENSTEER_LOCAL_VIEW_SESSION_VERSION;
|
|
|
10365
10445
|
var init_session_manifest = __esm({
|
|
10366
10446
|
"src/local-view/session-manifest.ts"() {
|
|
10367
10447
|
init_filesystem2();
|
|
10448
|
+
init_live_session();
|
|
10368
10449
|
init_runtime_dir();
|
|
10369
10450
|
OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT = "opensteer-local-view-session";
|
|
10370
10451
|
OPENSTEER_LOCAL_VIEW_SESSION_VERSION = 1;
|
|
@@ -10413,7 +10494,8 @@ function normalizeOpensteerEngineName(value, source = "engine") {
|
|
|
10413
10494
|
if (normalized === "playwright" || normalized === "abp") {
|
|
10414
10495
|
return normalized;
|
|
10415
10496
|
}
|
|
10416
|
-
throw new
|
|
10497
|
+
throw new OpensteerProtocolError(
|
|
10498
|
+
"invalid-argument",
|
|
10417
10499
|
`${source} must be one of ${OPENSTEER_ENGINE_NAMES.join(", ")}; received "${value}".`
|
|
10418
10500
|
);
|
|
10419
10501
|
}
|
|
@@ -10422,7 +10504,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
10422
10504
|
return;
|
|
10423
10505
|
}
|
|
10424
10506
|
if (typeof input.browser === "object" && input.browser !== null && input.browser.mode === "attach") {
|
|
10425
|
-
throw new
|
|
10507
|
+
throw new OpensteerProtocolError(
|
|
10508
|
+
"invalid-argument",
|
|
10426
10509
|
'ABP engine does not support browser.mode="attach". Use the Playwright engine for attach flows.'
|
|
10427
10510
|
);
|
|
10428
10511
|
}
|
|
@@ -10430,7 +10513,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
10430
10513
|
if (unsupportedContextOptionNames.length === 0) {
|
|
10431
10514
|
return;
|
|
10432
10515
|
}
|
|
10433
|
-
throw new
|
|
10516
|
+
throw new OpensteerProtocolError(
|
|
10517
|
+
"invalid-argument",
|
|
10434
10518
|
`ABP engine does not support ${unsupportedContextOptionNames.join(", ")}. Supported ABP context options: context.viewport.`
|
|
10435
10519
|
);
|
|
10436
10520
|
}
|
|
@@ -10488,6 +10572,7 @@ function stripWindowSizeArgs(args) {
|
|
|
10488
10572
|
var OPENSTEER_ENGINE_NAMES, DEFAULT_OPENSTEER_ENGINE;
|
|
10489
10573
|
var init_engine_selection = __esm({
|
|
10490
10574
|
"../runtime-core/src/internal/engine-selection.ts"() {
|
|
10575
|
+
init_src2();
|
|
10491
10576
|
OPENSTEER_ENGINE_NAMES = ["playwright", "abp"];
|
|
10492
10577
|
DEFAULT_OPENSTEER_ENGINE = "playwright";
|
|
10493
10578
|
}
|
|
@@ -10529,6 +10614,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
10529
10614
|
version: 1,
|
|
10530
10615
|
provider: "local",
|
|
10531
10616
|
...workspace === void 0 ? {} : { workspace },
|
|
10617
|
+
ownership: live.ownership,
|
|
10532
10618
|
engine: live.engine,
|
|
10533
10619
|
...live.endpoint === void 0 ? {} : { endpoint: live.endpoint },
|
|
10534
10620
|
...live.baseUrl === void 0 ? {} : { baseUrl: live.baseUrl },
|
|
@@ -10544,6 +10630,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
10544
10630
|
function toWorkspaceLiveBrowserRecord(record) {
|
|
10545
10631
|
return {
|
|
10546
10632
|
mode: "persistent",
|
|
10633
|
+
ownership: getPersistedLocalBrowserSessionOwnership(record),
|
|
10547
10634
|
engine: record.engine,
|
|
10548
10635
|
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
10549
10636
|
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
@@ -10570,7 +10657,12 @@ function isAttachBrowserOptions(browser) {
|
|
|
10570
10657
|
async function resolveAttachEndpoint(browser) {
|
|
10571
10658
|
const endpoint = browser?.endpoint?.trim();
|
|
10572
10659
|
if (endpoint && endpoint.length > 0) {
|
|
10573
|
-
|
|
10660
|
+
const inspected = await inspectCdpEndpoint({
|
|
10661
|
+
endpoint,
|
|
10662
|
+
...browser?.headers === void 0 ? {} : { headers: browser.headers },
|
|
10663
|
+
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
10664
|
+
});
|
|
10665
|
+
return inspected.endpoint;
|
|
10574
10666
|
}
|
|
10575
10667
|
const selection = await selectAttachBrowserCandidate({
|
|
10576
10668
|
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
@@ -10996,7 +11088,7 @@ var init_browser_manager = __esm({
|
|
|
10996
11088
|
}
|
|
10997
11089
|
const liveRecord = await this.readLivePersistentBrowser(await this.ensureWorkspaceStore());
|
|
10998
11090
|
return {
|
|
10999
|
-
mode: this.mode,
|
|
11091
|
+
mode: liveRecord?.ownership === "attached" ? "attach" : this.mode,
|
|
11000
11092
|
engine: liveRecord?.engine ?? this.engineName,
|
|
11001
11093
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11002
11094
|
live: liveRecord !== void 0
|
|
@@ -11124,6 +11216,7 @@ var init_browser_manager = __esm({
|
|
|
11124
11216
|
});
|
|
11125
11217
|
const liveRecord = {
|
|
11126
11218
|
mode: "persistent",
|
|
11219
|
+
ownership: "owned",
|
|
11127
11220
|
engine: "abp",
|
|
11128
11221
|
baseUrl: launched.baseUrl,
|
|
11129
11222
|
remoteDebuggingUrl: launched.remoteDebuggingUrl,
|
|
@@ -11210,11 +11303,78 @@ var init_browser_manager = __esm({
|
|
|
11210
11303
|
}
|
|
11211
11304
|
async createAttachEngine() {
|
|
11212
11305
|
const endpoint = await resolveAttachEndpoint(this.browserOptions);
|
|
11213
|
-
|
|
11214
|
-
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11306
|
+
if (this.workspace === void 0) {
|
|
11307
|
+
return this.createAttachedEngine({
|
|
11308
|
+
endpoint,
|
|
11309
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
11310
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
11311
|
+
onDispose: async () => void 0
|
|
11312
|
+
});
|
|
11313
|
+
}
|
|
11314
|
+
const workspace = await this.ensureWorkspaceStore();
|
|
11315
|
+
return workspace.lock(async () => {
|
|
11316
|
+
const live = await this.readLivePersistentBrowser(workspace);
|
|
11317
|
+
if (live) {
|
|
11318
|
+
if (live.engine !== "playwright") {
|
|
11319
|
+
throw new Error(
|
|
11320
|
+
`workspace "${this.workspace}" already has a live ${live.engine} browser. Close it before attaching a Playwright browser.`
|
|
11321
|
+
);
|
|
11322
|
+
}
|
|
11323
|
+
if (live.ownership !== "attached") {
|
|
11324
|
+
throw new Error(
|
|
11325
|
+
`workspace "${this.workspace}" already has a live Opensteer-owned browser. Close it before attaching another browser.`
|
|
11326
|
+
);
|
|
11327
|
+
}
|
|
11328
|
+
if (live.endpoint === void 0) {
|
|
11329
|
+
throw new Error("workspace live browser record is missing a DevTools endpoint.");
|
|
11330
|
+
}
|
|
11331
|
+
if (live.endpoint !== endpoint) {
|
|
11332
|
+
throw new Error(
|
|
11333
|
+
`workspace "${this.workspace}" is already attached to a different browser endpoint. Close it before reattaching.`
|
|
11334
|
+
);
|
|
11335
|
+
}
|
|
11336
|
+
await bestEffortRegisterLocalViewSession({
|
|
11337
|
+
rootPath: workspace.rootPath,
|
|
11338
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11339
|
+
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
11340
|
+
ownership: "attached"
|
|
11341
|
+
});
|
|
11342
|
+
return this.createAttachedEngine({
|
|
11343
|
+
endpoint: live.endpoint,
|
|
11344
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
11345
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
11346
|
+
onDispose: async () => void 0
|
|
11347
|
+
});
|
|
11348
|
+
}
|
|
11349
|
+
const liveRecord = {
|
|
11350
|
+
mode: "persistent",
|
|
11351
|
+
ownership: "attached",
|
|
11352
|
+
engine: "playwright",
|
|
11353
|
+
endpoint,
|
|
11354
|
+
pid: 0,
|
|
11355
|
+
startedAt: Date.now(),
|
|
11356
|
+
userDataDir: workspace.browserUserDataDir
|
|
11357
|
+
};
|
|
11358
|
+
await this.writeLivePersistentBrowser(workspace, liveRecord);
|
|
11359
|
+
const persistedLiveRecord = toPersistedLocalBrowserSessionRecord(this.workspace, liveRecord);
|
|
11360
|
+
await bestEffortRegisterLocalViewSession({
|
|
11361
|
+
rootPath: workspace.rootPath,
|
|
11362
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11363
|
+
live: persistedLiveRecord,
|
|
11364
|
+
ownership: "attached"
|
|
11365
|
+
});
|
|
11366
|
+
try {
|
|
11367
|
+
return await this.createAttachedEngine({
|
|
11368
|
+
endpoint,
|
|
11369
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
11370
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
11371
|
+
onDispose: async () => void 0
|
|
11372
|
+
});
|
|
11373
|
+
} catch (error) {
|
|
11374
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
|
|
11375
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11376
|
+
throw error;
|
|
11377
|
+
}
|
|
11218
11378
|
});
|
|
11219
11379
|
}
|
|
11220
11380
|
async createPersistentEngine() {
|
|
@@ -11234,7 +11394,7 @@ var init_browser_manager = __esm({
|
|
|
11234
11394
|
rootPath: workspace.rootPath,
|
|
11235
11395
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11236
11396
|
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
11237
|
-
ownership:
|
|
11397
|
+
ownership: live.ownership
|
|
11238
11398
|
});
|
|
11239
11399
|
return this.createAttachedEngine({
|
|
11240
11400
|
endpoint: live.endpoint,
|
|
@@ -11250,6 +11410,7 @@ var init_browser_manager = __esm({
|
|
|
11250
11410
|
});
|
|
11251
11411
|
const liveRecord = {
|
|
11252
11412
|
mode: "persistent",
|
|
11413
|
+
ownership: "owned",
|
|
11253
11414
|
engine: "playwright",
|
|
11254
11415
|
endpoint: launched.endpoint,
|
|
11255
11416
|
pid: launched.pid,
|
|
@@ -11379,7 +11540,20 @@ var init_browser_manager = __esm({
|
|
|
11379
11540
|
if (live === void 0) {
|
|
11380
11541
|
return void 0;
|
|
11381
11542
|
}
|
|
11543
|
+
if (live.ownership === "attached") {
|
|
11544
|
+
const attachedRecord = toPersistedLocalBrowserSessionRecord(this.workspace, live);
|
|
11545
|
+
if (!await isAttachedLocalBrowserSessionReachable(attachedRecord)) {
|
|
11546
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, attachedRecord);
|
|
11547
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11548
|
+
return void 0;
|
|
11549
|
+
}
|
|
11550
|
+
return live;
|
|
11551
|
+
}
|
|
11382
11552
|
if (!isProcessRunning(live.pid)) {
|
|
11553
|
+
await this.unregisterLocalViewSessionForRecord(
|
|
11554
|
+
workspace.rootPath,
|
|
11555
|
+
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
11556
|
+
);
|
|
11383
11557
|
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11384
11558
|
return void 0;
|
|
11385
11559
|
}
|
|
@@ -11427,6 +11601,10 @@ var init_browser_manager = __esm({
|
|
|
11427
11601
|
workspace.rootPath,
|
|
11428
11602
|
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
11429
11603
|
);
|
|
11604
|
+
if (live.ownership === "attached") {
|
|
11605
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11606
|
+
return;
|
|
11607
|
+
}
|
|
11430
11608
|
if (live.engine === "playwright") {
|
|
11431
11609
|
if (live.endpoint !== void 0) {
|
|
11432
11610
|
await requestBrowserClose(live.endpoint).catch(() => void 0);
|
|
@@ -11455,10 +11633,18 @@ var init_browser_manager = __esm({
|
|
|
11455
11633
|
}
|
|
11456
11634
|
async unregisterLocalViewSessionForRecord(rootPath, record) {
|
|
11457
11635
|
await bestEffortUnregisterLocalViewSession(
|
|
11458
|
-
buildLocalViewSessionId({
|
|
11636
|
+
getPersistedLocalBrowserSessionOwnership(record) === "attached" ? buildLocalViewSessionId({
|
|
11459
11637
|
rootPath,
|
|
11460
|
-
|
|
11461
|
-
|
|
11638
|
+
startedAt: record.startedAt,
|
|
11639
|
+
ownership: "attached",
|
|
11640
|
+
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
11641
|
+
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
11642
|
+
...record.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: record.remoteDebuggingUrl }
|
|
11643
|
+
}) : buildLocalViewSessionId({
|
|
11644
|
+
rootPath,
|
|
11645
|
+
startedAt: record.startedAt,
|
|
11646
|
+
ownership: "owned",
|
|
11647
|
+
pid: record.pid
|
|
11462
11648
|
})
|
|
11463
11649
|
);
|
|
11464
11650
|
}
|
|
@@ -11472,7 +11658,8 @@ function assertProviderSupportsEngine(provider, engine) {
|
|
|
11472
11658
|
return;
|
|
11473
11659
|
}
|
|
11474
11660
|
if (provider === "cloud") {
|
|
11475
|
-
throw new
|
|
11661
|
+
throw new OpensteerProtocolError(
|
|
11662
|
+
"invalid-argument",
|
|
11476
11663
|
"ABP is not supported for provider=cloud. Cloud provider currently requires Playwright."
|
|
11477
11664
|
);
|
|
11478
11665
|
}
|
|
@@ -11482,7 +11669,8 @@ function normalizeOpensteerProviderMode(value, source = "OPENSTEER_PROVIDER") {
|
|
|
11482
11669
|
if (normalized === OPENSTEER_PROVIDER_MODES[0] || normalized === OPENSTEER_PROVIDER_MODES[1]) {
|
|
11483
11670
|
return normalized;
|
|
11484
11671
|
}
|
|
11485
|
-
throw new
|
|
11672
|
+
throw new OpensteerProtocolError(
|
|
11673
|
+
"invalid-argument",
|
|
11486
11674
|
`${source} must be one of ${OPENSTEER_PROVIDER_MODES.join(", ")}; received "${value}".`
|
|
11487
11675
|
);
|
|
11488
11676
|
}
|
|
@@ -11507,6 +11695,7 @@ function resolveOpensteerProvider(input = {}) {
|
|
|
11507
11695
|
var OPENSTEER_PROVIDER_MODES;
|
|
11508
11696
|
var init_config = __esm({
|
|
11509
11697
|
"src/provider/config.ts"() {
|
|
11698
|
+
init_src2();
|
|
11510
11699
|
OPENSTEER_PROVIDER_MODES = ["local", "cloud"];
|
|
11511
11700
|
}
|
|
11512
11701
|
});
|
|
@@ -11968,12 +12157,60 @@ function wrapCloudFetchError(error, input) {
|
|
|
11968
12157
|
wrapped.name = error.name;
|
|
11969
12158
|
return wrapped;
|
|
11970
12159
|
}
|
|
11971
|
-
|
|
12160
|
+
async function createCloudRequestError(response, input) {
|
|
12161
|
+
const payload = await readCloudErrorPayload(response);
|
|
12162
|
+
return new OpensteerCloudRequestError({
|
|
12163
|
+
statusCode: response.status,
|
|
12164
|
+
method: input.method,
|
|
12165
|
+
pathname: input.pathname,
|
|
12166
|
+
url: input.url,
|
|
12167
|
+
message: payload?.error ?? `${input.method} ${input.pathname} failed with ${String(response.status)}.`,
|
|
12168
|
+
...payload?.code === void 0 ? {} : { code: payload.code },
|
|
12169
|
+
...payload?.details === void 0 ? {} : { details: payload.details }
|
|
12170
|
+
});
|
|
12171
|
+
}
|
|
12172
|
+
async function readCloudErrorPayload(response) {
|
|
12173
|
+
try {
|
|
12174
|
+
return asCloudErrorPayload(await response.json());
|
|
12175
|
+
} catch {
|
|
12176
|
+
return void 0;
|
|
12177
|
+
}
|
|
12178
|
+
}
|
|
12179
|
+
function asCloudErrorPayload(value) {
|
|
12180
|
+
if (value === null || typeof value !== "object") {
|
|
12181
|
+
return void 0;
|
|
12182
|
+
}
|
|
12183
|
+
const payload = value;
|
|
12184
|
+
return {
|
|
12185
|
+
...typeof payload.error === "string" ? { error: payload.error } : {},
|
|
12186
|
+
...typeof payload.code === "string" ? { code: payload.code } : {},
|
|
12187
|
+
..."details" in payload ? { details: payload.details } : {}
|
|
12188
|
+
};
|
|
12189
|
+
}
|
|
12190
|
+
var CLOUD_CLOSE_TIMEOUT_MS, CLOUD_CLOSE_POLL_INTERVAL_MS, OpensteerCloudRequestError, OpensteerCloudClient;
|
|
11972
12191
|
var init_client = __esm({
|
|
11973
12192
|
"src/cloud/client.ts"() {
|
|
11974
12193
|
init_profile_sync();
|
|
11975
12194
|
CLOUD_CLOSE_TIMEOUT_MS = 6e4;
|
|
11976
12195
|
CLOUD_CLOSE_POLL_INTERVAL_MS = 250;
|
|
12196
|
+
OpensteerCloudRequestError = class extends Error {
|
|
12197
|
+
statusCode;
|
|
12198
|
+
code;
|
|
12199
|
+
details;
|
|
12200
|
+
method;
|
|
12201
|
+
pathname;
|
|
12202
|
+
url;
|
|
12203
|
+
constructor(args) {
|
|
12204
|
+
super(args.message);
|
|
12205
|
+
this.name = "OpensteerCloudRequestError";
|
|
12206
|
+
this.statusCode = args.statusCode;
|
|
12207
|
+
this.code = args.code;
|
|
12208
|
+
this.details = args.details;
|
|
12209
|
+
this.method = args.method;
|
|
12210
|
+
this.pathname = args.pathname;
|
|
12211
|
+
this.url = args.url;
|
|
12212
|
+
}
|
|
12213
|
+
};
|
|
11977
12214
|
OpensteerCloudClient = class {
|
|
11978
12215
|
constructor(config) {
|
|
11979
12216
|
this.config = config;
|
|
@@ -12149,7 +12386,11 @@ var init_client = __esm({
|
|
|
12149
12386
|
});
|
|
12150
12387
|
}
|
|
12151
12388
|
if (!response.ok) {
|
|
12152
|
-
throw
|
|
12389
|
+
throw await createCloudRequestError(response, {
|
|
12390
|
+
method: init.method,
|
|
12391
|
+
pathname,
|
|
12392
|
+
url
|
|
12393
|
+
});
|
|
12153
12394
|
}
|
|
12154
12395
|
return response;
|
|
12155
12396
|
}
|
|
@@ -12220,7 +12461,7 @@ var init_package = __esm({
|
|
|
12220
12461
|
"../runtime-core/package.json"() {
|
|
12221
12462
|
package_default2 = {
|
|
12222
12463
|
name: "@opensteer/runtime-core",
|
|
12223
|
-
version: "0.2.
|
|
12464
|
+
version: "0.2.6",
|
|
12224
12465
|
description: "Shared semantic runtime for Opensteer local and cloud execution.",
|
|
12225
12466
|
license: "MIT",
|
|
12226
12467
|
type: "module",
|
|
@@ -12372,7 +12613,7 @@ var init_errors3 = __esm({
|
|
|
12372
12613
|
function defaultPolicy() {
|
|
12373
12614
|
return DEFAULT_POLICY;
|
|
12374
12615
|
}
|
|
12375
|
-
var DEFAULT_TIMEOUTS, DEFAULT_SETTLE_DELAYS,
|
|
12616
|
+
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
12617
|
var init_defaults = __esm({
|
|
12377
12618
|
"../runtime-core/src/policy/defaults.ts"() {
|
|
12378
12619
|
init_src();
|
|
@@ -12401,30 +12642,15 @@ var init_defaults = __esm({
|
|
|
12401
12642
|
"dom-action": 100,
|
|
12402
12643
|
snapshot: 0
|
|
12403
12644
|
};
|
|
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
12645
|
DOM_ACTION_VISUAL_STABILITY_PROFILES = {
|
|
12420
|
-
"dom.click": { settleMs: 750, scope: "
|
|
12421
|
-
"dom.input": { settleMs: 750, scope: "
|
|
12422
|
-
"dom.scroll": { settleMs: 600, scope: "
|
|
12646
|
+
"dom.click": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
12647
|
+
"dom.input": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
12648
|
+
"dom.scroll": { settleMs: 600, scope: "main-frame", timeoutMs: 7e3 },
|
|
12423
12649
|
"dom.hover": { settleMs: 200, scope: "main-frame", timeoutMs: 2500 }
|
|
12424
12650
|
};
|
|
12425
12651
|
DEFAULT_DOM_ACTION_VISUAL_STABILITY_PROFILE = {
|
|
12426
12652
|
settleMs: 750,
|
|
12427
|
-
scope: "
|
|
12653
|
+
scope: "main-frame",
|
|
12428
12654
|
timeoutMs: 7e3
|
|
12429
12655
|
};
|
|
12430
12656
|
NAVIGATION_VISUAL_STABILITY_PROFILE = {
|
|
@@ -12448,6 +12674,7 @@ var init_defaults = __esm({
|
|
|
12448
12674
|
pageRef: input.pageRef,
|
|
12449
12675
|
timeoutMs: effectiveTimeout,
|
|
12450
12676
|
settleMs: profile.settleMs,
|
|
12677
|
+
...input.observedMutationQuietMs === void 0 ? {} : { initialQuietMs: input.observedMutationQuietMs },
|
|
12451
12678
|
scope: profile.scope
|
|
12452
12679
|
});
|
|
12453
12680
|
return true;
|
|
@@ -12468,15 +12695,20 @@ var init_defaults = __esm({
|
|
|
12468
12695
|
return false;
|
|
12469
12696
|
}
|
|
12470
12697
|
try {
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
12479
|
-
|
|
12698
|
+
let visualTimeout = effectiveTimeout;
|
|
12699
|
+
let initialQuietMs = input.observedMutationQuietMs ?? 0;
|
|
12700
|
+
if (!input.postLoadHandled) {
|
|
12701
|
+
const startedAt = Date.now();
|
|
12702
|
+
await input.engine.waitForPostLoadQuiet({
|
|
12703
|
+
pageRef: input.pageRef,
|
|
12704
|
+
timeoutMs: effectiveTimeout,
|
|
12705
|
+
quietMs: DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS,
|
|
12706
|
+
captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
|
|
12707
|
+
signal: input.signal
|
|
12708
|
+
});
|
|
12709
|
+
visualTimeout = Math.max(0, effectiveTimeout - (Date.now() - startedAt));
|
|
12710
|
+
initialQuietMs = Math.max(initialQuietMs, DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS);
|
|
12711
|
+
}
|
|
12480
12712
|
if (visualTimeout <= 0) {
|
|
12481
12713
|
return true;
|
|
12482
12714
|
}
|
|
@@ -12484,6 +12716,7 @@ var init_defaults = __esm({
|
|
|
12484
12716
|
pageRef: input.pageRef,
|
|
12485
12717
|
timeoutMs: visualTimeout,
|
|
12486
12718
|
settleMs: profile.settleMs,
|
|
12719
|
+
...initialQuietMs <= 0 ? {} : { initialQuietMs },
|
|
12487
12720
|
scope: profile.scope
|
|
12488
12721
|
});
|
|
12489
12722
|
return true;
|
|
@@ -12494,7 +12727,6 @@ var init_defaults = __esm({
|
|
|
12494
12727
|
};
|
|
12495
12728
|
Object.freeze(defaultNavigationSettleObserver);
|
|
12496
12729
|
DEFAULT_SETTLE_OBSERVERS = Object.freeze([
|
|
12497
|
-
defaultSnapshotSettleObserver,
|
|
12498
12730
|
defaultDomActionSettleObserver,
|
|
12499
12731
|
defaultNavigationSettleObserver
|
|
12500
12732
|
]);
|
|
@@ -12982,6 +13214,9 @@ function buildClauseSelector(node, clause) {
|
|
|
12982
13214
|
if (!clause || typeof clause !== "object") {
|
|
12983
13215
|
return "";
|
|
12984
13216
|
}
|
|
13217
|
+
if (clause.kind === "text") {
|
|
13218
|
+
return "";
|
|
13219
|
+
}
|
|
12985
13220
|
if (clause.kind === "position") {
|
|
12986
13221
|
if (clause.axis === "nthOfType") {
|
|
12987
13222
|
return `:nth-of-type(${Math.max(1, Number(node.position?.nthOfType || 1))})`;
|
|
@@ -13097,7 +13332,7 @@ function resolveExtractedValueInContext(normalizedValue, options) {
|
|
|
13097
13332
|
function stripPositionClauses(nodes) {
|
|
13098
13333
|
return (nodes || []).map((node) => ({
|
|
13099
13334
|
...node,
|
|
13100
|
-
match: (node.match || []).filter((clause) => clause.kind !== "position")
|
|
13335
|
+
match: (node.match || []).filter((clause) => clause.kind !== "position" && clause.kind !== "text")
|
|
13101
13336
|
}));
|
|
13102
13337
|
}
|
|
13103
13338
|
function dedupeSelectors(selectors) {
|
|
@@ -13685,9 +13920,17 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
13685
13920
|
if (!candidates.length) {
|
|
13686
13921
|
return null;
|
|
13687
13922
|
}
|
|
13923
|
+
const lastNode = domPath[domPath.length - 1];
|
|
13924
|
+
const textClauses = lastNode?.match.filter((c) => c.kind === "text") ?? [];
|
|
13688
13925
|
let fallback = null;
|
|
13689
13926
|
for (const selector of candidates) {
|
|
13690
|
-
|
|
13927
|
+
let matches = querySelectorAllInScope(index, selector, scope);
|
|
13928
|
+
if (textClauses.length > 0 && matches.length > 1) {
|
|
13929
|
+
const filtered = matches.filter((node) => matchesTextClauses(node, textClauses));
|
|
13930
|
+
if (filtered.length > 0) {
|
|
13931
|
+
matches = filtered;
|
|
13932
|
+
}
|
|
13933
|
+
}
|
|
13691
13934
|
if (matches.length === 1) {
|
|
13692
13935
|
return {
|
|
13693
13936
|
node: matches[0],
|
|
@@ -13707,6 +13950,10 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
13707
13950
|
}
|
|
13708
13951
|
return fallback;
|
|
13709
13952
|
}
|
|
13953
|
+
function matchesTextClauses(node, clauses) {
|
|
13954
|
+
const text = (node.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
13955
|
+
return clauses.every((clause) => text.includes(clause.value));
|
|
13956
|
+
}
|
|
13710
13957
|
function queryAllDomPathInScope(index, domPath, scope) {
|
|
13711
13958
|
const selectors = buildPathCandidates(domPath);
|
|
13712
13959
|
for (const selector of selectors) {
|
|
@@ -13865,7 +14112,13 @@ function clonePathNode(node) {
|
|
|
13865
14112
|
};
|
|
13866
14113
|
}
|
|
13867
14114
|
function cloneMatchClause(clause) {
|
|
13868
|
-
|
|
14115
|
+
if (clause.kind === "position") {
|
|
14116
|
+
return { kind: "position", axis: clause.axis };
|
|
14117
|
+
}
|
|
14118
|
+
if (clause.kind === "text") {
|
|
14119
|
+
return { kind: "text", value: clause.value };
|
|
14120
|
+
}
|
|
14121
|
+
return {
|
|
13869
14122
|
kind: "attr",
|
|
13870
14123
|
key: clause.key,
|
|
13871
14124
|
...clause.op === void 0 ? {} : { op: clause.op },
|
|
@@ -13920,6 +14173,13 @@ function normalizeMatch(rawMatch, attrs, position, tag) {
|
|
|
13920
14173
|
op,
|
|
13921
14174
|
...value === void 0 ? {} : { value }
|
|
13922
14175
|
});
|
|
14176
|
+
continue;
|
|
14177
|
+
}
|
|
14178
|
+
if (record.kind === "text") {
|
|
14179
|
+
const textValue = typeof record.value === "string" ? record.value.trim() : "";
|
|
14180
|
+
if (textValue) {
|
|
14181
|
+
push({ kind: "text", value: textValue.slice(0, 80) });
|
|
14182
|
+
}
|
|
13923
14183
|
}
|
|
13924
14184
|
}
|
|
13925
14185
|
}
|
|
@@ -14334,7 +14594,7 @@ var init_executor = __esm({
|
|
|
14334
14594
|
init_action_boundary2();
|
|
14335
14595
|
init_policy();
|
|
14336
14596
|
init_bridge();
|
|
14337
|
-
MAX_DOM_ACTION_ATTEMPTS =
|
|
14597
|
+
MAX_DOM_ACTION_ATTEMPTS = 2;
|
|
14338
14598
|
DEFAULT_SCROLL_OPTIONS = {
|
|
14339
14599
|
block: "center",
|
|
14340
14600
|
inline: "center"
|
|
@@ -14624,7 +14884,7 @@ var init_executor = __esm({
|
|
|
14624
14884
|
...snapshot === void 0 ? {} : { snapshot },
|
|
14625
14885
|
signal: timeout.signal,
|
|
14626
14886
|
remainingMs: () => timeout.remainingMs(),
|
|
14627
|
-
policySettle: async (targetPageRef, trigger) => {
|
|
14887
|
+
policySettle: async (targetPageRef, trigger, boundary2) => {
|
|
14628
14888
|
try {
|
|
14629
14889
|
await settleWithPolicy(this.options.policy.settle, {
|
|
14630
14890
|
operation,
|
|
@@ -14632,7 +14892,9 @@ var init_executor = __esm({
|
|
|
14632
14892
|
engine: this.options.engine,
|
|
14633
14893
|
pageRef: targetPageRef,
|
|
14634
14894
|
signal: timeout.signal,
|
|
14635
|
-
remainingMs: timeout.remainingMs()
|
|
14895
|
+
remainingMs: timeout.remainingMs(),
|
|
14896
|
+
...boundary2?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary2.observedMutationQuietMs },
|
|
14897
|
+
...boundary2?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
14636
14898
|
});
|
|
14637
14899
|
} catch (error) {
|
|
14638
14900
|
if (snapshot !== void 0 && isSoftSettleTimeoutError(error, timeout.signal)) {
|
|
@@ -14821,11 +15083,12 @@ var init_executor = __esm({
|
|
|
14821
15083
|
throw this.createActionabilityError(
|
|
14822
15084
|
operation,
|
|
14823
15085
|
"obscured",
|
|
14824
|
-
`
|
|
15086
|
+
`target is obscured by ${assessment.blockingDescription ?? "another element"} at the click point`,
|
|
14825
15087
|
{
|
|
14826
15088
|
...details,
|
|
14827
15089
|
hitRelation: assessment.relation,
|
|
14828
15090
|
...assessment.ambiguous === void 0 ? {} : { hitAmbiguous: assessment.ambiguous },
|
|
15091
|
+
...assessment.blockingDescription === void 0 ? {} : { blockingDescription: assessment.blockingDescription },
|
|
14829
15092
|
...assessment.canonicalTarget === void 0 ? {} : {
|
|
14830
15093
|
canonicalNodeRef: assessment.canonicalTarget.nodeRef,
|
|
14831
15094
|
canonicalDocumentRef: assessment.canonicalTarget.documentRef,
|
|
@@ -14839,8 +15102,7 @@ var init_executor = __esm({
|
|
|
14839
15102
|
hitMissingFromSnapshot: !resolved.snapshot.nodes.some(
|
|
14840
15103
|
(node) => node.nodeRef === hit.nodeRef
|
|
14841
15104
|
)
|
|
14842
|
-
}
|
|
14843
|
-
true
|
|
15105
|
+
}
|
|
14844
15106
|
);
|
|
14845
15107
|
}
|
|
14846
15108
|
async resolveActionablePointerTarget(session, operation, resolved) {
|
|
@@ -15031,7 +15293,12 @@ var init_runtime = __esm({
|
|
|
15031
15293
|
});
|
|
15032
15294
|
}
|
|
15033
15295
|
async buildPath(input) {
|
|
15034
|
-
return sanitizeReplayElementPath(
|
|
15296
|
+
return sanitizeReplayElementPath(
|
|
15297
|
+
await this.requireBridge().buildReplayPath(
|
|
15298
|
+
input.locator,
|
|
15299
|
+
input.enableTextMatch ? { enableTextMatch: true } : void 0
|
|
15300
|
+
)
|
|
15301
|
+
);
|
|
15035
15302
|
}
|
|
15036
15303
|
async resolveTarget(input) {
|
|
15037
15304
|
return this.withSnapshotSession((session) => this.resolveTargetWithSession(session, input));
|
|
@@ -15251,7 +15518,7 @@ var init_runtime = __esm({
|
|
|
15251
15518
|
if (resolvedByLocator) {
|
|
15252
15519
|
const { snapshot, node } = resolvedByLocator;
|
|
15253
15520
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
15254
|
-
const replayPath = await this.tryBuildPathFromNode(snapshot, node);
|
|
15521
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch: true });
|
|
15255
15522
|
return this.createResolvedTarget("live", snapshot, node, anchor, {
|
|
15256
15523
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
15257
15524
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -15269,11 +15536,12 @@ var init_runtime = __esm({
|
|
|
15269
15536
|
const { snapshot, node } = resolved;
|
|
15270
15537
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
15271
15538
|
const writeDescriptor = descriptorWriter ?? ((input) => this.descriptors.write(input));
|
|
15272
|
-
const
|
|
15539
|
+
const enableTextMatch = method !== "extract";
|
|
15540
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch });
|
|
15273
15541
|
const descriptor = target.persist === void 0 ? void 0 : await writeDescriptor({
|
|
15274
15542
|
method,
|
|
15275
15543
|
persist: target.persist,
|
|
15276
|
-
path: replayPath ?? await this.buildPathForNode(snapshot, node),
|
|
15544
|
+
path: replayPath ?? await this.buildPathForNode(snapshot, node, { enableTextMatch }),
|
|
15277
15545
|
sourceUrl: snapshot.url
|
|
15278
15546
|
});
|
|
15279
15547
|
return this.createResolvedTarget("selector", snapshot, node, anchor, {
|
|
@@ -15373,7 +15641,7 @@ var init_runtime = __esm({
|
|
|
15373
15641
|
`Unable to resolve structural anchor "${buildPathSelectorHint(anchor)}" in the current session`
|
|
15374
15642
|
);
|
|
15375
15643
|
}
|
|
15376
|
-
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node);
|
|
15644
|
+
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, { enableTextMatch: true });
|
|
15377
15645
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
15378
15646
|
...persist === void 0 ? {} : { persist },
|
|
15379
15647
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -15544,19 +15812,20 @@ var init_runtime = __esm({
|
|
|
15544
15812
|
}
|
|
15545
15813
|
return this.bridge;
|
|
15546
15814
|
}
|
|
15547
|
-
async buildPathForNode(snapshot, node) {
|
|
15815
|
+
async buildPathForNode(snapshot, node, options) {
|
|
15548
15816
|
if (node.nodeRef === void 0) {
|
|
15549
15817
|
throw new Error(
|
|
15550
15818
|
`snapshot node ${String(node.snapshotNodeId)} does not expose a live node reference`
|
|
15551
15819
|
);
|
|
15552
15820
|
}
|
|
15553
15821
|
return this.buildPath({
|
|
15554
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef)
|
|
15822
|
+
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
15823
|
+
...options?.enableTextMatch ? { enableTextMatch: true } : {}
|
|
15555
15824
|
});
|
|
15556
15825
|
}
|
|
15557
|
-
async tryBuildPathFromNode(snapshot, node) {
|
|
15826
|
+
async tryBuildPathFromNode(snapshot, node, options) {
|
|
15558
15827
|
try {
|
|
15559
|
-
return await this.buildPathForNode(snapshot, node);
|
|
15828
|
+
return await this.buildPathForNode(snapshot, node, options);
|
|
15560
15829
|
} catch {
|
|
15561
15830
|
return void 0;
|
|
15562
15831
|
}
|
|
@@ -15883,12 +16152,16 @@ function toOpensteerResolvedTarget(target) {
|
|
|
15883
16152
|
documentRef: target.documentRef,
|
|
15884
16153
|
documentEpoch: target.documentEpoch,
|
|
15885
16154
|
nodeRef: target.nodeRef,
|
|
15886
|
-
tagName: target.node.nodeName
|
|
16155
|
+
tagName: toOpensteerTagName(target.node.nodeName),
|
|
15887
16156
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
15888
16157
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
15889
16158
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
15890
16159
|
};
|
|
15891
16160
|
}
|
|
16161
|
+
function toOpensteerTagName(nodeName) {
|
|
16162
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
16163
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
16164
|
+
}
|
|
15892
16165
|
var init_trace_enrichment = __esm({
|
|
15893
16166
|
"../runtime-core/src/runtimes/computer-use/trace-enrichment.ts"() {
|
|
15894
16167
|
init_src();
|
|
@@ -15944,7 +16217,7 @@ var init_runtime2 = __esm({
|
|
|
15944
16217
|
screenshot,
|
|
15945
16218
|
signal: input.timeout.signal,
|
|
15946
16219
|
remainingMs: () => input.timeout.remainingMs(),
|
|
15947
|
-
policySettle: async (pageRef, trigger) => {
|
|
16220
|
+
policySettle: async (pageRef, trigger, boundary) => {
|
|
15948
16221
|
try {
|
|
15949
16222
|
await settleWithPolicy(this.options.policy.settle, {
|
|
15950
16223
|
operation: "computer.execute",
|
|
@@ -15952,7 +16225,9 @@ var init_runtime2 = __esm({
|
|
|
15952
16225
|
engine: this.options.engine,
|
|
15953
16226
|
pageRef,
|
|
15954
16227
|
signal: input.timeout.signal,
|
|
15955
|
-
remainingMs: input.timeout.remainingMs()
|
|
16228
|
+
remainingMs: input.timeout.remainingMs(),
|
|
16229
|
+
...boundary?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary.observedMutationQuietMs },
|
|
16230
|
+
...boundary?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
15956
16231
|
});
|
|
15957
16232
|
} catch (error) {
|
|
15958
16233
|
if (pageRef === input.pageRef && isSoftSettleTimeoutError(error, input.timeout.signal)) {
|
|
@@ -16948,29 +17223,29 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
16948
17223
|
const keyStats = /* @__PURE__ */ new Map();
|
|
16949
17224
|
for (const descriptor of descriptors) {
|
|
16950
17225
|
for (const field of descriptor.fields) {
|
|
16951
|
-
const
|
|
17226
|
+
const stat3 = keyStats.get(field.path) ?? {
|
|
16952
17227
|
indices: /* @__PURE__ */ new Set(),
|
|
16953
17228
|
pathNodes: [],
|
|
16954
17229
|
attributes: [],
|
|
16955
17230
|
sources: []
|
|
16956
17231
|
};
|
|
16957
|
-
|
|
17232
|
+
stat3.indices.add(descriptor.index);
|
|
16958
17233
|
if (isPersistedOpensteerExtractionValueNode(field.node)) {
|
|
16959
|
-
|
|
16960
|
-
|
|
17234
|
+
stat3.pathNodes.push(field.node.$path);
|
|
17235
|
+
stat3.attributes.push(field.node.attribute);
|
|
16961
17236
|
} else if (isPersistedOpensteerExtractionSourceNode(field.node)) {
|
|
16962
|
-
|
|
17237
|
+
stat3.sources.push("current_url");
|
|
16963
17238
|
}
|
|
16964
|
-
keyStats.set(field.path,
|
|
17239
|
+
keyStats.set(field.path, stat3);
|
|
16965
17240
|
}
|
|
16966
17241
|
}
|
|
16967
17242
|
const mergedFields = [];
|
|
16968
|
-
for (const [fieldPath,
|
|
16969
|
-
if (
|
|
17243
|
+
for (const [fieldPath, stat3] of keyStats) {
|
|
17244
|
+
if (stat3.indices.size < threshold) {
|
|
16970
17245
|
continue;
|
|
16971
17246
|
}
|
|
16972
|
-
if (
|
|
16973
|
-
let mergedFieldPath =
|
|
17247
|
+
if (stat3.pathNodes.length >= threshold) {
|
|
17248
|
+
let mergedFieldPath = stat3.pathNodes.length === 1 ? sanitizeElementPath(stat3.pathNodes[0]) : mergeElementPathsByMajority(stat3.pathNodes);
|
|
16974
17249
|
if (!mergedFieldPath) {
|
|
16975
17250
|
continue;
|
|
16976
17251
|
}
|
|
@@ -16978,8 +17253,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
16978
17253
|
mergedFieldPath = relaxPathForSingleSample(mergedFieldPath, "field");
|
|
16979
17254
|
}
|
|
16980
17255
|
mergedFieldPath = minimizePathMatchClauses(mergedFieldPath, "field");
|
|
16981
|
-
const attrThreshold =
|
|
16982
|
-
const attribute = pickModeString(
|
|
17256
|
+
const attrThreshold = stat3.pathNodes.length === 1 ? 1 : majorityThreshold(stat3.pathNodes.length);
|
|
17257
|
+
const attribute = pickModeString(stat3.attributes, attrThreshold);
|
|
16983
17258
|
mergedFields.push({
|
|
16984
17259
|
path: fieldPath,
|
|
16985
17260
|
node: createValueNode({
|
|
@@ -16989,7 +17264,7 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
16989
17264
|
});
|
|
16990
17265
|
continue;
|
|
16991
17266
|
}
|
|
16992
|
-
const dominantSource = pickModeString(
|
|
17267
|
+
const dominantSource = pickModeString(stat3.sources, threshold);
|
|
16993
17268
|
if (dominantSource === "current_url") {
|
|
16994
17269
|
mergedFields.push({
|
|
16995
17270
|
path: fieldPath,
|
|
@@ -17126,6 +17401,9 @@ function relaxPathForSingleSample(path24, mode) {
|
|
|
17126
17401
|
}
|
|
17127
17402
|
return !isLast;
|
|
17128
17403
|
}
|
|
17404
|
+
if (clause.kind === "text") {
|
|
17405
|
+
return false;
|
|
17406
|
+
}
|
|
17129
17407
|
const key = String(clause.key || "").trim().toLowerCase();
|
|
17130
17408
|
if (!key || !shouldKeepAttrForSingleSample(key)) {
|
|
17131
17409
|
return false;
|
|
@@ -17228,9 +17506,11 @@ function buildNodeStructure(node) {
|
|
|
17228
17506
|
}
|
|
17229
17507
|
structuralAttrs[key] = value;
|
|
17230
17508
|
}
|
|
17231
|
-
const matchClauses = (node.match || []).map(
|
|
17232
|
-
(clause
|
|
17233
|
-
|
|
17509
|
+
const matchClauses = (node.match || []).map((clause) => {
|
|
17510
|
+
if (clause.kind === "position") return `position:${clause.axis}`;
|
|
17511
|
+
if (clause.kind === "text") return `text:${clause.value}`;
|
|
17512
|
+
return `attr:${String(clause.key || "").trim().toLowerCase()}`;
|
|
17513
|
+
}).sort();
|
|
17234
17514
|
return {
|
|
17235
17515
|
tag,
|
|
17236
17516
|
attrs: structuralAttrs,
|
|
@@ -17636,6 +17916,9 @@ function mergeMatchByMajority(matchLists, attrs, threshold, positionFlags = {
|
|
|
17636
17916
|
});
|
|
17637
17917
|
continue;
|
|
17638
17918
|
}
|
|
17919
|
+
if (clause.kind === "text") {
|
|
17920
|
+
continue;
|
|
17921
|
+
}
|
|
17639
17922
|
if (clause.axis === "nthOfType") {
|
|
17640
17923
|
if (positionFlags.hasNthOfType) {
|
|
17641
17924
|
merged.push({ kind: "position", axis: "nthOfType" });
|
|
@@ -19089,28 +19372,24 @@ function restoreBoundedAttr(el, attr, value) {
|
|
|
19089
19372
|
}
|
|
19090
19373
|
setBoundedAttr(el, attr, value);
|
|
19091
19374
|
}
|
|
19092
|
-
function
|
|
19375
|
+
function deduplicateImagesInDom($) {
|
|
19093
19376
|
const seen = /* @__PURE__ */ new Set();
|
|
19094
|
-
|
|
19095
|
-
|
|
19096
|
-
|
|
19097
|
-
|
|
19098
|
-
const srcMatch = attrContent.match(/\bsrc\s*=\s*(["']?)(.*?)\1/);
|
|
19099
|
-
const srcsetMatch = attrContent.match(/\bsrcset\s*=\s*(["'])(.*?)\1/);
|
|
19100
|
-
let src = null;
|
|
19101
|
-
if (srcMatch && srcMatch[2]) {
|
|
19102
|
-
src = srcMatch[2].trim();
|
|
19103
|
-
} else if (srcsetMatch && srcsetMatch[2]) {
|
|
19104
|
-
src = srcsetMatch[2].split(",")[0]?.trim().split(" ")[0] ?? null;
|
|
19377
|
+
$("img").each(function deduplicateDomImage() {
|
|
19378
|
+
const el = $(this);
|
|
19379
|
+
if (el.attr("c") !== void 0) {
|
|
19380
|
+
return;
|
|
19105
19381
|
}
|
|
19382
|
+
const srcValue = el.attr("src")?.trim();
|
|
19383
|
+
const srcsetValue = el.attr("srcset");
|
|
19384
|
+
const src = srcValue && srcValue.length > 0 ? srcValue : srcsetValue?.split(",")[0]?.trim().split(/\s+/u)[0];
|
|
19106
19385
|
if (!src) {
|
|
19107
|
-
return
|
|
19386
|
+
return;
|
|
19108
19387
|
}
|
|
19109
19388
|
if (seen.has(src)) {
|
|
19110
|
-
|
|
19389
|
+
el.remove();
|
|
19390
|
+
return;
|
|
19111
19391
|
}
|
|
19112
19392
|
seen.add(src);
|
|
19113
|
-
return full;
|
|
19114
19393
|
});
|
|
19115
19394
|
}
|
|
19116
19395
|
function hasAttribute2(node, attr) {
|
|
@@ -19168,23 +19447,6 @@ function isPreservedImageElement(node) {
|
|
|
19168
19447
|
function getElementsInReverseDocumentOrder($) {
|
|
19169
19448
|
return $.root().find("*").toArray().reverse().filter((node) => node.type === "tag");
|
|
19170
19449
|
}
|
|
19171
|
-
function getNodeDepth(node) {
|
|
19172
|
-
let depth = 0;
|
|
19173
|
-
let current = node.parent;
|
|
19174
|
-
while (current) {
|
|
19175
|
-
depth++;
|
|
19176
|
-
current = current.parent;
|
|
19177
|
-
}
|
|
19178
|
-
return depth;
|
|
19179
|
-
}
|
|
19180
|
-
function getElementsByDepthDescending($) {
|
|
19181
|
-
const elements = $.root().find("*").toArray().filter((node) => node.type === "tag");
|
|
19182
|
-
const depths = /* @__PURE__ */ new Map();
|
|
19183
|
-
for (const el of elements) {
|
|
19184
|
-
depths.set(el, getNodeDepth(el));
|
|
19185
|
-
}
|
|
19186
|
-
return elements.sort((a, b) => (depths.get(b) ?? 0) - (depths.get(a) ?? 0));
|
|
19187
|
-
}
|
|
19188
19450
|
function flattenExtractionTree($) {
|
|
19189
19451
|
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
19190
19452
|
const el = $(node);
|
|
@@ -19202,19 +19464,6 @@ function flattenExtractionTree($) {
|
|
|
19202
19464
|
el.replaceWith(el.contents());
|
|
19203
19465
|
}
|
|
19204
19466
|
}
|
|
19205
|
-
function hasMarkedAncestor(el, attr) {
|
|
19206
|
-
let current = el[0]?.parent;
|
|
19207
|
-
while (current) {
|
|
19208
|
-
if (!isElementLikeNode(current)) {
|
|
19209
|
-
return false;
|
|
19210
|
-
}
|
|
19211
|
-
if (current.attribs?.[attr] !== void 0) {
|
|
19212
|
-
return true;
|
|
19213
|
-
}
|
|
19214
|
-
current = current.parent;
|
|
19215
|
-
}
|
|
19216
|
-
return false;
|
|
19217
|
-
}
|
|
19218
19467
|
function isIndicatorImage(node) {
|
|
19219
19468
|
return (node?.tagName || "").toLowerCase() === "img" && (hasAttribute2(node, "alt") || hasAttribute2(node, "src") || hasAttribute2(node, "srcset"));
|
|
19220
19469
|
}
|
|
@@ -19332,7 +19581,7 @@ function serializeForExtraction($, root) {
|
|
|
19332
19581
|
traverse(root, 0);
|
|
19333
19582
|
return lines.map((l) => l.trim()).filter((l) => l.length > 0).join("");
|
|
19334
19583
|
}
|
|
19335
|
-
function isClickable(
|
|
19584
|
+
function isClickable(el, context) {
|
|
19336
19585
|
if (context.hasPreMarked) {
|
|
19337
19586
|
return el.attr(OPENSTEER_INTERACTIVE_ATTR) !== void 0;
|
|
19338
19587
|
}
|
|
@@ -19366,21 +19615,17 @@ function isClickable($, el, context) {
|
|
|
19366
19615
|
}
|
|
19367
19616
|
return false;
|
|
19368
19617
|
}
|
|
19369
|
-
function
|
|
19618
|
+
function prepareExtractionSnapshotDom(html) {
|
|
19370
19619
|
if (!html.trim()) {
|
|
19371
|
-
return
|
|
19620
|
+
return void 0;
|
|
19372
19621
|
}
|
|
19373
19622
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
19374
19623
|
removeNoise($);
|
|
19375
19624
|
removeComments($);
|
|
19376
19625
|
markInlineSelfHiddenFallback($);
|
|
19377
19626
|
pruneSelfHiddenNodes($);
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
{ xmlMode: false }
|
|
19381
|
-
);
|
|
19382
|
-
$clean("*").each(function stripAndRestoreExtractionAttrs() {
|
|
19383
|
-
const el = $clean(this);
|
|
19627
|
+
$("*").each(function stripAndRestoreExtractionAttrs() {
|
|
19628
|
+
const el = $(this);
|
|
19384
19629
|
const node = el[0];
|
|
19385
19630
|
if (!node) {
|
|
19386
19631
|
return;
|
|
@@ -19421,16 +19666,20 @@ function cleanForExtraction(html) {
|
|
|
19421
19666
|
restoreBoundedAttr(el, "href", hrefValue);
|
|
19422
19667
|
}
|
|
19423
19668
|
});
|
|
19424
|
-
flattenExtractionTree($
|
|
19425
|
-
|
|
19669
|
+
flattenExtractionTree($);
|
|
19670
|
+
deduplicateImagesInDom($);
|
|
19671
|
+
return $;
|
|
19672
|
+
}
|
|
19673
|
+
function serializePreparedExtractionSnapshot($) {
|
|
19674
|
+
const root = $.root()[0];
|
|
19426
19675
|
if (root === void 0) {
|
|
19427
19676
|
return "";
|
|
19428
19677
|
}
|
|
19429
|
-
return
|
|
19678
|
+
return serializeForExtraction($, root);
|
|
19430
19679
|
}
|
|
19431
|
-
function
|
|
19680
|
+
function prepareActionSnapshotDom(html) {
|
|
19432
19681
|
if (!html.trim()) {
|
|
19433
|
-
return
|
|
19682
|
+
return void 0;
|
|
19434
19683
|
}
|
|
19435
19684
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
19436
19685
|
removeNoise($);
|
|
@@ -19439,13 +19688,12 @@ function cleanForAction(html) {
|
|
|
19439
19688
|
pruneSelfHiddenNodes($);
|
|
19440
19689
|
const clickableMark = "data-clickable-marker";
|
|
19441
19690
|
const indicatorMark = "data-keep-indicator";
|
|
19442
|
-
const branchMark = "data-keep-branch";
|
|
19443
19691
|
const context = {
|
|
19444
19692
|
hasPreMarked: $(`[${OPENSTEER_INTERACTIVE_ATTR}]`).length > 0
|
|
19445
19693
|
};
|
|
19446
19694
|
$("*").each(function markClickables() {
|
|
19447
19695
|
const el = $(this);
|
|
19448
|
-
if (isClickable(
|
|
19696
|
+
if (isClickable(el, context)) {
|
|
19449
19697
|
el.attr(clickableMark, "1");
|
|
19450
19698
|
}
|
|
19451
19699
|
});
|
|
@@ -19475,25 +19723,7 @@ function cleanForAction(html) {
|
|
|
19475
19723
|
el.remove();
|
|
19476
19724
|
}
|
|
19477
19725
|
});
|
|
19478
|
-
|
|
19479
|
-
let current = $(this).parent();
|
|
19480
|
-
while (current.length > 0) {
|
|
19481
|
-
const node = current[0];
|
|
19482
|
-
if (!node || node.type !== "tag") {
|
|
19483
|
-
break;
|
|
19484
|
-
}
|
|
19485
|
-
const ancestor = current;
|
|
19486
|
-
const tag = (node.tagName || "").toLowerCase();
|
|
19487
|
-
if (ROOT_TAGS.has(tag) || ancestor.attr(clickableMark) !== void 0) {
|
|
19488
|
-
break;
|
|
19489
|
-
}
|
|
19490
|
-
if (!isBoundaryTag(tag)) {
|
|
19491
|
-
ancestor.attr(branchMark, "1");
|
|
19492
|
-
}
|
|
19493
|
-
current = ancestor.parent();
|
|
19494
|
-
}
|
|
19495
|
-
});
|
|
19496
|
-
for (const node of getElementsByDepthDescending($)) {
|
|
19726
|
+
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
19497
19727
|
const el = $(node);
|
|
19498
19728
|
const tag = (node.tagName || "").toLowerCase();
|
|
19499
19729
|
if (ROOT_TAGS.has(tag) || isBoundaryTag(tag)) {
|
|
@@ -19502,17 +19732,7 @@ function cleanForAction(html) {
|
|
|
19502
19732
|
if (el.attr(clickableMark) !== void 0 || el.attr(indicatorMark) !== void 0) {
|
|
19503
19733
|
continue;
|
|
19504
19734
|
}
|
|
19505
|
-
const insideClickable = hasMarkedAncestor(el, clickableMark);
|
|
19506
|
-
const preserveBranch = el.attr(branchMark) !== void 0;
|
|
19507
19735
|
const hasContent = hasElementChildren(node) || hasDirectText(node);
|
|
19508
|
-
if (insideClickable || preserveBranch) {
|
|
19509
|
-
if (!hasContent) {
|
|
19510
|
-
el.remove();
|
|
19511
|
-
} else {
|
|
19512
|
-
unwrapActionNode($, el);
|
|
19513
|
-
}
|
|
19514
|
-
continue;
|
|
19515
|
-
}
|
|
19516
19736
|
if (!hasContent) {
|
|
19517
19737
|
el.remove();
|
|
19518
19738
|
continue;
|
|
@@ -19613,13 +19833,20 @@ function cleanForAction(html) {
|
|
|
19613
19833
|
}
|
|
19614
19834
|
el.removeAttr(clickableMark);
|
|
19615
19835
|
el.removeAttr(indicatorMark);
|
|
19616
|
-
el.removeAttr(branchMark);
|
|
19617
19836
|
el.removeAttr(OPENSTEER_INTERACTIVE_ATTR);
|
|
19618
19837
|
el.removeAttr(OPENSTEER_HIDDEN_ATTR);
|
|
19619
19838
|
el.removeAttr(OPENSTEER_SCROLLABLE_ATTR);
|
|
19620
19839
|
el.removeAttr(OPENSTEER_SELF_HIDDEN_ATTR);
|
|
19621
19840
|
});
|
|
19622
|
-
|
|
19841
|
+
deduplicateImagesInDom($);
|
|
19842
|
+
return $;
|
|
19843
|
+
}
|
|
19844
|
+
function serializePreparedActionSnapshot($) {
|
|
19845
|
+
const normalized = compactHtml($.html());
|
|
19846
|
+
if (normalized.length === 0) {
|
|
19847
|
+
return "";
|
|
19848
|
+
}
|
|
19849
|
+
return cheerio__namespace.load(normalized, { xmlMode: false }).html();
|
|
19623
19850
|
}
|
|
19624
19851
|
var STRIP_TAGS, TEXT_ATTR_MAX, SRCSET_ATTR_MAX, MIDDLE_TRUNCATED_URL_ATTRS, TEXT_ATTRS, TRUNCATION_SUFFIX, MIDDLE_TRUNCATION_MARKER, MIDDLE_TRUNCATION_HEAD_MAX, MIDDLE_TRUNCATION_TAIL_MAX, SRCSET_CANDIDATE_HEAD_MAX, SRCSET_CANDIDATE_TAIL_MAX, SRCSET_COMPACT_CANDIDATE_HEAD_MAX, SRCSET_COMPACT_CANDIDATE_TAIL_MAX, SRCSET_FALLBACK_HEAD_MAX, SRCSET_FALLBACK_TAIL_MAX, NOISE_SELECTORS, VOID_TAGS2;
|
|
19625
19852
|
var init_cleaner = __esm({
|
|
@@ -19680,23 +19907,27 @@ async function markLiveSnapshotSemantics(options) {
|
|
|
19680
19907
|
const frames = await options.engine.listFrames({
|
|
19681
19908
|
pageRef: options.pageRef
|
|
19682
19909
|
});
|
|
19683
|
-
|
|
19684
|
-
|
|
19685
|
-
|
|
19686
|
-
frame.frameRef,
|
|
19687
|
-
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
19688
|
-
SNAPSHOT_SEMANTIC_ARGS
|
|
19689
|
-
);
|
|
19690
|
-
}
|
|
19691
|
-
return async () => {
|
|
19692
|
-
for (const frame of frames) {
|
|
19693
|
-
await evaluateFrameBestEffort(
|
|
19910
|
+
await Promise.all(
|
|
19911
|
+
frames.map(
|
|
19912
|
+
(frame) => evaluateFrameBestEffort(
|
|
19694
19913
|
options.engine,
|
|
19695
19914
|
frame.frameRef,
|
|
19696
|
-
|
|
19697
|
-
|
|
19698
|
-
)
|
|
19699
|
-
|
|
19915
|
+
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
19916
|
+
SNAPSHOT_SEMANTIC_ARGS
|
|
19917
|
+
)
|
|
19918
|
+
)
|
|
19919
|
+
);
|
|
19920
|
+
return async () => {
|
|
19921
|
+
await Promise.all(
|
|
19922
|
+
frames.map(
|
|
19923
|
+
(frame) => evaluateFrameBestEffort(
|
|
19924
|
+
options.engine,
|
|
19925
|
+
frame.frameRef,
|
|
19926
|
+
CLEAR_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
19927
|
+
CLEAR_SNAPSHOT_SEMANTIC_ARGS
|
|
19928
|
+
)
|
|
19929
|
+
)
|
|
19930
|
+
);
|
|
19700
19931
|
};
|
|
19701
19932
|
}
|
|
19702
19933
|
var MARK_SNAPSHOT_SEMANTICS_SCRIPT, CLEAR_SNAPSHOT_SEMANTICS_SCRIPT, SNAPSHOT_SEMANTIC_ARGS, CLEAR_SNAPSHOT_SEMANTIC_ARGS;
|
|
@@ -19894,6 +20125,8 @@ var init_marking = __esm({
|
|
|
19894
20125
|
];
|
|
19895
20126
|
}
|
|
19896
20127
|
});
|
|
20128
|
+
|
|
20129
|
+
// ../runtime-core/src/sdk/snapshot/compiler.ts
|
|
19897
20130
|
function isLiveCounterSyncError(error) {
|
|
19898
20131
|
return error instanceof LiveCounterSyncError;
|
|
19899
20132
|
}
|
|
@@ -19931,20 +20164,22 @@ function ensureSparseCountersForAllRecords(counterRecords) {
|
|
|
19931
20164
|
async function clearOpensteerLiveCounters(engine, pageRef) {
|
|
19932
20165
|
const frames = await engine.listFrames({ pageRef });
|
|
19933
20166
|
const failures = [];
|
|
19934
|
-
|
|
19935
|
-
|
|
19936
|
-
|
|
19937
|
-
|
|
19938
|
-
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
|
|
20167
|
+
await Promise.all(
|
|
20168
|
+
frames.map(async (frame) => {
|
|
20169
|
+
try {
|
|
20170
|
+
await engine.evaluateFrame({
|
|
20171
|
+
frameRef: frame.frameRef,
|
|
20172
|
+
script: CLEAR_LIVE_COUNTERS_SCRIPT,
|
|
20173
|
+
args: [{ sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR }]
|
|
20174
|
+
});
|
|
20175
|
+
} catch (error) {
|
|
20176
|
+
if (isDetachedFrameSyncError(error)) {
|
|
20177
|
+
return;
|
|
20178
|
+
}
|
|
20179
|
+
failures.push(`frame ${frame.frameRef} could not be cleared (${describeError(error)}).`);
|
|
19944
20180
|
}
|
|
19945
|
-
|
|
19946
|
-
|
|
19947
|
-
}
|
|
20181
|
+
})
|
|
20182
|
+
);
|
|
19948
20183
|
if (failures.length > 0) {
|
|
19949
20184
|
throw buildLiveCounterSyncError("clear live counters", failures);
|
|
19950
20185
|
}
|
|
@@ -19993,25 +20228,29 @@ async function syncDenseCountersToLiveDom(engine, pageRef, sparseToDirectMapping
|
|
|
19993
20228
|
denseCounter
|
|
19994
20229
|
])
|
|
19995
20230
|
);
|
|
19996
|
-
|
|
19997
|
-
|
|
19998
|
-
|
|
19999
|
-
|
|
20000
|
-
|
|
20001
|
-
|
|
20002
|
-
|
|
20003
|
-
|
|
20004
|
-
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
|
|
20010
|
-
|
|
20231
|
+
await Promise.all(
|
|
20232
|
+
frames.map(async (frame) => {
|
|
20233
|
+
try {
|
|
20234
|
+
await engine.evaluateFrame({
|
|
20235
|
+
frameRef: frame.frameRef,
|
|
20236
|
+
script: APPLY_DENSE_COUNTERS_SCRIPT,
|
|
20237
|
+
args: [
|
|
20238
|
+
{
|
|
20239
|
+
sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR,
|
|
20240
|
+
mapping: mappingObj
|
|
20241
|
+
}
|
|
20242
|
+
]
|
|
20243
|
+
});
|
|
20244
|
+
} catch (error) {
|
|
20245
|
+
if (isDetachedFrameSyncError(error)) {
|
|
20246
|
+
return;
|
|
20247
|
+
}
|
|
20248
|
+
failures.push(
|
|
20249
|
+
`frame ${frame.frameRef} could not be synchronized (${describeError(error)}).`
|
|
20250
|
+
);
|
|
20011
20251
|
}
|
|
20012
|
-
|
|
20013
|
-
|
|
20014
|
-
}
|
|
20252
|
+
})
|
|
20253
|
+
);
|
|
20015
20254
|
if (failures.length > 0) {
|
|
20016
20255
|
throw buildLiveCounterSyncError("synchronize dense counters", failures);
|
|
20017
20256
|
}
|
|
@@ -20029,26 +20268,26 @@ async function compileOpensteerSnapshot(options) {
|
|
|
20029
20268
|
await clearOpensteerLiveCounters(options.engine, options.pageRef);
|
|
20030
20269
|
await assignSparseCountersToLiveDom(options.engine, options.pageRef);
|
|
20031
20270
|
const pageInfo = await options.engine.getPageInfo({ pageRef: options.pageRef });
|
|
20032
|
-
const mainSnapshot = await
|
|
20033
|
-
|
|
20271
|
+
const { mainSnapshot, snapshotsByDocumentRef } = await getPageDocumentSnapshots(
|
|
20272
|
+
options.engine,
|
|
20273
|
+
options.pageRef
|
|
20274
|
+
);
|
|
20034
20275
|
await cleanupLiveSemantics();
|
|
20035
20276
|
cleanupLiveSemantics = async () => {
|
|
20036
20277
|
};
|
|
20037
|
-
const snapshotIndices = /* @__PURE__ */ new Map();
|
|
20038
20278
|
const renderedNodes = /* @__PURE__ */ new Map();
|
|
20039
20279
|
const rawHtml = renderDocumentSnapshot(
|
|
20040
20280
|
mainSnapshot.documentRef,
|
|
20041
20281
|
snapshotsByDocumentRef,
|
|
20042
|
-
snapshotIndices,
|
|
20043
20282
|
renderedNodes,
|
|
20044
20283
|
{
|
|
20045
20284
|
iframeDepth: 0,
|
|
20046
20285
|
shadowDepth: 0
|
|
20047
20286
|
}
|
|
20048
20287
|
);
|
|
20049
|
-
const
|
|
20050
|
-
const compiledHtml =
|
|
20051
|
-
const finalHtml = options.mode === "extraction" ?
|
|
20288
|
+
const preparedSnapshotDom = options.mode === "extraction" ? prepareExtractionSnapshotDom(rawHtml) : prepareActionSnapshotDom(rawHtml);
|
|
20289
|
+
const compiledHtml = assignCountersInDom(preparedSnapshotDom, renderedNodes, options.mode);
|
|
20290
|
+
const finalHtml = preparedSnapshotDom === void 0 ? "" : options.mode === "extraction" ? serializePreparedExtractionSnapshot(preparedSnapshotDom) : serializePreparedActionSnapshot(preparedSnapshotDom);
|
|
20052
20291
|
ensureSparseCountersForAllRecords(compiledHtml.counterRecords);
|
|
20053
20292
|
await syncDenseCountersToLiveDom(
|
|
20054
20293
|
options.engine,
|
|
@@ -20083,6 +20322,25 @@ async function getMainDocumentSnapshot(engine, pageRef) {
|
|
|
20083
20322
|
}
|
|
20084
20323
|
return engine.getDomSnapshot({ frameRef: mainFrame.frameRef });
|
|
20085
20324
|
}
|
|
20325
|
+
async function getPageDocumentSnapshots(engine, pageRef) {
|
|
20326
|
+
const bundleEngine = engine;
|
|
20327
|
+
const bundledSnapshots = await bundleEngine.getPageDomSnapshots?.({ pageRef });
|
|
20328
|
+
if (bundledSnapshots && bundledSnapshots.length > 0) {
|
|
20329
|
+
const mainSnapshot2 = bundledSnapshots.find((snapshot) => snapshot.parentDocumentRef === void 0) ?? bundledSnapshots[0];
|
|
20330
|
+
return {
|
|
20331
|
+
mainSnapshot: mainSnapshot2,
|
|
20332
|
+
snapshotsByDocumentRef: new Map(
|
|
20333
|
+
bundledSnapshots.map((snapshot) => [snapshot.documentRef, snapshot])
|
|
20334
|
+
)
|
|
20335
|
+
};
|
|
20336
|
+
}
|
|
20337
|
+
const mainSnapshot = await getMainDocumentSnapshot(engine, pageRef);
|
|
20338
|
+
const snapshotsByDocumentRef = await collectDocumentSnapshots(engine, mainSnapshot);
|
|
20339
|
+
return {
|
|
20340
|
+
mainSnapshot,
|
|
20341
|
+
snapshotsByDocumentRef
|
|
20342
|
+
};
|
|
20343
|
+
}
|
|
20086
20344
|
async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
20087
20345
|
const snapshotsByDocumentRef = /* @__PURE__ */ new Map([
|
|
20088
20346
|
[mainSnapshot.documentRef, mainSnapshot]
|
|
@@ -20101,7 +20359,7 @@ async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
|
20101
20359
|
}
|
|
20102
20360
|
return snapshotsByDocumentRef;
|
|
20103
20361
|
}
|
|
20104
|
-
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef,
|
|
20362
|
+
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
20105
20363
|
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
20106
20364
|
if (!snapshot) {
|
|
20107
20365
|
return "";
|
|
@@ -20113,17 +20371,9 @@ function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, snapshotInd
|
|
|
20113
20371
|
`snapshot ${snapshot.documentRef} is missing root node ${String(snapshot.rootSnapshotNodeId)}`
|
|
20114
20372
|
);
|
|
20115
20373
|
}
|
|
20116
|
-
return renderNode(
|
|
20117
|
-
snapshot,
|
|
20118
|
-
rootNode,
|
|
20119
|
-
nodesById,
|
|
20120
|
-
snapshotsByDocumentRef,
|
|
20121
|
-
snapshotIndices,
|
|
20122
|
-
renderedNodes,
|
|
20123
|
-
depth
|
|
20124
|
-
);
|
|
20374
|
+
return renderNode(snapshot, rootNode, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20125
20375
|
}
|
|
20126
|
-
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
20376
|
+
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
20127
20377
|
if (node.nodeType === 3) {
|
|
20128
20378
|
return escapeHtml(node.nodeValue || node.textContent || "");
|
|
20129
20379
|
}
|
|
@@ -20131,56 +20381,26 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20131
20381
|
return "";
|
|
20132
20382
|
}
|
|
20133
20383
|
if (node.nodeType === 9 || node.nodeType === 11) {
|
|
20134
|
-
return renderChildren(
|
|
20135
|
-
snapshot,
|
|
20136
|
-
node,
|
|
20137
|
-
nodesById,
|
|
20138
|
-
snapshotsByDocumentRef,
|
|
20139
|
-
snapshotIndices,
|
|
20140
|
-
renderedNodes,
|
|
20141
|
-
depth
|
|
20142
|
-
);
|
|
20384
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20143
20385
|
}
|
|
20144
20386
|
if (node.nodeType !== 1) {
|
|
20145
|
-
return renderChildren(
|
|
20146
|
-
snapshot,
|
|
20147
|
-
node,
|
|
20148
|
-
nodesById,
|
|
20149
|
-
snapshotsByDocumentRef,
|
|
20150
|
-
snapshotIndices,
|
|
20151
|
-
renderedNodes,
|
|
20152
|
-
depth
|
|
20153
|
-
);
|
|
20387
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20154
20388
|
}
|
|
20155
20389
|
const tagName = normalizeTagName(node.nodeName);
|
|
20156
20390
|
if (isPseudoElementTagName(tagName)) {
|
|
20157
|
-
return renderChildren(
|
|
20158
|
-
snapshot,
|
|
20159
|
-
node,
|
|
20160
|
-
nodesById,
|
|
20161
|
-
snapshotsByDocumentRef,
|
|
20162
|
-
snapshotIndices,
|
|
20163
|
-
renderedNodes,
|
|
20164
|
-
depth
|
|
20165
|
-
);
|
|
20391
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20166
20392
|
}
|
|
20167
20393
|
if ((depth.iframeDepth > 0 || depth.shadowDepth > 0) && (tagName === "html" || tagName === "head" || tagName === "body")) {
|
|
20168
|
-
return renderChildren(
|
|
20169
|
-
snapshot,
|
|
20170
|
-
node,
|
|
20171
|
-
nodesById,
|
|
20172
|
-
snapshotsByDocumentRef,
|
|
20173
|
-
snapshotIndices,
|
|
20174
|
-
renderedNodes,
|
|
20175
|
-
depth
|
|
20176
|
-
);
|
|
20394
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20177
20395
|
}
|
|
20178
20396
|
const snapshotAttributes = normalizeNodeAttributes(node.attributes);
|
|
20397
|
+
const snapshotAttributeIndex = indexNodeAttributes(snapshotAttributes);
|
|
20179
20398
|
const authoredAttributes = stripInternalSnapshotAttributes(snapshotAttributes);
|
|
20399
|
+
const authoredAttributeIndex = indexNodeAttributes(authoredAttributes);
|
|
20180
20400
|
const attributes = [...authoredAttributes];
|
|
20181
|
-
const subtreeHidden =
|
|
20182
|
-
const selfHidden = !subtreeHidden && (
|
|
20183
|
-
const interactive = !subtreeHidden && !selfHidden && (
|
|
20401
|
+
const subtreeHidden = snapshotAttributeIndex.has(OPENSTEER_HIDDEN_ATTR) || isLikelySubtreeHidden(node);
|
|
20402
|
+
const selfHidden = !subtreeHidden && (snapshotAttributeIndex.has(OPENSTEER_SELF_HIDDEN_ATTR) || isLikelySelfHidden(node, nodesById));
|
|
20403
|
+
const interactive = !subtreeHidden && !selfHidden && (snapshotAttributeIndex.has(OPENSTEER_INTERACTIVE_ATTR) || isLikelyInteractive(tagName, node, authoredAttributes, authoredAttributeIndex));
|
|
20184
20404
|
if (interactive) {
|
|
20185
20405
|
attributes.push({ name: OPENSTEER_INTERACTIVE_ATTR, value: "1" });
|
|
20186
20406
|
}
|
|
@@ -20189,7 +20409,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20189
20409
|
} else if (selfHidden) {
|
|
20190
20410
|
attributes.push({ name: OPENSTEER_SELF_HIDDEN_ATTR, value: "1" });
|
|
20191
20411
|
}
|
|
20192
|
-
const sparseCounter =
|
|
20412
|
+
const sparseCounter = snapshotAttributeIndex.get(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20193
20413
|
if (sparseCounter !== void 0) {
|
|
20194
20414
|
attributes.push({ name: OPENSTEER_SPARSE_COUNTER_ATTR, value: sparseCounter });
|
|
20195
20415
|
}
|
|
@@ -20200,21 +20420,18 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20200
20420
|
const syntheticNodeId = buildSyntheticNodeId(snapshot, node);
|
|
20201
20421
|
attributes.push({ name: OPENSTEER_NODE_ID_ATTR, value: syntheticNodeId });
|
|
20202
20422
|
renderedNodes.set(syntheticNodeId, {
|
|
20203
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
20204
|
-
anchor: buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices),
|
|
20205
20423
|
pageRef: snapshot.pageRef,
|
|
20206
20424
|
frameRef: snapshot.frameRef,
|
|
20207
20425
|
documentRef: snapshot.documentRef,
|
|
20208
20426
|
documentEpoch: snapshot.documentEpoch,
|
|
20209
20427
|
nodeRef: node.nodeRef,
|
|
20210
20428
|
tagName: tagName.toUpperCase(),
|
|
20211
|
-
pathHint: buildPathHint(tagName, authoredAttributes),
|
|
20212
|
-
...buildTextSnippet(node.textContent) === void 0 ? {} : { text: buildTextSnippet(node.textContent) },
|
|
20213
20429
|
...authoredAttributes.length === 0 ? {} : { attributes: authoredAttributes },
|
|
20214
20430
|
iframeDepth: depth.iframeDepth,
|
|
20215
20431
|
shadowDepth: depth.shadowDepth,
|
|
20216
20432
|
interactive,
|
|
20217
|
-
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById)
|
|
20433
|
+
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById),
|
|
20434
|
+
...node.textContent === void 0 ? {} : { textContent: node.textContent }
|
|
20218
20435
|
});
|
|
20219
20436
|
}
|
|
20220
20437
|
const attributeText = attributesToHtml(attributes);
|
|
@@ -20223,7 +20440,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20223
20440
|
node,
|
|
20224
20441
|
nodesById,
|
|
20225
20442
|
snapshotsByDocumentRef,
|
|
20226
|
-
snapshotIndices,
|
|
20227
20443
|
renderedNodes,
|
|
20228
20444
|
depth
|
|
20229
20445
|
);
|
|
@@ -20234,7 +20450,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20234
20450
|
const iframeHtml = renderDocumentSnapshot(
|
|
20235
20451
|
node.contentDocumentRef,
|
|
20236
20452
|
snapshotsByDocumentRef,
|
|
20237
|
-
snapshotIndices,
|
|
20238
20453
|
renderedNodes,
|
|
20239
20454
|
{
|
|
20240
20455
|
iframeDepth: depth.iframeDepth + 1,
|
|
@@ -20246,7 +20461,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20246
20461
|
}
|
|
20247
20462
|
return `${elementHtml}<${OPENSTEER_IFRAME_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="iframe">${iframeHtml}</${OPENSTEER_IFRAME_BOUNDARY_TAG}>`;
|
|
20248
20463
|
}
|
|
20249
|
-
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
20464
|
+
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
20250
20465
|
const regularChildren = [];
|
|
20251
20466
|
const shadowChildren = [];
|
|
20252
20467
|
for (const childSnapshotNodeId of node.childSnapshotNodeIds) {
|
|
@@ -20263,18 +20478,10 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
20263
20478
|
const chunks = [];
|
|
20264
20479
|
if (shadowChildren.length > 0) {
|
|
20265
20480
|
const shadowHtml = shadowChildren.map(
|
|
20266
|
-
(child) => renderNode(
|
|
20267
|
-
|
|
20268
|
-
|
|
20269
|
-
|
|
20270
|
-
snapshotsByDocumentRef,
|
|
20271
|
-
snapshotIndices,
|
|
20272
|
-
renderedNodes,
|
|
20273
|
-
{
|
|
20274
|
-
iframeDepth: depth.iframeDepth,
|
|
20275
|
-
shadowDepth: depth.shadowDepth + 1
|
|
20276
|
-
}
|
|
20277
|
-
)
|
|
20481
|
+
(child) => renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, {
|
|
20482
|
+
iframeDepth: depth.iframeDepth,
|
|
20483
|
+
shadowDepth: depth.shadowDepth + 1
|
|
20484
|
+
})
|
|
20278
20485
|
).join("");
|
|
20279
20486
|
chunks.push(
|
|
20280
20487
|
`<${OPENSTEER_SHADOW_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="shadow">${shadowHtml}</${OPENSTEER_SHADOW_BOUNDARY_TAG}>`
|
|
@@ -20282,24 +20489,21 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
20282
20489
|
}
|
|
20283
20490
|
for (const child of regularChildren) {
|
|
20284
20491
|
chunks.push(
|
|
20285
|
-
renderNode(
|
|
20286
|
-
snapshot,
|
|
20287
|
-
child,
|
|
20288
|
-
nodesById,
|
|
20289
|
-
snapshotsByDocumentRef,
|
|
20290
|
-
snapshotIndices,
|
|
20291
|
-
renderedNodes,
|
|
20292
|
-
depth
|
|
20293
|
-
)
|
|
20492
|
+
renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, depth)
|
|
20294
20493
|
);
|
|
20295
20494
|
}
|
|
20296
20495
|
return chunks.join("");
|
|
20297
20496
|
}
|
|
20298
|
-
function
|
|
20299
|
-
const $ = cheerio__namespace.load(cleanedHtml, { xmlMode: false });
|
|
20497
|
+
function assignCountersInDom($, renderedNodes, mode) {
|
|
20300
20498
|
const counterRecords = /* @__PURE__ */ new Map();
|
|
20301
20499
|
const sparseToDirectMapping = /* @__PURE__ */ new Map();
|
|
20302
20500
|
let nextCounter = 1;
|
|
20501
|
+
if (!$) {
|
|
20502
|
+
return {
|
|
20503
|
+
counterRecords,
|
|
20504
|
+
sparseToDirectMapping
|
|
20505
|
+
};
|
|
20506
|
+
}
|
|
20303
20507
|
$("*").each(function assignElementCounter() {
|
|
20304
20508
|
const el = $(this);
|
|
20305
20509
|
const syntheticNodeId = el.attr(OPENSTEER_NODE_ID_ATTR);
|
|
@@ -20311,14 +20515,24 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
20311
20515
|
if (!rendered) {
|
|
20312
20516
|
return;
|
|
20313
20517
|
}
|
|
20518
|
+
if (mode === "extraction" && EXTRACTION_SKIPPED_COUNTER_TAGS.has(rendered.tagName.toLowerCase())) {
|
|
20519
|
+
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20520
|
+
return;
|
|
20521
|
+
}
|
|
20314
20522
|
const rawSparseCounter = el.attr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20315
20523
|
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20316
20524
|
const sparseCounter = rawSparseCounter ? Number.parseInt(rawSparseCounter, 10) : void 0;
|
|
20525
|
+
const replayableSparseCounter = typeof sparseCounter === "number" && Number.isFinite(sparseCounter) ? sparseCounter : void 0;
|
|
20526
|
+
if (rendered.liveCounterSyncEligible && replayableSparseCounter === void 0) {
|
|
20527
|
+
return;
|
|
20528
|
+
}
|
|
20317
20529
|
const counter = nextCounter++;
|
|
20318
20530
|
el.attr("c", String(counter));
|
|
20319
|
-
if (
|
|
20320
|
-
sparseToDirectMapping.set(
|
|
20531
|
+
if (replayableSparseCounter !== void 0) {
|
|
20532
|
+
sparseToDirectMapping.set(replayableSparseCounter, counter);
|
|
20321
20533
|
}
|
|
20534
|
+
const pathHint = buildPathHint(rendered.tagName.toLowerCase(), rendered.attributes ?? []);
|
|
20535
|
+
const text = buildTextSnippet(rendered.textContent);
|
|
20322
20536
|
counterRecords.set(counter, {
|
|
20323
20537
|
element: counter,
|
|
20324
20538
|
pageRef: rendered.pageRef,
|
|
@@ -20327,20 +20541,17 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
20327
20541
|
documentEpoch: rendered.documentEpoch,
|
|
20328
20542
|
nodeRef: rendered.nodeRef,
|
|
20329
20543
|
tagName: rendered.tagName,
|
|
20330
|
-
pathHint
|
|
20331
|
-
...
|
|
20544
|
+
pathHint,
|
|
20545
|
+
...text === void 0 ? {} : { text },
|
|
20332
20546
|
...rendered.attributes === void 0 ? {} : { attributes: rendered.attributes },
|
|
20333
20547
|
iframeDepth: rendered.iframeDepth,
|
|
20334
20548
|
shadowDepth: rendered.shadowDepth,
|
|
20335
20549
|
interactive: rendered.interactive,
|
|
20336
20550
|
liveCounterSyncEligible: rendered.liveCounterSyncEligible,
|
|
20337
|
-
|
|
20338
|
-
anchor: rendered.anchor,
|
|
20339
|
-
...sparseCounter !== void 0 && Number.isFinite(sparseCounter) ? { sparseCounter } : {}
|
|
20551
|
+
...replayableSparseCounter === void 0 ? {} : { sparseCounter: replayableSparseCounter }
|
|
20340
20552
|
});
|
|
20341
20553
|
});
|
|
20342
20554
|
return {
|
|
20343
|
-
html: $.html(),
|
|
20344
20555
|
counterRecords,
|
|
20345
20556
|
sparseToDirectMapping
|
|
20346
20557
|
};
|
|
@@ -20414,28 +20625,28 @@ function isLikelySelfHidden(node, nodesById) {
|
|
|
20414
20625
|
}
|
|
20415
20626
|
return !hasVisibleOutOfFlowChild(node, nodesById);
|
|
20416
20627
|
}
|
|
20417
|
-
function isLikelyInteractive(tagName, node, attributes) {
|
|
20628
|
+
function isLikelyInteractive(tagName, node, attributes, attributeIndex) {
|
|
20418
20629
|
if (NATIVE_INTERACTIVE_TAGS.has(tagName)) {
|
|
20419
|
-
if (tagName === "input" &&
|
|
20630
|
+
if (tagName === "input" && attributeIndex.get("type")?.toLowerCase() === "hidden") {
|
|
20420
20631
|
return false;
|
|
20421
20632
|
}
|
|
20422
20633
|
if (tagName !== "a") {
|
|
20423
20634
|
return true;
|
|
20424
20635
|
}
|
|
20425
20636
|
}
|
|
20426
|
-
if (tagName === "a" &&
|
|
20637
|
+
if (tagName === "a" && attributeIndex.has("href")) {
|
|
20427
20638
|
return true;
|
|
20428
20639
|
}
|
|
20429
|
-
if (
|
|
20640
|
+
if (attributeIndex.has("onclick") || attributeIndex.has("onmousedown") || attributeIndex.has("onmouseup") || attributeIndex.has("data-action") || attributeIndex.has("data-click") || attributeIndex.has("data-toggle")) {
|
|
20430
20641
|
return true;
|
|
20431
20642
|
}
|
|
20432
|
-
if (hasNonNegativeTabIndex(
|
|
20643
|
+
if (hasNonNegativeTabIndex(attributeIndex.get("tabindex"))) {
|
|
20433
20644
|
return true;
|
|
20434
20645
|
}
|
|
20435
|
-
if (
|
|
20646
|
+
if (attributeIndex.get("contenteditable")?.toLowerCase() === "true") {
|
|
20436
20647
|
return true;
|
|
20437
20648
|
}
|
|
20438
|
-
const role =
|
|
20649
|
+
const role = attributeIndex.get("role")?.toLowerCase();
|
|
20439
20650
|
return role !== void 0 && INTERACTIVE_ROLE_SET.has(role);
|
|
20440
20651
|
}
|
|
20441
20652
|
function hasVisibleOutOfFlowChild(node, nodesById) {
|
|
@@ -20498,14 +20709,6 @@ function parseOpacity(value) {
|
|
|
20498
20709
|
const parsed = Number.parseFloat(value);
|
|
20499
20710
|
return Number.isFinite(parsed) ? parsed : Number.NaN;
|
|
20500
20711
|
}
|
|
20501
|
-
function hasAttribute3(attributes, name) {
|
|
20502
|
-
const normalizedName = name.toLowerCase();
|
|
20503
|
-
return attributes.some((attribute) => attribute.name.toLowerCase() === normalizedName);
|
|
20504
|
-
}
|
|
20505
|
-
function unwrapExtractionHtml(html) {
|
|
20506
|
-
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
20507
|
-
return $("body").html()?.trim() || html;
|
|
20508
|
-
}
|
|
20509
20712
|
function buildSyntheticNodeId(snapshot, node) {
|
|
20510
20713
|
return `${snapshot.documentRef}:${String(snapshot.documentEpoch)}:${String(node.snapshotNodeId)}`;
|
|
20511
20714
|
}
|
|
@@ -20552,6 +20755,13 @@ function findAttributeValue(attributes, name) {
|
|
|
20552
20755
|
const normalizedName = name.toLowerCase();
|
|
20553
20756
|
return attributes.find((attribute) => attribute.name.toLowerCase() === normalizedName)?.value;
|
|
20554
20757
|
}
|
|
20758
|
+
function indexNodeAttributes(attributes) {
|
|
20759
|
+
const indexed = /* @__PURE__ */ new Map();
|
|
20760
|
+
for (const attribute of attributes) {
|
|
20761
|
+
indexed.set(attribute.name.toLowerCase(), attribute.value);
|
|
20762
|
+
}
|
|
20763
|
+
return indexed;
|
|
20764
|
+
}
|
|
20555
20765
|
function attributesToHtml(attributes) {
|
|
20556
20766
|
if (attributes.length === 0) {
|
|
20557
20767
|
return "";
|
|
@@ -20561,68 +20771,16 @@ function attributesToHtml(attributes) {
|
|
|
20561
20771
|
function escapeAttribute(value) {
|
|
20562
20772
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
20563
20773
|
}
|
|
20564
|
-
function buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices) {
|
|
20565
|
-
const index = getSnapshotIndex(snapshot.documentRef, snapshotsByDocumentRef, snapshotIndices);
|
|
20566
|
-
const localAnchor = buildLocalStructuralElementAnchor(index, node);
|
|
20567
|
-
return prefixIframeContext(snapshot, localAnchor, snapshotsByDocumentRef, snapshotIndices);
|
|
20568
|
-
}
|
|
20569
|
-
function prefixIframeContext(snapshot, localPath, snapshotsByDocumentRef, snapshotIndices) {
|
|
20570
|
-
if (snapshot.parentDocumentRef === void 0) {
|
|
20571
|
-
return sanitizeStructuralElementAnchor(localPath);
|
|
20572
|
-
}
|
|
20573
|
-
const parentSnapshot = snapshotsByDocumentRef.get(snapshot.parentDocumentRef);
|
|
20574
|
-
if (!parentSnapshot) {
|
|
20575
|
-
throw new Error(
|
|
20576
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no parent snapshot`
|
|
20577
|
-
);
|
|
20578
|
-
}
|
|
20579
|
-
const parentIndex = getSnapshotIndex(
|
|
20580
|
-
parentSnapshot.documentRef,
|
|
20581
|
-
snapshotsByDocumentRef,
|
|
20582
|
-
snapshotIndices
|
|
20583
|
-
);
|
|
20584
|
-
const iframeHost = findIframeHostNode(parentIndex, snapshot.documentRef);
|
|
20585
|
-
if (!iframeHost) {
|
|
20586
|
-
throw new Error(
|
|
20587
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no iframe host`
|
|
20588
|
-
);
|
|
20589
|
-
}
|
|
20590
|
-
const hostPath = buildSnapshotElementAnchor(
|
|
20591
|
-
parentSnapshot,
|
|
20592
|
-
iframeHost,
|
|
20593
|
-
snapshotsByDocumentRef,
|
|
20594
|
-
snapshotIndices
|
|
20595
|
-
);
|
|
20596
|
-
return sanitizeStructuralElementAnchor({
|
|
20597
|
-
context: [...hostPath.context, { kind: "iframe", host: hostPath.nodes }, ...localPath.context],
|
|
20598
|
-
nodes: localPath.nodes
|
|
20599
|
-
});
|
|
20600
|
-
}
|
|
20601
|
-
function getSnapshotIndex(documentRef, snapshotsByDocumentRef, snapshotIndices) {
|
|
20602
|
-
const existing = snapshotIndices.get(documentRef);
|
|
20603
|
-
if (existing) {
|
|
20604
|
-
return existing;
|
|
20605
|
-
}
|
|
20606
|
-
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
20607
|
-
if (!snapshot) {
|
|
20608
|
-
throw new Error(`missing DOM snapshot for ${documentRef}`);
|
|
20609
|
-
}
|
|
20610
|
-
const index = createSnapshotIndex(snapshot);
|
|
20611
|
-
snapshotIndices.set(documentRef, index);
|
|
20612
|
-
return index;
|
|
20613
|
-
}
|
|
20614
20774
|
function escapeHtml(value) {
|
|
20615
20775
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
20616
20776
|
}
|
|
20617
|
-
var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES, MAX_LIVE_COUNTER_SYNC_ATTEMPTS, CLEAR_LIVE_COUNTERS_SCRIPT, ASSIGN_SPARSE_COUNTERS_SCRIPT, APPLY_DENSE_COUNTERS_SCRIPT, LiveCounterSyncError;
|
|
20777
|
+
var EXTRACTION_SKIPPED_COUNTER_TAGS, INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES, MAX_LIVE_COUNTER_SYNC_ATTEMPTS, CLEAR_LIVE_COUNTERS_SCRIPT, ASSIGN_SPARSE_COUNTERS_SCRIPT, APPLY_DENSE_COUNTERS_SCRIPT, LiveCounterSyncError;
|
|
20618
20778
|
var init_compiler = __esm({
|
|
20619
20779
|
"../runtime-core/src/sdk/snapshot/compiler.ts"() {
|
|
20620
|
-
init_src();
|
|
20621
|
-
init_path();
|
|
20622
|
-
init_selectors();
|
|
20623
20780
|
init_cleaner();
|
|
20624
20781
|
init_constants();
|
|
20625
20782
|
init_marking();
|
|
20783
|
+
EXTRACTION_SKIPPED_COUNTER_TAGS = /* @__PURE__ */ new Set(["html", "head", "body"]);
|
|
20626
20784
|
INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
|
|
20627
20785
|
"c",
|
|
20628
20786
|
OPENSTEER_BOUNDARY_ATTR,
|
|
@@ -20637,7 +20795,7 @@ var init_compiler = __esm({
|
|
|
20637
20795
|
MAX_LIVE_COUNTER_SYNC_ATTEMPTS = 4;
|
|
20638
20796
|
CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
|
|
20639
20797
|
const walk = (root) => {
|
|
20640
|
-
for (const child of root
|
|
20798
|
+
for (const child of Array.from(root?.children || [])) {
|
|
20641
20799
|
child.removeAttribute("c");
|
|
20642
20800
|
child.removeAttribute(sparseCounterAttr);
|
|
20643
20801
|
walk(child);
|
|
@@ -20653,7 +20811,7 @@ var init_compiler = __esm({
|
|
|
20653
20811
|
ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
|
|
20654
20812
|
let counter = startCounter;
|
|
20655
20813
|
const walk = (root) => {
|
|
20656
|
-
for (const child of root
|
|
20814
|
+
for (const child of Array.from(root?.children || [])) {
|
|
20657
20815
|
child.setAttribute(sparseCounterAttr, String(counter++));
|
|
20658
20816
|
walk(child);
|
|
20659
20817
|
if (child.shadowRoot) {
|
|
@@ -20667,7 +20825,7 @@ var init_compiler = __esm({
|
|
|
20667
20825
|
})`;
|
|
20668
20826
|
APPLY_DENSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, mapping }) => {
|
|
20669
20827
|
const walk = (root) => {
|
|
20670
|
-
for (const child of root
|
|
20828
|
+
for (const child of Array.from(root?.children || [])) {
|
|
20671
20829
|
child.removeAttribute("c");
|
|
20672
20830
|
const sparse = child.getAttribute(sparseCounterAttr);
|
|
20673
20831
|
if (sparse !== null) {
|
|
@@ -22851,15 +23009,10 @@ function normalizeNamespace2(value) {
|
|
|
22851
23009
|
const normalized = String(value ?? "default").trim();
|
|
22852
23010
|
return normalized.length === 0 ? "default" : normalized;
|
|
22853
23011
|
}
|
|
22854
|
-
function toOpensteerActionResult(
|
|
23012
|
+
function toOpensteerActionResult(target) {
|
|
22855
23013
|
return {
|
|
22856
|
-
|
|
22857
|
-
...
|
|
22858
|
-
point: {
|
|
22859
|
-
x: result.point.x,
|
|
22860
|
-
y: result.point.y
|
|
22861
|
-
}
|
|
22862
|
-
}
|
|
23014
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
23015
|
+
...target.persist === void 0 ? {} : { persist: target.persist }
|
|
22863
23016
|
};
|
|
22864
23017
|
}
|
|
22865
23018
|
function toOpensteerResolvedTarget2(target) {
|
|
@@ -22869,12 +23022,16 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
22869
23022
|
documentRef: target.documentRef,
|
|
22870
23023
|
documentEpoch: target.documentEpoch,
|
|
22871
23024
|
nodeRef: target.nodeRef,
|
|
22872
|
-
tagName: target.node.nodeName
|
|
23025
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
22873
23026
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
22874
23027
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
22875
23028
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
22876
23029
|
};
|
|
22877
23030
|
}
|
|
23031
|
+
function toOpensteerTagName2(nodeName) {
|
|
23032
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
23033
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
23034
|
+
}
|
|
22878
23035
|
function normalizeOpensteerError(error) {
|
|
22879
23036
|
return normalizeThrownOpensteerError(error, "Unknown Opensteer runtime failure");
|
|
22880
23037
|
}
|
|
@@ -23192,7 +23349,7 @@ var init_runtime3 = __esm({
|
|
|
23192
23349
|
options
|
|
23193
23350
|
);
|
|
23194
23351
|
}
|
|
23195
|
-
return this.
|
|
23352
|
+
return this.readNavigationSummary();
|
|
23196
23353
|
}
|
|
23197
23354
|
const startedAt = Date.now();
|
|
23198
23355
|
const root = await this.ensureRoot();
|
|
@@ -23213,7 +23370,8 @@ var init_runtime3 = __esm({
|
|
|
23213
23370
|
openedSessionRef = sessionRef;
|
|
23214
23371
|
const createdPage = await timeout.runStep(
|
|
23215
23372
|
() => engine.createPage({
|
|
23216
|
-
sessionRef
|
|
23373
|
+
sessionRef,
|
|
23374
|
+
...input.url === void 0 ? {} : { url: input.url }
|
|
23217
23375
|
})
|
|
23218
23376
|
);
|
|
23219
23377
|
openedPageRef = createdPage.data.pageRef;
|
|
@@ -23223,18 +23381,19 @@ var init_runtime3 = __esm({
|
|
|
23223
23381
|
await timeout.runStep(() => this.ensureSemantics());
|
|
23224
23382
|
let frameRef2 = createdPage.frameRef;
|
|
23225
23383
|
if (input.url !== void 0) {
|
|
23226
|
-
|
|
23227
|
-
{
|
|
23384
|
+
await timeout.runStep(
|
|
23385
|
+
() => settleWithPolicy(this.policy.settle, {
|
|
23228
23386
|
operation: "session.open",
|
|
23387
|
+
trigger: "navigation",
|
|
23388
|
+
engine: this.requireEngine(),
|
|
23229
23389
|
pageRef: createdPage.data.pageRef,
|
|
23230
|
-
|
|
23231
|
-
|
|
23232
|
-
|
|
23390
|
+
signal: timeout.signal,
|
|
23391
|
+
remainingMs: timeout.remainingMs()
|
|
23392
|
+
})
|
|
23233
23393
|
);
|
|
23234
|
-
frameRef2 = navigation.data.mainFrame.frameRef;
|
|
23235
23394
|
}
|
|
23236
23395
|
return {
|
|
23237
|
-
state: await timeout.runStep(() => this.
|
|
23396
|
+
state: await timeout.runStep(() => this.readNavigationSummary()),
|
|
23238
23397
|
frameRef: frameRef2
|
|
23239
23398
|
};
|
|
23240
23399
|
},
|
|
@@ -23327,7 +23486,11 @@ var init_runtime3 = __esm({
|
|
|
23327
23486
|
"page.new cannot use openerPageRef before a session exists"
|
|
23328
23487
|
);
|
|
23329
23488
|
}
|
|
23330
|
-
|
|
23489
|
+
const summary = await this.open(input.url === void 0 ? {} : { url: input.url }, options);
|
|
23490
|
+
return {
|
|
23491
|
+
pageRef: await this.ensurePageRef(),
|
|
23492
|
+
...summary
|
|
23493
|
+
};
|
|
23331
23494
|
}
|
|
23332
23495
|
const startedAt = Date.now();
|
|
23333
23496
|
try {
|
|
@@ -23342,7 +23505,7 @@ var init_runtime3 = __esm({
|
|
|
23342
23505
|
})
|
|
23343
23506
|
);
|
|
23344
23507
|
this.pageRef = created.data.pageRef;
|
|
23345
|
-
return this.
|
|
23508
|
+
return this.readCreatedPageOutput(created.data.pageRef);
|
|
23346
23509
|
},
|
|
23347
23510
|
options
|
|
23348
23511
|
);
|
|
@@ -23384,7 +23547,7 @@ var init_runtime3 = __esm({
|
|
|
23384
23547
|
() => this.requireEngine().activatePage({ pageRef: input.pageRef })
|
|
23385
23548
|
);
|
|
23386
23549
|
this.pageRef = input.pageRef;
|
|
23387
|
-
return this.
|
|
23550
|
+
return this.readNavigationSummary(input.pageRef);
|
|
23388
23551
|
},
|
|
23389
23552
|
options
|
|
23390
23553
|
);
|
|
@@ -23510,7 +23673,7 @@ var init_runtime3 = __esm({
|
|
|
23510
23673
|
timeout.throwIfAborted();
|
|
23511
23674
|
return {
|
|
23512
23675
|
navigation: navigation2,
|
|
23513
|
-
state: await timeout.runStep(() => this.
|
|
23676
|
+
state: await timeout.runStep(() => this.readNavigationSummary(pageRef))
|
|
23514
23677
|
};
|
|
23515
23678
|
},
|
|
23516
23679
|
(diagnostics) => {
|
|
@@ -24744,7 +24907,7 @@ var init_runtime3 = __esm({
|
|
|
24744
24907
|
let mutationCaptureDiagnostics;
|
|
24745
24908
|
let boundaryDiagnostics;
|
|
24746
24909
|
try {
|
|
24747
|
-
const { artifacts, output } = await this.runMutationCapturedOperation(
|
|
24910
|
+
const { artifacts, output, result } = await this.runMutationCapturedOperation(
|
|
24748
24911
|
"computer.execute",
|
|
24749
24912
|
{
|
|
24750
24913
|
...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
|
|
@@ -24762,9 +24925,14 @@ var init_runtime3 = __esm({
|
|
|
24762
24925
|
await this.invalidateLiveSnapshotCounters([pageRef, output2.pageRef], timeout);
|
|
24763
24926
|
this.pageRef = output2.pageRef;
|
|
24764
24927
|
const artifacts2 = await this.persistComputerArtifacts(output2, timeout);
|
|
24928
|
+
const result2 = {
|
|
24929
|
+
...await timeout.runStep(() => this.readNavigationSummary(output2.pageRef)),
|
|
24930
|
+
screenshot: artifacts2.screenshot
|
|
24931
|
+
};
|
|
24765
24932
|
return {
|
|
24766
24933
|
artifacts: { manifests: artifacts2.manifests },
|
|
24767
|
-
output:
|
|
24934
|
+
output: output2,
|
|
24935
|
+
result: result2
|
|
24768
24936
|
};
|
|
24769
24937
|
} catch (error) {
|
|
24770
24938
|
boundaryDiagnostics ??= takeActionBoundaryDiagnostics(timeout.signal);
|
|
@@ -24801,7 +24969,7 @@ var init_runtime3 = __esm({
|
|
|
24801
24969
|
documentEpoch: output.screenshot.documentEpoch
|
|
24802
24970
|
})
|
|
24803
24971
|
});
|
|
24804
|
-
return
|
|
24972
|
+
return result;
|
|
24805
24973
|
} catch (error) {
|
|
24806
24974
|
await this.appendTrace({
|
|
24807
24975
|
operation: "computer.execute",
|
|
@@ -24949,8 +25117,9 @@ var init_runtime3 = __esm({
|
|
|
24949
25117
|
mutationCaptureDiagnostics = diagnostics;
|
|
24950
25118
|
}
|
|
24951
25119
|
);
|
|
24952
|
-
const output = toOpensteerActionResult(executed.result);
|
|
25120
|
+
const output = toOpensteerActionResult(executed.result.resolved);
|
|
24953
25121
|
const actionEvents = "events" in executed.result ? executed.result.events : void 0;
|
|
25122
|
+
const resolvedTarget = toOpensteerResolvedTarget2(executed.result.resolved);
|
|
24954
25123
|
await this.appendTrace({
|
|
24955
25124
|
operation,
|
|
24956
25125
|
startedAt,
|
|
@@ -24958,8 +25127,13 @@ var init_runtime3 = __esm({
|
|
|
24958
25127
|
outcome: "ok",
|
|
24959
25128
|
...actionEvents === void 0 ? {} : { events: actionEvents },
|
|
24960
25129
|
data: {
|
|
24961
|
-
target:
|
|
24962
|
-
...
|
|
25130
|
+
target: resolvedTarget,
|
|
25131
|
+
..."point" in executed.result && executed.result.point !== void 0 ? {
|
|
25132
|
+
point: {
|
|
25133
|
+
x: executed.result.point.x,
|
|
25134
|
+
y: executed.result.point.y
|
|
25135
|
+
}
|
|
25136
|
+
} : {},
|
|
24963
25137
|
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
24964
25138
|
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
24965
25139
|
},
|
|
@@ -26424,20 +26598,20 @@ var init_runtime3 = __esm({
|
|
|
26424
26598
|
throw error;
|
|
26425
26599
|
}
|
|
26426
26600
|
}
|
|
26427
|
-
async
|
|
26428
|
-
const pageRef = await this.ensurePageRef();
|
|
26601
|
+
async readNavigationSummary(targetPageRef) {
|
|
26602
|
+
const pageRef = targetPageRef ?? await this.ensurePageRef();
|
|
26429
26603
|
const pageInfo = await this.requireEngine().getPageInfo({ pageRef });
|
|
26430
|
-
const sessionRef = this.sessionRef;
|
|
26431
|
-
if (!sessionRef) {
|
|
26432
|
-
throw new Error("Opensteer session is not initialized");
|
|
26433
|
-
}
|
|
26434
26604
|
return {
|
|
26435
|
-
sessionRef,
|
|
26436
|
-
pageRef,
|
|
26437
26605
|
url: pageInfo.url,
|
|
26438
26606
|
title: pageInfo.title
|
|
26439
26607
|
};
|
|
26440
26608
|
}
|
|
26609
|
+
async readCreatedPageOutput(pageRef) {
|
|
26610
|
+
return {
|
|
26611
|
+
pageRef,
|
|
26612
|
+
...await this.readNavigationSummary(pageRef)
|
|
26613
|
+
};
|
|
26614
|
+
}
|
|
26441
26615
|
async captureSnapshotArtifacts(pageRef, options, timeout) {
|
|
26442
26616
|
const root = this.requireRoot();
|
|
26443
26617
|
const mainFrame = await timeout.runStep(() => getMainFrame(this.requireEngine(), pageRef));
|
|
@@ -26509,12 +26683,12 @@ var init_runtime3 = __esm({
|
|
|
26509
26683
|
const screenshotPayload = manifestToExternalBinaryLocation(root.rootPath, screenshotManifest);
|
|
26510
26684
|
return {
|
|
26511
26685
|
manifests,
|
|
26512
|
-
|
|
26513
|
-
|
|
26514
|
-
|
|
26515
|
-
|
|
26516
|
-
|
|
26517
|
-
}
|
|
26686
|
+
screenshot: {
|
|
26687
|
+
payload: screenshotPayload,
|
|
26688
|
+
format: output.screenshot.format,
|
|
26689
|
+
size: output.screenshot.size,
|
|
26690
|
+
coordinateSpace: output.screenshot.coordinateSpace,
|
|
26691
|
+
...output.screenshot.clip === void 0 ? {} : { clip: output.screenshot.clip }
|
|
26518
26692
|
}
|
|
26519
26693
|
};
|
|
26520
26694
|
}
|
|
@@ -28599,7 +28773,11 @@ function generateReplayScript(options) {
|
|
|
28599
28773
|
``,
|
|
28600
28774
|
...renderOpensteerBootstrap(replayTarget),
|
|
28601
28775
|
``,
|
|
28602
|
-
`
|
|
28776
|
+
`await opensteer.open(${JSON.stringify(initialPages[0]?.initialUrl ?? "")});`,
|
|
28777
|
+
`const ${initialPageId} = (await opensteer.listPages()).activePageRef;`,
|
|
28778
|
+
`if (!${initialPageId}) {`,
|
|
28779
|
+
` throw new Error("Opensteer did not report an active page after open().");`,
|
|
28780
|
+
`}`,
|
|
28603
28781
|
`let activePageRef: string | undefined = ${initialPageId};`,
|
|
28604
28782
|
``,
|
|
28605
28783
|
`async function ensureActive(pageRef: string): Promise<void> {`,
|
|
@@ -29528,8 +29706,29 @@ function assertSupportedCloudBrowserMode(browser) {
|
|
|
29528
29706
|
}
|
|
29529
29707
|
}
|
|
29530
29708
|
function isMissingCloudSessionError(error) {
|
|
29709
|
+
if (error instanceof OpensteerCloudRequestError) {
|
|
29710
|
+
return error.statusCode === 404 && (error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND");
|
|
29711
|
+
}
|
|
29531
29712
|
return error instanceof Error && /\b404\b/.test(error.message);
|
|
29532
29713
|
}
|
|
29714
|
+
function isRecoverableCloudSessionError(error) {
|
|
29715
|
+
if (!(error instanceof OpensteerCloudRequestError)) {
|
|
29716
|
+
return false;
|
|
29717
|
+
}
|
|
29718
|
+
if (error.statusCode === 404) {
|
|
29719
|
+
return error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND";
|
|
29720
|
+
}
|
|
29721
|
+
return error.statusCode === 409 && error.code === "CLOUD_SESSION_STALE";
|
|
29722
|
+
}
|
|
29723
|
+
function isBootstrapRecoveryOperation(operation) {
|
|
29724
|
+
return operation === "session.open" || operation === "instrumentation.route" || operation === "instrumentation.intercept-script";
|
|
29725
|
+
}
|
|
29726
|
+
function isReusableCloudSessionState(session) {
|
|
29727
|
+
if (session.status === "closing" || session.status === "closed" || session.status === "failed") {
|
|
29728
|
+
return false;
|
|
29729
|
+
}
|
|
29730
|
+
return !(typeof session.expiresAt === "number" && session.expiresAt <= Date.now() + CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS);
|
|
29731
|
+
}
|
|
29533
29732
|
function isLoopbackBaseUrl(baseUrl) {
|
|
29534
29733
|
let url;
|
|
29535
29734
|
try {
|
|
@@ -29539,7 +29738,7 @@ function isLoopbackBaseUrl(baseUrl) {
|
|
|
29539
29738
|
}
|
|
29540
29739
|
return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1" || url.hostname === "[::1]";
|
|
29541
29740
|
}
|
|
29542
|
-
var TEMPORARY_CLOUD_WORKSPACE_PREFIX, CloudSessionProxy;
|
|
29741
|
+
var TEMPORARY_CLOUD_WORKSPACE_PREFIX, CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS, CloudSessionProxy;
|
|
29543
29742
|
var init_session_proxy = __esm({
|
|
29544
29743
|
"src/cloud/session-proxy.ts"() {
|
|
29545
29744
|
init_src3();
|
|
@@ -29549,8 +29748,10 @@ var init_session_proxy = __esm({
|
|
|
29549
29748
|
init_policy2();
|
|
29550
29749
|
init_semantic_rest_client();
|
|
29551
29750
|
init_automation_client();
|
|
29751
|
+
init_client();
|
|
29552
29752
|
init_workspace_sync();
|
|
29553
29753
|
TEMPORARY_CLOUD_WORKSPACE_PREFIX = "opensteer-cloud-workspace-";
|
|
29754
|
+
CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS = 1e4;
|
|
29554
29755
|
CloudSessionProxy = class {
|
|
29555
29756
|
rootPath;
|
|
29556
29757
|
workspace;
|
|
@@ -29564,6 +29765,8 @@ var init_session_proxy = __esm({
|
|
|
29564
29765
|
automation;
|
|
29565
29766
|
workspaceStore;
|
|
29566
29767
|
syncWorkspaceOnClose = false;
|
|
29768
|
+
liveSessionStateEstablished = false;
|
|
29769
|
+
storedInstrumentation = [];
|
|
29567
29770
|
constructor(cloud, options = {}) {
|
|
29568
29771
|
this.cloud = cloud;
|
|
29569
29772
|
this.workspace = options.workspace;
|
|
@@ -29593,15 +29796,12 @@ var init_session_proxy = __esm({
|
|
|
29593
29796
|
if (this.client === void 0 && this.sessionId === void 0 && persisted !== void 0 && await this.isReusableCloudSession(persisted.sessionId)) {
|
|
29594
29797
|
this.bindClient(persisted);
|
|
29595
29798
|
}
|
|
29596
|
-
|
|
29597
|
-
|
|
29598
|
-
|
|
29599
|
-
|
|
29600
|
-
|
|
29601
|
-
|
|
29602
|
-
};
|
|
29603
|
-
} catch {
|
|
29604
|
-
}
|
|
29799
|
+
const sessionInfo = this.automation ? await this.automation.getSessionInfo().catch(() => void 0) : void 0;
|
|
29800
|
+
if (sessionInfo !== void 0) {
|
|
29801
|
+
return {
|
|
29802
|
+
...sessionInfo,
|
|
29803
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace }
|
|
29804
|
+
};
|
|
29605
29805
|
}
|
|
29606
29806
|
return {
|
|
29607
29807
|
provider: {
|
|
@@ -29713,12 +29913,26 @@ var init_session_proxy = __esm({
|
|
|
29713
29913
|
return this.invokeSemanticOperation("session.cookies", input);
|
|
29714
29914
|
}
|
|
29715
29915
|
async route(input) {
|
|
29716
|
-
await this.
|
|
29717
|
-
|
|
29916
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
29917
|
+
"instrumentation.route",
|
|
29918
|
+
(automation) => automation.route(input)
|
|
29919
|
+
);
|
|
29920
|
+
this.storedInstrumentation.push({
|
|
29921
|
+
kind: "route",
|
|
29922
|
+
input
|
|
29923
|
+
});
|
|
29924
|
+
return registration;
|
|
29718
29925
|
}
|
|
29719
29926
|
async interceptScript(input) {
|
|
29720
|
-
await this.
|
|
29721
|
-
|
|
29927
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
29928
|
+
"instrumentation.intercept-script",
|
|
29929
|
+
(automation) => automation.interceptScript(input)
|
|
29930
|
+
);
|
|
29931
|
+
this.storedInstrumentation.push({
|
|
29932
|
+
kind: "intercept-script",
|
|
29933
|
+
input
|
|
29934
|
+
});
|
|
29935
|
+
return registration;
|
|
29722
29936
|
}
|
|
29723
29937
|
async getStorageSnapshot(input = {}) {
|
|
29724
29938
|
return this.invokeSemanticOperation("session.storage", input);
|
|
@@ -29766,6 +29980,8 @@ var init_session_proxy = __esm({
|
|
|
29766
29980
|
this.client = void 0;
|
|
29767
29981
|
this.sessionId = void 0;
|
|
29768
29982
|
this.semanticGrant = void 0;
|
|
29983
|
+
this.liveSessionStateEstablished = false;
|
|
29984
|
+
this.storedInstrumentation.length = 0;
|
|
29769
29985
|
if (this.cleanupRootOnClose) {
|
|
29770
29986
|
await promises.rm(this.rootPath, { recursive: true, force: true }).catch(() => void 0);
|
|
29771
29987
|
}
|
|
@@ -29793,6 +30009,8 @@ var init_session_proxy = __esm({
|
|
|
29793
30009
|
this.automation = void 0;
|
|
29794
30010
|
this.sessionId = void 0;
|
|
29795
30011
|
this.semanticGrant = void 0;
|
|
30012
|
+
this.liveSessionStateEstablished = false;
|
|
30013
|
+
this.storedInstrumentation.length = 0;
|
|
29796
30014
|
if (syncError !== void 0) {
|
|
29797
30015
|
throw syncError;
|
|
29798
30016
|
}
|
|
@@ -29840,6 +30058,7 @@ var init_session_proxy = __esm({
|
|
|
29840
30058
|
};
|
|
29841
30059
|
await this.writePersistedSession(record);
|
|
29842
30060
|
this.bindClient(record, session.initialGrants?.semantic);
|
|
30061
|
+
await this.restoreStoredInstrumentation();
|
|
29843
30062
|
}
|
|
29844
30063
|
async syncWorkspaceToCloud() {
|
|
29845
30064
|
if (this.workspace === void 0) {
|
|
@@ -29851,6 +30070,7 @@ var init_session_proxy = __esm({
|
|
|
29851
30070
|
bindClient(record, initialSemanticGrant) {
|
|
29852
30071
|
this.sessionId = record.sessionId;
|
|
29853
30072
|
this.semanticGrant = initialSemanticGrant?.kind === "semantic" ? initialSemanticGrant : void 0;
|
|
30073
|
+
this.liveSessionStateEstablished = false;
|
|
29854
30074
|
this.client = new OpensteerSemanticRestClient({
|
|
29855
30075
|
getBaseUrl: async () => (await this.ensureSemanticGrant()).url,
|
|
29856
30076
|
getAuthorizationHeader: async () => `Bearer ${(await this.ensureSemanticGrant()).token}`,
|
|
@@ -29858,6 +30078,19 @@ var init_session_proxy = __esm({
|
|
|
29858
30078
|
});
|
|
29859
30079
|
this.automation = new OpensteerCloudAutomationClient(this.cloud, record.sessionId);
|
|
29860
30080
|
}
|
|
30081
|
+
async restoreStoredInstrumentation() {
|
|
30082
|
+
if (this.storedInstrumentation.length === 0) {
|
|
30083
|
+
return;
|
|
30084
|
+
}
|
|
30085
|
+
const automation = this.requireAutomation();
|
|
30086
|
+
for (const registration of this.storedInstrumentation) {
|
|
30087
|
+
if (registration.kind === "route") {
|
|
30088
|
+
await automation.route(registration.input);
|
|
30089
|
+
} else {
|
|
30090
|
+
await automation.interceptScript(registration.input);
|
|
30091
|
+
}
|
|
30092
|
+
}
|
|
30093
|
+
}
|
|
29861
30094
|
async ensureWorkspaceStore() {
|
|
29862
30095
|
if (this.workspaceStore !== void 0) {
|
|
29863
30096
|
return this.workspaceStore;
|
|
@@ -29880,13 +30113,22 @@ var init_session_proxy = __esm({
|
|
|
29880
30113
|
async clearPersistedSession() {
|
|
29881
30114
|
await clearPersistedSessionRecord(this.rootPath, "cloud").catch(() => void 0);
|
|
29882
30115
|
}
|
|
30116
|
+
async invalidateSession() {
|
|
30117
|
+
await this.automation?.close().catch(() => void 0);
|
|
30118
|
+
this.automation = void 0;
|
|
30119
|
+
this.client = void 0;
|
|
30120
|
+
this.sessionId = void 0;
|
|
30121
|
+
this.semanticGrant = void 0;
|
|
30122
|
+
this.liveSessionStateEstablished = false;
|
|
30123
|
+
await this.clearPersistedSession();
|
|
30124
|
+
}
|
|
29883
30125
|
async isReusableCloudSession(sessionId, timeout) {
|
|
29884
30126
|
try {
|
|
29885
30127
|
const session = await this.cloud.getSession(sessionId, {
|
|
29886
30128
|
signal: timeout?.signal,
|
|
29887
30129
|
timeoutMs: timeout?.remainingMs()
|
|
29888
30130
|
});
|
|
29889
|
-
return session
|
|
30131
|
+
return isReusableCloudSessionState(session);
|
|
29890
30132
|
} catch (error) {
|
|
29891
30133
|
if (isMissingCloudSessionError(error)) {
|
|
29892
30134
|
return false;
|
|
@@ -29935,26 +30177,79 @@ var init_session_proxy = __esm({
|
|
|
29935
30177
|
try {
|
|
29936
30178
|
await this.ensureSemanticGrant(true);
|
|
29937
30179
|
return true;
|
|
29938
|
-
} catch {
|
|
30180
|
+
} catch (refreshError) {
|
|
30181
|
+
if (await this.resetStaleSession(refreshError)) {
|
|
30182
|
+
throw refreshError;
|
|
30183
|
+
}
|
|
29939
30184
|
return false;
|
|
29940
30185
|
}
|
|
29941
30186
|
}
|
|
29942
30187
|
async invokeSemanticOperation(operation, input, sessionInit = {}) {
|
|
29943
|
-
return this.
|
|
30188
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
29944
30189
|
await this.ensureSession(sessionInit, timeout);
|
|
29945
30190
|
await this.ensureSemanticGrant(false, timeout);
|
|
29946
|
-
|
|
30191
|
+
const output = await this.requireClient().invoke(operation, input, {
|
|
29947
30192
|
signal: timeout.signal,
|
|
29948
30193
|
timeoutMs: timeout.remainingMs()
|
|
29949
30194
|
});
|
|
30195
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
30196
|
+
return output;
|
|
29950
30197
|
});
|
|
29951
30198
|
}
|
|
29952
30199
|
async invokeAutomationOperation(operation, invoke, sessionInit = {}) {
|
|
29953
|
-
return this.
|
|
30200
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
29954
30201
|
await this.ensureSession(sessionInit, timeout);
|
|
29955
|
-
|
|
30202
|
+
const output = await invoke(this.requireAutomation());
|
|
30203
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
30204
|
+
return output;
|
|
29956
30205
|
});
|
|
29957
30206
|
}
|
|
30207
|
+
async invokeBootstrapInstrumentationOperation(operation, invoke) {
|
|
30208
|
+
let recovered = false;
|
|
30209
|
+
while (true) {
|
|
30210
|
+
try {
|
|
30211
|
+
await this.ensureSession();
|
|
30212
|
+
return await invoke(this.requireAutomation());
|
|
30213
|
+
} catch (error) {
|
|
30214
|
+
const stale = await this.resetStaleSession(error);
|
|
30215
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
30216
|
+
throw error;
|
|
30217
|
+
}
|
|
30218
|
+
recovered = true;
|
|
30219
|
+
}
|
|
30220
|
+
}
|
|
30221
|
+
}
|
|
30222
|
+
async runOperationWithSessionRecovery(operation, invoke) {
|
|
30223
|
+
return this.runOperationWithPolicy(operation, async (timeout) => {
|
|
30224
|
+
let recovered = false;
|
|
30225
|
+
while (true) {
|
|
30226
|
+
try {
|
|
30227
|
+
return await invoke(timeout);
|
|
30228
|
+
} catch (error) {
|
|
30229
|
+
const stale = await this.resetStaleSession(error);
|
|
30230
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
30231
|
+
throw error;
|
|
30232
|
+
}
|
|
30233
|
+
recovered = true;
|
|
30234
|
+
}
|
|
30235
|
+
}
|
|
30236
|
+
});
|
|
30237
|
+
}
|
|
30238
|
+
async resetStaleSession(error) {
|
|
30239
|
+
if (!isRecoverableCloudSessionError(error)) {
|
|
30240
|
+
return false;
|
|
30241
|
+
}
|
|
30242
|
+
await this.invalidateSession();
|
|
30243
|
+
return true;
|
|
30244
|
+
}
|
|
30245
|
+
canRecoverWithFreshSession(operation) {
|
|
30246
|
+
return !this.liveSessionStateEstablished && isBootstrapRecoveryOperation(operation);
|
|
30247
|
+
}
|
|
30248
|
+
noteSuccessfulLiveOperation(operation) {
|
|
30249
|
+
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") {
|
|
30250
|
+
this.liveSessionStateEstablished = true;
|
|
30251
|
+
}
|
|
30252
|
+
}
|
|
29958
30253
|
async runOperationWithPolicy(operation, invoke) {
|
|
29959
30254
|
return runWithPolicyTimeout(this.policy.timeout, { operation }, invoke);
|
|
29960
30255
|
}
|
|
@@ -30269,14 +30564,85 @@ var init_session_control = __esm({
|
|
|
30269
30564
|
}
|
|
30270
30565
|
});
|
|
30271
30566
|
|
|
30567
|
+
// src/internal/errors.ts
|
|
30568
|
+
function normalizeThrownOpensteerError2(error, fallbackMessage) {
|
|
30569
|
+
if (isOpensteerProtocolError(error)) {
|
|
30570
|
+
return toOpensteerError(error);
|
|
30571
|
+
}
|
|
30572
|
+
if (isBrowserCoreError(error)) {
|
|
30573
|
+
return createOpensteerError(error.code, error.message, {
|
|
30574
|
+
retriable: error.retriable,
|
|
30575
|
+
...error.details === void 0 ? {} : { details: error.details }
|
|
30576
|
+
});
|
|
30577
|
+
}
|
|
30578
|
+
if (error instanceof OpensteerAttachAmbiguousError) {
|
|
30579
|
+
return createOpensteerError("conflict", error.message, {
|
|
30580
|
+
details: {
|
|
30581
|
+
candidates: error.candidates,
|
|
30582
|
+
code: error.code,
|
|
30583
|
+
name: error.name
|
|
30584
|
+
}
|
|
30585
|
+
});
|
|
30586
|
+
}
|
|
30587
|
+
if (error instanceof Error && "opensteerError" in error && typeof error.opensteerError === "object" && error.opensteerError !== null) {
|
|
30588
|
+
const oe = error.opensteerError;
|
|
30589
|
+
return createOpensteerError(oe.code, oe.message, {
|
|
30590
|
+
retriable: oe.retriable,
|
|
30591
|
+
...oe.capability === void 0 ? {} : { capability: oe.capability },
|
|
30592
|
+
...oe.details === void 0 ? {} : { details: oe.details }
|
|
30593
|
+
});
|
|
30594
|
+
}
|
|
30595
|
+
if (error instanceof Error) {
|
|
30596
|
+
return createOpensteerError("operation-failed", error.message, {
|
|
30597
|
+
details: {
|
|
30598
|
+
name: error.name
|
|
30599
|
+
}
|
|
30600
|
+
});
|
|
30601
|
+
}
|
|
30602
|
+
return createOpensteerError("internal", fallbackMessage, {
|
|
30603
|
+
details: {
|
|
30604
|
+
value: error
|
|
30605
|
+
}
|
|
30606
|
+
});
|
|
30607
|
+
}
|
|
30608
|
+
var init_errors5 = __esm({
|
|
30609
|
+
"src/internal/errors.ts"() {
|
|
30610
|
+
init_src();
|
|
30611
|
+
init_src2();
|
|
30612
|
+
init_cdp_discovery();
|
|
30613
|
+
}
|
|
30614
|
+
});
|
|
30615
|
+
|
|
30272
30616
|
// src/sdk/opensteer.ts
|
|
30273
30617
|
var opensteer_exports = {};
|
|
30274
30618
|
__export(opensteer_exports, {
|
|
30275
30619
|
Opensteer: () => Opensteer
|
|
30276
30620
|
});
|
|
30621
|
+
function createSdkProtocolError(error, fallbackMessage) {
|
|
30622
|
+
const normalized = normalizeThrownOpensteerError2(error, fallbackMessage);
|
|
30623
|
+
return new OpensteerProtocolError(normalized.code, normalized.message, {
|
|
30624
|
+
cause: error,
|
|
30625
|
+
retriable: normalized.retriable,
|
|
30626
|
+
...normalized.capability === void 0 ? {} : { capability: normalized.capability },
|
|
30627
|
+
...normalized.details === void 0 ? {} : { details: normalized.details }
|
|
30628
|
+
});
|
|
30629
|
+
}
|
|
30630
|
+
async function wrapSdkError(operation, fn) {
|
|
30631
|
+
try {
|
|
30632
|
+
return await fn();
|
|
30633
|
+
} catch (error) {
|
|
30634
|
+
if (isOpensteerProtocolError(error)) {
|
|
30635
|
+
throw error;
|
|
30636
|
+
}
|
|
30637
|
+
throw createSdkProtocolError(error, `${operation} failed`);
|
|
30638
|
+
}
|
|
30639
|
+
}
|
|
30277
30640
|
function createUnsupportedBrowserController() {
|
|
30278
30641
|
const fail = async () => {
|
|
30279
|
-
throw new
|
|
30642
|
+
throw new OpensteerProtocolError(
|
|
30643
|
+
"unsupported-operation",
|
|
30644
|
+
"browser.* helpers are only available in local mode."
|
|
30645
|
+
);
|
|
30280
30646
|
};
|
|
30281
30647
|
return {
|
|
30282
30648
|
status: fail,
|
|
@@ -30289,7 +30655,10 @@ function normalizeTargetOptions(input) {
|
|
|
30289
30655
|
const hasElement = input.element !== void 0;
|
|
30290
30656
|
const hasSelector = input.selector !== void 0;
|
|
30291
30657
|
if (hasElement && hasSelector) {
|
|
30292
|
-
throw new
|
|
30658
|
+
throw new OpensteerProtocolError(
|
|
30659
|
+
"invalid-argument",
|
|
30660
|
+
"Specify exactly one of element, selector, or persist."
|
|
30661
|
+
);
|
|
30293
30662
|
}
|
|
30294
30663
|
if (hasElement) {
|
|
30295
30664
|
return {
|
|
@@ -30312,7 +30681,10 @@ function normalizeTargetOptions(input) {
|
|
|
30312
30681
|
};
|
|
30313
30682
|
}
|
|
30314
30683
|
if (input.persist === void 0) {
|
|
30315
|
-
throw new
|
|
30684
|
+
throw new OpensteerProtocolError(
|
|
30685
|
+
"invalid-argument",
|
|
30686
|
+
"Specify exactly one of element, selector, or persist."
|
|
30687
|
+
);
|
|
30316
30688
|
}
|
|
30317
30689
|
return {
|
|
30318
30690
|
target: {
|
|
@@ -30374,8 +30746,10 @@ function delay5(ms) {
|
|
|
30374
30746
|
var SessionCookieJar, Opensteer;
|
|
30375
30747
|
var init_opensteer = __esm({
|
|
30376
30748
|
"src/sdk/opensteer.ts"() {
|
|
30749
|
+
init_src2();
|
|
30377
30750
|
init_browser_manager();
|
|
30378
30751
|
init_env();
|
|
30752
|
+
init_errors5();
|
|
30379
30753
|
init_runtime_resolution();
|
|
30380
30754
|
SessionCookieJar = class {
|
|
30381
30755
|
domain;
|
|
@@ -30406,202 +30780,257 @@ var init_opensteer = __esm({
|
|
|
30406
30780
|
dom;
|
|
30407
30781
|
network;
|
|
30408
30782
|
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({
|
|
30783
|
+
try {
|
|
30784
|
+
const environment = resolveOpensteerEnvironment(options.rootDir);
|
|
30785
|
+
const { provider, engineName, ...runtimeOptions } = options;
|
|
30786
|
+
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
30436
30787
|
...provider === void 0 ? {} : { provider },
|
|
30437
|
-
|
|
30438
|
-
environment,
|
|
30439
|
-
runtimeOptions: {
|
|
30440
|
-
...runtimeOptions,
|
|
30441
|
-
rootPath: this.browserManager.rootPath,
|
|
30442
|
-
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
30443
|
-
}
|
|
30788
|
+
environment
|
|
30444
30789
|
});
|
|
30445
|
-
|
|
30446
|
-
|
|
30447
|
-
|
|
30448
|
-
|
|
30449
|
-
|
|
30790
|
+
if (runtimeConfig.provider.mode === "cloud") {
|
|
30791
|
+
this.browserManager = void 0;
|
|
30792
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
30793
|
+
...provider === void 0 ? {} : { provider },
|
|
30794
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
30795
|
+
environment,
|
|
30796
|
+
runtimeOptions
|
|
30797
|
+
});
|
|
30798
|
+
this.browser = createUnsupportedBrowserController();
|
|
30799
|
+
} else {
|
|
30800
|
+
this.browserManager = new OpensteerBrowserManager({
|
|
30801
|
+
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
30802
|
+
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
30803
|
+
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
30804
|
+
...engineName === void 0 ? {} : { engineName },
|
|
30805
|
+
environment,
|
|
30806
|
+
...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
|
|
30807
|
+
...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
|
|
30808
|
+
...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
|
|
30809
|
+
});
|
|
30810
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
30811
|
+
...provider === void 0 ? {} : { provider },
|
|
30812
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
30813
|
+
environment,
|
|
30814
|
+
runtimeOptions: {
|
|
30815
|
+
...runtimeOptions,
|
|
30816
|
+
rootPath: this.browserManager.rootPath,
|
|
30817
|
+
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
30818
|
+
}
|
|
30819
|
+
});
|
|
30820
|
+
this.browser = {
|
|
30821
|
+
status: () => wrapSdkError("browser.status", () => this.browserManager.status()),
|
|
30822
|
+
clone: (input) => wrapSdkError("browser.clone", () => this.browserManager.clonePersistentBrowser(input)),
|
|
30823
|
+
reset: () => wrapSdkError("browser.reset", () => this.browserManager.reset()),
|
|
30824
|
+
delete: () => wrapSdkError("browser.delete", () => this.browserManager.delete())
|
|
30825
|
+
};
|
|
30826
|
+
}
|
|
30827
|
+
this.dom = {
|
|
30828
|
+
click: (input) => this.click(input),
|
|
30829
|
+
hover: (input) => this.hover(input),
|
|
30830
|
+
input: (input) => this.input(input),
|
|
30831
|
+
scroll: (input) => this.scroll(input)
|
|
30832
|
+
};
|
|
30833
|
+
this.network = {
|
|
30834
|
+
query: (input = {}) => wrapSdkError("network.query", () => this.runtime.queryNetwork(input)),
|
|
30835
|
+
detail: (recordId, options2) => wrapSdkError(
|
|
30836
|
+
"network.detail",
|
|
30837
|
+
() => this.runtime.getNetworkDetail({ recordId, ...options2 })
|
|
30838
|
+
)
|
|
30450
30839
|
};
|
|
30840
|
+
} catch (error) {
|
|
30841
|
+
if (isOpensteerProtocolError(error)) {
|
|
30842
|
+
throw error;
|
|
30843
|
+
}
|
|
30844
|
+
throw createSdkProtocolError(error, "Failed to initialize Opensteer");
|
|
30451
30845
|
}
|
|
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
30846
|
}
|
|
30463
30847
|
async open(input = {}) {
|
|
30464
|
-
return
|
|
30848
|
+
return wrapSdkError(
|
|
30849
|
+
"session.open",
|
|
30850
|
+
() => this.runtime.open(typeof input === "string" ? { url: input } : input)
|
|
30851
|
+
);
|
|
30465
30852
|
}
|
|
30466
30853
|
async info() {
|
|
30467
|
-
return this.runtime.info();
|
|
30854
|
+
return wrapSdkError("session.info", () => this.runtime.info());
|
|
30468
30855
|
}
|
|
30469
30856
|
async listPages(input = {}) {
|
|
30470
|
-
return this.runtime.listPages(input);
|
|
30857
|
+
return wrapSdkError("page.list", () => this.runtime.listPages(input));
|
|
30471
30858
|
}
|
|
30472
30859
|
async newPage(input = {}) {
|
|
30473
|
-
return this.runtime.newPage(input);
|
|
30860
|
+
return wrapSdkError("page.new", () => this.runtime.newPage(input));
|
|
30474
30861
|
}
|
|
30475
30862
|
async activatePage(input) {
|
|
30476
|
-
return this.runtime.activatePage(input);
|
|
30863
|
+
return wrapSdkError("page.activate", () => this.runtime.activatePage(input));
|
|
30477
30864
|
}
|
|
30478
30865
|
async closePage(input = {}) {
|
|
30479
|
-
return this.runtime.closePage(input);
|
|
30866
|
+
return wrapSdkError("page.close", () => this.runtime.closePage(input));
|
|
30480
30867
|
}
|
|
30481
30868
|
async goto(url, options = {}) {
|
|
30482
|
-
return
|
|
30483
|
-
|
|
30484
|
-
|
|
30485
|
-
|
|
30869
|
+
return wrapSdkError(
|
|
30870
|
+
"page.goto",
|
|
30871
|
+
() => this.runtime.goto({
|
|
30872
|
+
url,
|
|
30873
|
+
...options
|
|
30874
|
+
})
|
|
30875
|
+
);
|
|
30486
30876
|
}
|
|
30487
30877
|
async evaluate(input) {
|
|
30488
|
-
|
|
30489
|
-
|
|
30490
|
-
|
|
30491
|
-
|
|
30878
|
+
return wrapSdkError("page.evaluate", async () => {
|
|
30879
|
+
const normalized = typeof input === "string" ? {
|
|
30880
|
+
script: input
|
|
30881
|
+
} : input;
|
|
30882
|
+
return (await this.runtime.evaluate(normalized)).value;
|
|
30883
|
+
});
|
|
30492
30884
|
}
|
|
30493
30885
|
async addInitScript(input) {
|
|
30494
|
-
return
|
|
30495
|
-
|
|
30496
|
-
|
|
30497
|
-
|
|
30886
|
+
return wrapSdkError(
|
|
30887
|
+
"page.addInitScript",
|
|
30888
|
+
() => this.runtime.addInitScript(
|
|
30889
|
+
typeof input === "string" ? {
|
|
30890
|
+
script: input
|
|
30891
|
+
} : input
|
|
30892
|
+
)
|
|
30498
30893
|
);
|
|
30499
30894
|
}
|
|
30500
30895
|
async click(input) {
|
|
30501
|
-
|
|
30502
|
-
|
|
30503
|
-
|
|
30504
|
-
|
|
30505
|
-
|
|
30506
|
-
|
|
30896
|
+
return wrapSdkError("dom.click", () => {
|
|
30897
|
+
const { button, clickCount, modifiers, ...target } = input;
|
|
30898
|
+
return this.runtime.click({
|
|
30899
|
+
...normalizeTargetOptions(target),
|
|
30900
|
+
...button === void 0 ? {} : { button },
|
|
30901
|
+
...clickCount === void 0 ? {} : { clickCount },
|
|
30902
|
+
...modifiers === void 0 ? {} : { modifiers }
|
|
30903
|
+
});
|
|
30507
30904
|
});
|
|
30508
30905
|
}
|
|
30509
30906
|
async hover(input) {
|
|
30510
|
-
return this.runtime.hover(normalizeTargetOptions(input));
|
|
30907
|
+
return wrapSdkError("dom.hover", () => this.runtime.hover(normalizeTargetOptions(input)));
|
|
30511
30908
|
}
|
|
30512
30909
|
async input(input) {
|
|
30513
|
-
return
|
|
30514
|
-
|
|
30515
|
-
|
|
30516
|
-
|
|
30517
|
-
|
|
30910
|
+
return wrapSdkError(
|
|
30911
|
+
"dom.input",
|
|
30912
|
+
() => this.runtime.input({
|
|
30913
|
+
...normalizeTargetOptions(input),
|
|
30914
|
+
text: input.text,
|
|
30915
|
+
...input.pressEnter === void 0 ? {} : { pressEnter: input.pressEnter }
|
|
30916
|
+
})
|
|
30917
|
+
);
|
|
30518
30918
|
}
|
|
30519
30919
|
async scroll(input) {
|
|
30520
|
-
return
|
|
30521
|
-
|
|
30522
|
-
|
|
30523
|
-
|
|
30524
|
-
|
|
30920
|
+
return wrapSdkError(
|
|
30921
|
+
"dom.scroll",
|
|
30922
|
+
() => this.runtime.scroll({
|
|
30923
|
+
...normalizeTargetOptions(input),
|
|
30924
|
+
direction: input.direction,
|
|
30925
|
+
amount: input.amount
|
|
30926
|
+
})
|
|
30927
|
+
);
|
|
30525
30928
|
}
|
|
30526
30929
|
async extract(input) {
|
|
30527
|
-
return (await this.runtime.extract(input)).data;
|
|
30930
|
+
return wrapSdkError("extract", async () => (await this.runtime.extract(input)).data);
|
|
30528
30931
|
}
|
|
30529
30932
|
async waitForPage(input = {}) {
|
|
30530
|
-
|
|
30531
|
-
|
|
30532
|
-
|
|
30533
|
-
|
|
30534
|
-
|
|
30535
|
-
|
|
30536
|
-
|
|
30537
|
-
|
|
30538
|
-
|
|
30539
|
-
|
|
30933
|
+
return wrapSdkError("page.waitForPage", async () => {
|
|
30934
|
+
const baseline = new Set((await this.runtime.listPages()).pages.map((page) => page.pageRef));
|
|
30935
|
+
const timeoutAt = Date.now() + (input.timeoutMs ?? 3e4);
|
|
30936
|
+
const pollIntervalMs = input.pollIntervalMs ?? 100;
|
|
30937
|
+
while (true) {
|
|
30938
|
+
const match = (await this.runtime.listPages()).pages.find((page) => {
|
|
30939
|
+
if (baseline.has(page.pageRef)) {
|
|
30940
|
+
return false;
|
|
30941
|
+
}
|
|
30942
|
+
if (input.openerPageRef !== void 0 && page.openerPageRef !== input.openerPageRef) {
|
|
30943
|
+
return false;
|
|
30944
|
+
}
|
|
30945
|
+
if (input.urlIncludes !== void 0 && !page.url.includes(input.urlIncludes)) {
|
|
30946
|
+
return false;
|
|
30947
|
+
}
|
|
30948
|
+
return true;
|
|
30949
|
+
});
|
|
30950
|
+
if (match !== void 0) {
|
|
30951
|
+
return match;
|
|
30540
30952
|
}
|
|
30541
|
-
if (
|
|
30542
|
-
|
|
30953
|
+
if (Date.now() >= timeoutAt) {
|
|
30954
|
+
throw new OpensteerProtocolError("timeout", "waitForPage timed out");
|
|
30543
30955
|
}
|
|
30544
|
-
|
|
30545
|
-
});
|
|
30546
|
-
if (match !== void 0) {
|
|
30547
|
-
return match;
|
|
30548
|
-
}
|
|
30549
|
-
if (Date.now() >= timeoutAt) {
|
|
30550
|
-
throw new Error("waitForPage timed out");
|
|
30956
|
+
await delay5(pollIntervalMs);
|
|
30551
30957
|
}
|
|
30552
|
-
|
|
30553
|
-
}
|
|
30958
|
+
});
|
|
30554
30959
|
}
|
|
30555
30960
|
async cookies(domain) {
|
|
30556
|
-
return
|
|
30557
|
-
|
|
30961
|
+
return wrapSdkError(
|
|
30962
|
+
"session.cookies",
|
|
30963
|
+
async () => new SessionCookieJar(await this.runtime.getCookies(domain === void 0 ? {} : { domain }))
|
|
30558
30964
|
);
|
|
30559
30965
|
}
|
|
30560
30966
|
async storage(domain, type = "local") {
|
|
30561
|
-
|
|
30562
|
-
|
|
30563
|
-
|
|
30564
|
-
|
|
30565
|
-
|
|
30566
|
-
|
|
30567
|
-
|
|
30967
|
+
return wrapSdkError("session.storage", async () => {
|
|
30968
|
+
const snapshot = await this.runtime.getStorageSnapshot(
|
|
30969
|
+
domain === void 0 ? {} : { domain }
|
|
30970
|
+
);
|
|
30971
|
+
const domainSnapshot = pickStorageDomainSnapshot(snapshot, domain);
|
|
30972
|
+
if (domainSnapshot === void 0) {
|
|
30973
|
+
return {};
|
|
30974
|
+
}
|
|
30975
|
+
const entries = type === "local" ? domainSnapshot.localStorage : domainSnapshot.sessionStorage;
|
|
30976
|
+
return Object.fromEntries(entries.map((entry) => [entry.key, entry.value]));
|
|
30977
|
+
});
|
|
30568
30978
|
}
|
|
30569
30979
|
async state(domain) {
|
|
30570
|
-
return
|
|
30980
|
+
return wrapSdkError(
|
|
30981
|
+
"session.state",
|
|
30982
|
+
() => this.runtime.getBrowserState(domain === void 0 ? {} : { domain })
|
|
30983
|
+
);
|
|
30571
30984
|
}
|
|
30572
30985
|
async fetch(url, options = {}) {
|
|
30573
|
-
|
|
30574
|
-
|
|
30575
|
-
|
|
30576
|
-
|
|
30577
|
-
|
|
30578
|
-
|
|
30986
|
+
return wrapSdkError("session.fetch", async () => {
|
|
30987
|
+
const input = buildFetchInput(url, options);
|
|
30988
|
+
const result = await this.runtime.fetch(input);
|
|
30989
|
+
if (result.response === void 0) {
|
|
30990
|
+
throw new OpensteerProtocolError(
|
|
30991
|
+
"operation-failed",
|
|
30992
|
+
result.note ?? `session.fetch did not produce a response for ${url}`
|
|
30993
|
+
);
|
|
30994
|
+
}
|
|
30995
|
+
return toResponse(result.response);
|
|
30996
|
+
});
|
|
30579
30997
|
}
|
|
30580
30998
|
async computerExecute(input) {
|
|
30581
|
-
return this.runtime.computerExecute(input);
|
|
30999
|
+
return wrapSdkError("session.computerExecute", () => this.runtime.computerExecute(input));
|
|
30582
31000
|
}
|
|
30583
31001
|
async route(input) {
|
|
30584
|
-
return
|
|
31002
|
+
return wrapSdkError(
|
|
31003
|
+
"session.route",
|
|
31004
|
+
() => this.requireOwnedInstrumentationRuntime("route").route(input)
|
|
31005
|
+
);
|
|
30585
31006
|
}
|
|
30586
31007
|
async interceptScript(input) {
|
|
30587
|
-
return
|
|
31008
|
+
return wrapSdkError(
|
|
31009
|
+
"session.interceptScript",
|
|
31010
|
+
() => this.requireOwnedInstrumentationRuntime("interceptScript").interceptScript(input)
|
|
31011
|
+
);
|
|
30588
31012
|
}
|
|
30589
31013
|
async close() {
|
|
30590
|
-
|
|
30591
|
-
|
|
30592
|
-
|
|
30593
|
-
|
|
30594
|
-
|
|
30595
|
-
|
|
31014
|
+
return wrapSdkError("session.close", async () => {
|
|
31015
|
+
if (this.browserManager === void 0 || this.browserManager.mode === "temporary") {
|
|
31016
|
+
return this.runtime.close();
|
|
31017
|
+
}
|
|
31018
|
+
const output = await this.runtime.close();
|
|
31019
|
+
await this.browserManager.close();
|
|
31020
|
+
return output;
|
|
31021
|
+
});
|
|
30596
31022
|
}
|
|
30597
31023
|
async disconnect() {
|
|
30598
|
-
|
|
31024
|
+
return wrapSdkError("session.disconnect", () => this.runtime.disconnect());
|
|
30599
31025
|
}
|
|
30600
31026
|
requireOwnedInstrumentationRuntime(method) {
|
|
30601
31027
|
if (typeof this.runtime.route === "function" && typeof this.runtime.interceptScript === "function") {
|
|
30602
31028
|
return this.runtime;
|
|
30603
31029
|
}
|
|
30604
|
-
throw new
|
|
31030
|
+
throw new OpensteerProtocolError(
|
|
31031
|
+
"unsupported-operation",
|
|
31032
|
+
`${method}() is not available for this session runtime.`
|
|
31033
|
+
);
|
|
30605
31034
|
}
|
|
30606
31035
|
};
|
|
30607
31036
|
}
|
|
@@ -30609,7 +31038,7 @@ var init_opensteer = __esm({
|
|
|
30609
31038
|
|
|
30610
31039
|
// package.json
|
|
30611
31040
|
var package_default = {
|
|
30612
|
-
version: "0.9.
|
|
31041
|
+
version: "0.9.7"};
|
|
30613
31042
|
|
|
30614
31043
|
// src/cli/bin.ts
|
|
30615
31044
|
init_browser_manager();
|
|
@@ -30624,6 +31053,110 @@ async function loadCliEnvironment(cwd) {
|
|
|
30624
31053
|
loadEnvironment(cwd);
|
|
30625
31054
|
}
|
|
30626
31055
|
|
|
31056
|
+
// src/cli/errors.ts
|
|
31057
|
+
init_src();
|
|
31058
|
+
init_src2();
|
|
31059
|
+
var CliError = class extends Error {
|
|
31060
|
+
type;
|
|
31061
|
+
usage;
|
|
31062
|
+
constructor(type, message, usage) {
|
|
31063
|
+
super(message);
|
|
31064
|
+
this.name = "CliError";
|
|
31065
|
+
this.type = type;
|
|
31066
|
+
this.usage = usage;
|
|
31067
|
+
}
|
|
31068
|
+
format() {
|
|
31069
|
+
return this.usage === void 0 ? this.message : `${this.message}
|
|
31070
|
+
Usage: ${this.usage}`;
|
|
31071
|
+
}
|
|
31072
|
+
};
|
|
31073
|
+
function isCliError(value) {
|
|
31074
|
+
return value instanceof CliError;
|
|
31075
|
+
}
|
|
31076
|
+
function formatCliErrorOutput(error) {
|
|
31077
|
+
if (isCliError(error)) {
|
|
31078
|
+
return {
|
|
31079
|
+
success: false,
|
|
31080
|
+
error: error.format(),
|
|
31081
|
+
type: error.type
|
|
31082
|
+
};
|
|
31083
|
+
}
|
|
31084
|
+
if (isOpensteerProtocolError(error)) {
|
|
31085
|
+
return {
|
|
31086
|
+
success: false,
|
|
31087
|
+
error: error.message,
|
|
31088
|
+
code: error.code,
|
|
31089
|
+
retriable: error.retriable
|
|
31090
|
+
};
|
|
31091
|
+
}
|
|
31092
|
+
if (isBrowserCoreError(error)) {
|
|
31093
|
+
return {
|
|
31094
|
+
success: false,
|
|
31095
|
+
error: error.message,
|
|
31096
|
+
code: error.code,
|
|
31097
|
+
retriable: error.retriable
|
|
31098
|
+
};
|
|
31099
|
+
}
|
|
31100
|
+
if (error instanceof Error && "opensteerError" in error) {
|
|
31101
|
+
const oe = error.opensteerError;
|
|
31102
|
+
return {
|
|
31103
|
+
success: false,
|
|
31104
|
+
error: oe.message,
|
|
31105
|
+
code: oe.code,
|
|
31106
|
+
retriable: oe.retriable
|
|
31107
|
+
};
|
|
31108
|
+
}
|
|
31109
|
+
if (error instanceof SyntaxError) {
|
|
31110
|
+
return {
|
|
31111
|
+
success: false,
|
|
31112
|
+
error: error.message,
|
|
31113
|
+
type: "invalid_value"
|
|
31114
|
+
};
|
|
31115
|
+
}
|
|
31116
|
+
return {
|
|
31117
|
+
success: false,
|
|
31118
|
+
error: error instanceof Error ? error.message : String(error)
|
|
31119
|
+
};
|
|
31120
|
+
}
|
|
31121
|
+
function emitWarning(warning) {
|
|
31122
|
+
process.stderr.write(`${JSON.stringify({ warning })}
|
|
31123
|
+
`);
|
|
31124
|
+
}
|
|
31125
|
+
var CLI_USAGE_HINTS = {
|
|
31126
|
+
"session.open": "opensteer open <url> [--workspace <id>]",
|
|
31127
|
+
"page.goto": "opensteer goto <url>",
|
|
31128
|
+
"page.evaluate": "opensteer evaluate <script>",
|
|
31129
|
+
"page.add-init-script": "opensteer init-script <script>",
|
|
31130
|
+
"dom.click": "opensteer click <element> --persist <key>",
|
|
31131
|
+
"dom.hover": "opensteer hover <element> --persist <key>",
|
|
31132
|
+
"dom.input": "opensteer input <element> <text> --persist <key>",
|
|
31133
|
+
"dom.scroll": "opensteer scroll <direction> <amount> --persist <key>",
|
|
31134
|
+
"dom.extract": "opensteer extract <template> --persist <key>",
|
|
31135
|
+
"network.detail": "opensteer network detail <recordId>",
|
|
31136
|
+
"session.fetch": "opensteer fetch <url>",
|
|
31137
|
+
"captcha.solve": "opensteer captcha solve --provider <name> --api-key <key>",
|
|
31138
|
+
"scripts.capture": "opensteer scripts capture",
|
|
31139
|
+
"scripts.beautify": "opensteer scripts beautify <artifactId>",
|
|
31140
|
+
"scripts.deobfuscate": "opensteer scripts deobfuscate <artifactId>",
|
|
31141
|
+
"scripts.sandbox": "opensteer scripts sandbox <artifactId>",
|
|
31142
|
+
"interaction.capture": "opensteer interaction capture",
|
|
31143
|
+
"interaction.get": "opensteer interaction get <traceId>",
|
|
31144
|
+
"interaction.replay": "opensteer interaction replay <traceId>",
|
|
31145
|
+
"interaction.diff": "opensteer interaction diff <leftTraceId> <rightTraceId>",
|
|
31146
|
+
"artifact.read": "opensteer artifact read <artifactId>",
|
|
31147
|
+
"computer.click": "opensteer computer click <x> <y>",
|
|
31148
|
+
"computer.type": "opensteer computer type <text>",
|
|
31149
|
+
"computer.key": "opensteer computer key <key>",
|
|
31150
|
+
"computer.scroll": "opensteer computer scroll <x> <y> --dx <n> --dy <n>",
|
|
31151
|
+
"computer.move": "opensteer computer move <x> <y>",
|
|
31152
|
+
"computer.drag": "opensteer computer drag <x1> <y1> <x2> <y2>",
|
|
31153
|
+
"computer.screenshot": "opensteer computer screenshot",
|
|
31154
|
+
exec: "opensteer exec <expression>",
|
|
31155
|
+
record: "opensteer record --url <url> --workspace <id>",
|
|
31156
|
+
"browser.inspect": "opensteer browser inspect <endpoint>",
|
|
31157
|
+
"browser.clone": "opensteer browser clone --source-user-data-dir <path>"
|
|
31158
|
+
};
|
|
31159
|
+
|
|
30627
31160
|
// src/cli/help.ts
|
|
30628
31161
|
function getHelpText() {
|
|
30629
31162
|
return `Opensteer CLI
|
|
@@ -30885,7 +31418,7 @@ function parseCommandLine(argv) {
|
|
|
30885
31418
|
const key = token.slice(2, separator === -1 ? void 0 : separator);
|
|
30886
31419
|
const spec = CLI_OPTION_SPECS[key];
|
|
30887
31420
|
if (spec === void 0) {
|
|
30888
|
-
throw new
|
|
31421
|
+
throw new CliError("unknown_option", `Unknown option: --${key}.`);
|
|
30889
31422
|
}
|
|
30890
31423
|
if (separator !== -1) {
|
|
30891
31424
|
rawOptions.set(key, [...rawOptions.get(key) ?? [], token.slice(separator + 1)]);
|
|
@@ -30914,7 +31447,8 @@ function parseCommandLine(argv) {
|
|
|
30914
31447
|
continue;
|
|
30915
31448
|
}
|
|
30916
31449
|
if (next === void 0 || next.startsWith("--")) {
|
|
30917
|
-
throw new
|
|
31450
|
+
throw new CliError(
|
|
31451
|
+
"missing_arguments",
|
|
30918
31452
|
`Option "--${key}" requires a value.${next?.startsWith("--") === true ? ` Use "--${key}=<value>" when the value begins with "--".` : ``}`
|
|
30919
31453
|
);
|
|
30920
31454
|
}
|
|
@@ -30960,10 +31494,14 @@ function parseCommandLine(argv) {
|
|
|
30960
31494
|
const autoLocalView = readOptionalBoolean(rawOptions, "auto");
|
|
30961
31495
|
const noAutoLocalView = readOptionalBoolean(rawOptions, "no-auto");
|
|
30962
31496
|
if (autoLocalView === true && noAutoLocalView === true) {
|
|
30963
|
-
throw new
|
|
31497
|
+
throw new CliError("invalid_option", 'Options "--auto" and "--no-auto" cannot be combined.');
|
|
30964
31498
|
}
|
|
30965
31499
|
if (command[0] !== "view" && (autoLocalView !== void 0 || noAutoLocalView !== void 0)) {
|
|
30966
|
-
throw new
|
|
31500
|
+
throw new CliError(
|
|
31501
|
+
"invalid_option",
|
|
31502
|
+
'Options "--auto" and "--no-auto" are only supported with "view".',
|
|
31503
|
+
"opensteer view --auto"
|
|
31504
|
+
);
|
|
30967
31505
|
}
|
|
30968
31506
|
const global = readOptionalBoolean(rawOptions, "global");
|
|
30969
31507
|
const yes = readOptionalBoolean(rawOptions, "yes");
|
|
@@ -31019,7 +31557,7 @@ function parseKeyValueList(values) {
|
|
|
31019
31557
|
values.map((entry) => {
|
|
31020
31558
|
const separator = entry.indexOf("=");
|
|
31021
31559
|
if (separator <= 0) {
|
|
31022
|
-
throw new
|
|
31560
|
+
throw new CliError("invalid_value", `Expected NAME=VALUE, received "${entry}".`);
|
|
31023
31561
|
}
|
|
31024
31562
|
return [entry.slice(0, separator), entry.slice(separator + 1)];
|
|
31025
31563
|
})
|
|
@@ -31050,7 +31588,7 @@ function readOptionalBoolean(options, name) {
|
|
|
31050
31588
|
if (value === "false") {
|
|
31051
31589
|
return false;
|
|
31052
31590
|
}
|
|
31053
|
-
throw new
|
|
31591
|
+
throw new CliError("invalid_value", `Option "--${name}" must be true or false.`);
|
|
31054
31592
|
}
|
|
31055
31593
|
function readOptionalNumber(options, name) {
|
|
31056
31594
|
const value = readSingle(options, name);
|
|
@@ -31059,13 +31597,20 @@ function readOptionalNumber(options, name) {
|
|
|
31059
31597
|
}
|
|
31060
31598
|
const parsed = Number(value);
|
|
31061
31599
|
if (!Number.isFinite(parsed)) {
|
|
31062
|
-
throw new
|
|
31600
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a number.`);
|
|
31063
31601
|
}
|
|
31064
31602
|
return parsed;
|
|
31065
31603
|
}
|
|
31066
31604
|
function readJsonValue(options, name) {
|
|
31067
31605
|
const value = readSingle(options, name);
|
|
31068
|
-
|
|
31606
|
+
if (value === void 0) {
|
|
31607
|
+
return void 0;
|
|
31608
|
+
}
|
|
31609
|
+
try {
|
|
31610
|
+
return JSON.parse(value);
|
|
31611
|
+
} catch {
|
|
31612
|
+
throw new CliError("invalid_value", `Option "--${name}" contains invalid JSON.`);
|
|
31613
|
+
}
|
|
31069
31614
|
}
|
|
31070
31615
|
function readJsonObject(options, name) {
|
|
31071
31616
|
const parsed = readJsonValue(options, name);
|
|
@@ -31073,7 +31618,7 @@ function readJsonObject(options, name) {
|
|
|
31073
31618
|
return void 0;
|
|
31074
31619
|
}
|
|
31075
31620
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31076
|
-
throw new
|
|
31621
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a JSON object.`);
|
|
31077
31622
|
}
|
|
31078
31623
|
return parsed;
|
|
31079
31624
|
}
|
|
@@ -31083,7 +31628,7 @@ function readJsonArray(options, name) {
|
|
|
31083
31628
|
return void 0;
|
|
31084
31629
|
}
|
|
31085
31630
|
if (!Array.isArray(parsed)) {
|
|
31086
|
-
throw new
|
|
31631
|
+
throw new CliError("invalid_value", `Option "--${name}" must be a JSON array.`);
|
|
31087
31632
|
}
|
|
31088
31633
|
return parsed;
|
|
31089
31634
|
}
|
|
@@ -31103,7 +31648,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31103
31648
|
case "session.open": {
|
|
31104
31649
|
const url = parsed.rest[0];
|
|
31105
31650
|
if (url === void 0) {
|
|
31106
|
-
throw new
|
|
31651
|
+
throw new CliError("missing_arguments", "open requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
31107
31652
|
}
|
|
31108
31653
|
return {
|
|
31109
31654
|
url,
|
|
@@ -31136,7 +31681,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31136
31681
|
}
|
|
31137
31682
|
case "page.goto": {
|
|
31138
31683
|
if (parsed.rest[0] === void 0) {
|
|
31139
|
-
throw new
|
|
31684
|
+
throw new CliError("missing_arguments", "goto requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
31140
31685
|
}
|
|
31141
31686
|
const captureNetwork = readSingle(parsed.rawOptions, "capture-network");
|
|
31142
31687
|
return {
|
|
@@ -31148,14 +31693,14 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31148
31693
|
return parsed.rest[0] === void 0 ? {} : { mode: parsed.rest[0] };
|
|
31149
31694
|
case "page.evaluate":
|
|
31150
31695
|
if (parsed.rest[0] === void 0) {
|
|
31151
|
-
throw new
|
|
31696
|
+
throw new CliError("missing_arguments", "evaluate requires a script.", CLI_USAGE_HINTS[operation]);
|
|
31152
31697
|
}
|
|
31153
31698
|
return {
|
|
31154
31699
|
script: joinRest(parsed.rest, 0)
|
|
31155
31700
|
};
|
|
31156
31701
|
case "page.add-init-script":
|
|
31157
31702
|
if (parsed.rest[0] === void 0) {
|
|
31158
|
-
throw new
|
|
31703
|
+
throw new CliError("missing_arguments", "init-script requires a script.", CLI_USAGE_HINTS[operation]);
|
|
31159
31704
|
}
|
|
31160
31705
|
return {
|
|
31161
31706
|
script: joinRest(parsed.rest, 0)
|
|
@@ -31171,7 +31716,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31171
31716
|
return buildElementTargetInput(parsed, "hover");
|
|
31172
31717
|
case "dom.input": {
|
|
31173
31718
|
if (parsed.rest[1] === void 0) {
|
|
31174
|
-
throw new
|
|
31719
|
+
throw new CliError("missing_arguments", "input requires an element number and text.", CLI_USAGE_HINTS[operation]);
|
|
31175
31720
|
}
|
|
31176
31721
|
const pressEnter = readOptionalBoolean(parsed.rawOptions, "press-enter");
|
|
31177
31722
|
return {
|
|
@@ -31202,7 +31747,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31202
31747
|
}
|
|
31203
31748
|
case "dom.extract": {
|
|
31204
31749
|
if (parsed.rest[0] === void 0) {
|
|
31205
|
-
throw new
|
|
31750
|
+
throw new CliError("missing_arguments", "extract requires a template.", CLI_USAGE_HINTS[operation]);
|
|
31206
31751
|
}
|
|
31207
31752
|
const persist = readPersistKey(parsed, "extract");
|
|
31208
31753
|
return {
|
|
@@ -31238,7 +31783,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31238
31783
|
}
|
|
31239
31784
|
case "network.detail": {
|
|
31240
31785
|
if (parsed.rest[0] === void 0) {
|
|
31241
|
-
throw new
|
|
31786
|
+
throw new CliError("missing_arguments", "network detail requires a record id.", CLI_USAGE_HINTS[operation]);
|
|
31242
31787
|
}
|
|
31243
31788
|
const probeFlag = readOptionalBoolean(parsed.rawOptions, "probe");
|
|
31244
31789
|
return {
|
|
@@ -31249,7 +31794,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31249
31794
|
case "session.fetch": {
|
|
31250
31795
|
const url = parsed.rest[0];
|
|
31251
31796
|
if (url === void 0) {
|
|
31252
|
-
throw new
|
|
31797
|
+
throw new CliError("missing_arguments", "fetch requires a URL.", CLI_USAGE_HINTS[operation]);
|
|
31253
31798
|
}
|
|
31254
31799
|
const bodyJson = readJsonValue(parsed.rawOptions, "body");
|
|
31255
31800
|
const bodyText = readSingle(parsed.rawOptions, "body-text");
|
|
@@ -31257,7 +31802,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31257
31802
|
const query = parseKeyValueList(parsed.rawOptions.get("query"));
|
|
31258
31803
|
const headers = parseKeyValueList(parsed.rawOptions.get("header"));
|
|
31259
31804
|
if (bodyJson !== void 0 && bodyText !== void 0) {
|
|
31260
|
-
throw new
|
|
31805
|
+
throw new CliError("invalid_option", 'Use either "--body" or "--body-text", not both.');
|
|
31261
31806
|
}
|
|
31262
31807
|
const transport = readSingle(parsed.rawOptions, "transport");
|
|
31263
31808
|
const cookies = readOptionalBoolean(parsed.rawOptions, "cookies");
|
|
@@ -31288,7 +31833,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31288
31833
|
const siteKey = readSingle(parsed.rawOptions, "site-key");
|
|
31289
31834
|
const pageUrl = readSingle(parsed.rawOptions, "page-url");
|
|
31290
31835
|
if (provider === void 0 || apiKey === void 0) {
|
|
31291
|
-
throw new
|
|
31836
|
+
throw new CliError("missing_arguments", 'captcha solve requires "--provider" and "--api-key".', CLI_USAGE_HINTS[operation]);
|
|
31292
31837
|
}
|
|
31293
31838
|
return {
|
|
31294
31839
|
provider: readCaptchaProvider(provider),
|
|
@@ -31318,7 +31863,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31318
31863
|
case "scripts.beautify":
|
|
31319
31864
|
case "scripts.deobfuscate": {
|
|
31320
31865
|
if (parsed.rest[0] === void 0) {
|
|
31321
|
-
throw new
|
|
31866
|
+
throw new CliError("missing_arguments", `${parsed.command.join(" ")} requires an artifact id.`, CLI_USAGE_HINTS[operation]);
|
|
31322
31867
|
}
|
|
31323
31868
|
const persist = readOptionalBoolean(parsed.rawOptions, "persist");
|
|
31324
31869
|
return {
|
|
@@ -31328,7 +31873,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31328
31873
|
}
|
|
31329
31874
|
case "scripts.sandbox":
|
|
31330
31875
|
if (parsed.rest[0] === void 0) {
|
|
31331
|
-
throw new
|
|
31876
|
+
throw new CliError("missing_arguments", "scripts sandbox requires an artifact id.", CLI_USAGE_HINTS[operation]);
|
|
31332
31877
|
}
|
|
31333
31878
|
{
|
|
31334
31879
|
const fidelity = readSingle(parsed.rawOptions, "fidelity");
|
|
@@ -31377,14 +31922,14 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31377
31922
|
case "interaction.get":
|
|
31378
31923
|
case "interaction.replay":
|
|
31379
31924
|
if (parsed.rest[0] === void 0) {
|
|
31380
|
-
throw new
|
|
31925
|
+
throw new CliError("missing_arguments", `${parsed.command.join(" ")} requires a trace id.`, CLI_USAGE_HINTS[operation]);
|
|
31381
31926
|
}
|
|
31382
31927
|
return {
|
|
31383
31928
|
traceId: parsed.rest[0]
|
|
31384
31929
|
};
|
|
31385
31930
|
case "interaction.diff":
|
|
31386
31931
|
if (parsed.rest[0] === void 0 || parsed.rest[1] === void 0) {
|
|
31387
|
-
throw new
|
|
31932
|
+
throw new CliError("missing_arguments", "interaction diff requires two trace ids.", CLI_USAGE_HINTS[operation]);
|
|
31388
31933
|
}
|
|
31389
31934
|
return {
|
|
31390
31935
|
leftTraceId: parsed.rest[0],
|
|
@@ -31392,7 +31937,7 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31392
31937
|
};
|
|
31393
31938
|
case "artifact.read":
|
|
31394
31939
|
if (parsed.rest[0] === void 0) {
|
|
31395
|
-
throw new
|
|
31940
|
+
throw new CliError("missing_arguments", "artifact read requires an artifact id.", CLI_USAGE_HINTS[operation]);
|
|
31396
31941
|
}
|
|
31397
31942
|
return {
|
|
31398
31943
|
artifactId: parsed.rest[0]
|
|
@@ -31400,7 +31945,8 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31400
31945
|
case "session.close":
|
|
31401
31946
|
return {};
|
|
31402
31947
|
default:
|
|
31403
|
-
throw new
|
|
31948
|
+
throw new CliError(
|
|
31949
|
+
"unsupported_operation",
|
|
31404
31950
|
`${operation} does not have a direct CLI input shape. Use a supported command or the SDK.`
|
|
31405
31951
|
);
|
|
31406
31952
|
}
|
|
@@ -31447,7 +31993,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31447
31993
|
}
|
|
31448
31994
|
case "type":
|
|
31449
31995
|
if (parsed.rest[0] === void 0) {
|
|
31450
|
-
throw new
|
|
31996
|
+
throw new CliError("missing_arguments", "computer type requires text.");
|
|
31451
31997
|
}
|
|
31452
31998
|
return {
|
|
31453
31999
|
action: {
|
|
@@ -31458,7 +32004,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31458
32004
|
};
|
|
31459
32005
|
case "key": {
|
|
31460
32006
|
if (parsed.rest[0] === void 0) {
|
|
31461
|
-
throw new
|
|
32007
|
+
throw new CliError("missing_arguments", "computer key requires a key.");
|
|
31462
32008
|
}
|
|
31463
32009
|
const modifiers = readKeyModifiers(readSingle(parsed.rawOptions, "modifiers"));
|
|
31464
32010
|
return {
|
|
@@ -31474,7 +32020,7 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31474
32020
|
const dx = readOptionalNumber(parsed.rawOptions, "dx");
|
|
31475
32021
|
const dy = readOptionalNumber(parsed.rawOptions, "dy");
|
|
31476
32022
|
if (dx === void 0 || dy === void 0) {
|
|
31477
|
-
throw new
|
|
32023
|
+
throw new CliError("missing_arguments", 'computer scroll requires "--dx" and "--dy".');
|
|
31478
32024
|
}
|
|
31479
32025
|
return {
|
|
31480
32026
|
action: {
|
|
@@ -31529,49 +32075,50 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31529
32075
|
}
|
|
31530
32076
|
};
|
|
31531
32077
|
default:
|
|
31532
|
-
throw new
|
|
32078
|
+
throw new CliError("unknown_command", `Unknown computer command: ${parsed.command.join(" ")}`);
|
|
31533
32079
|
}
|
|
31534
32080
|
}
|
|
31535
32081
|
async function resolvePageRefByIndex(runtime, index) {
|
|
31536
32082
|
const pages = (await runtime.listPages({})).pages;
|
|
31537
32083
|
const page = pages[index - 1];
|
|
31538
32084
|
if (page === void 0) {
|
|
31539
|
-
throw new
|
|
32085
|
+
throw new CliError("invalid_value", `tab ${String(index)} does not exist.`);
|
|
31540
32086
|
}
|
|
31541
32087
|
return page.pageRef;
|
|
31542
32088
|
}
|
|
31543
32089
|
function readRequiredPositiveInteger(value, message) {
|
|
31544
32090
|
const parsed = readRequiredNumber(value, message);
|
|
31545
32091
|
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
31546
|
-
throw new
|
|
32092
|
+
throw new CliError("missing_arguments", message);
|
|
31547
32093
|
}
|
|
31548
32094
|
return parsed;
|
|
31549
32095
|
}
|
|
31550
32096
|
function readRequiredNumber(value, message) {
|
|
31551
32097
|
if (value === void 0) {
|
|
31552
|
-
throw new
|
|
32098
|
+
throw new CliError("missing_arguments", message);
|
|
31553
32099
|
}
|
|
31554
32100
|
const parsed = Number(value);
|
|
31555
32101
|
if (!Number.isFinite(parsed)) {
|
|
31556
|
-
throw new
|
|
32102
|
+
throw new CliError("missing_arguments", message);
|
|
31557
32103
|
}
|
|
31558
32104
|
return parsed;
|
|
31559
32105
|
}
|
|
31560
32106
|
function readSingleDirection(value) {
|
|
31561
32107
|
if (value === void 0 || !SCROLL_DIRECTIONS.has(value)) {
|
|
31562
|
-
throw new
|
|
32108
|
+
throw new CliError("missing_arguments", "scroll requires a direction: up, down, left, or right.");
|
|
31563
32109
|
}
|
|
31564
32110
|
return value;
|
|
31565
32111
|
}
|
|
31566
32112
|
function readClickButton(value) {
|
|
31567
32113
|
if (value === void 0 || !CLICK_BUTTONS.has(value)) {
|
|
31568
|
-
throw new
|
|
32114
|
+
throw new CliError("invalid_value", 'Expected "--button" to be one of: left, middle, right.');
|
|
31569
32115
|
}
|
|
31570
32116
|
return value;
|
|
31571
32117
|
}
|
|
31572
32118
|
function readFetchTransport(value) {
|
|
31573
32119
|
if (value === void 0 || !FETCH_TRANSPORTS.has(value)) {
|
|
31574
|
-
throw new
|
|
32120
|
+
throw new CliError(
|
|
32121
|
+
"invalid_value",
|
|
31575
32122
|
'Expected "--transport" to be one of: auto, direct, matched-tls, context, page.'
|
|
31576
32123
|
);
|
|
31577
32124
|
}
|
|
@@ -31579,31 +32126,31 @@ function readFetchTransport(value) {
|
|
|
31579
32126
|
}
|
|
31580
32127
|
function readCaptchaProvider(value) {
|
|
31581
32128
|
if (value === void 0 || !CAPTCHA_PROVIDERS.has(value)) {
|
|
31582
|
-
throw new
|
|
32129
|
+
throw new CliError("invalid_value", 'Expected "--provider" to be one of: 2captcha, capsolver.');
|
|
31583
32130
|
}
|
|
31584
32131
|
return value;
|
|
31585
32132
|
}
|
|
31586
32133
|
function readCaptchaType(value) {
|
|
31587
32134
|
if (value === void 0 || !CAPTCHA_TYPES.has(value)) {
|
|
31588
|
-
throw new
|
|
32135
|
+
throw new CliError("invalid_value", 'Expected "--type" to be one of: recaptcha-v2, hcaptcha, turnstile.');
|
|
31589
32136
|
}
|
|
31590
32137
|
return value;
|
|
31591
32138
|
}
|
|
31592
32139
|
function readSandboxFidelity(value) {
|
|
31593
32140
|
if (value === void 0 || !SANDBOX_FIDELITIES.has(value)) {
|
|
31594
|
-
throw new
|
|
32141
|
+
throw new CliError("invalid_value", 'Expected "--fidelity" to be one of: minimal, standard, full.');
|
|
31595
32142
|
}
|
|
31596
32143
|
return value;
|
|
31597
32144
|
}
|
|
31598
32145
|
function readSandboxClockMode(value) {
|
|
31599
32146
|
if (value === void 0 || !SANDBOX_CLOCK_MODES.has(value)) {
|
|
31600
|
-
throw new
|
|
32147
|
+
throw new CliError("invalid_value", 'Expected "--clock" to be one of: real, manual.');
|
|
31601
32148
|
}
|
|
31602
32149
|
return value;
|
|
31603
32150
|
}
|
|
31604
32151
|
function readScreenshotFormat(value) {
|
|
31605
32152
|
if (value === void 0 || !SCREENSHOT_FORMATS.has(value)) {
|
|
31606
|
-
throw new
|
|
32153
|
+
throw new CliError("invalid_value", 'Expected "--format" to be one of: png, jpeg, webp.');
|
|
31607
32154
|
}
|
|
31608
32155
|
return value;
|
|
31609
32156
|
}
|
|
@@ -31614,7 +32161,7 @@ function readKeyModifiers(value) {
|
|
|
31614
32161
|
}
|
|
31615
32162
|
for (const modifier of modifiers) {
|
|
31616
32163
|
if (!KEY_MODIFIERS.has(modifier)) {
|
|
31617
|
-
throw new
|
|
32164
|
+
throw new CliError("invalid_value", 'Expected "--modifiers" to contain only: Shift, Control, Alt, Meta.');
|
|
31618
32165
|
}
|
|
31619
32166
|
}
|
|
31620
32167
|
return [...new Set(modifiers)];
|
|
@@ -31622,17 +32169,22 @@ function readKeyModifiers(value) {
|
|
|
31622
32169
|
function readPersistKey(parsed, verb) {
|
|
31623
32170
|
const value = readSingle(parsed.rawOptions, "persist");
|
|
31624
32171
|
if (value === void 0) {
|
|
31625
|
-
throw new
|
|
32172
|
+
throw new CliError("missing_arguments", `${verb} requires "--persist <key>".`);
|
|
31626
32173
|
}
|
|
31627
32174
|
if (value === "true" || value === "false") {
|
|
31628
|
-
throw new
|
|
32175
|
+
throw new CliError("missing_arguments", `${verb} requires "--persist <key>".`);
|
|
31629
32176
|
}
|
|
31630
32177
|
return value;
|
|
31631
32178
|
}
|
|
31632
32179
|
function parseRequiredJsonObjectArgument(value, label) {
|
|
31633
|
-
|
|
32180
|
+
let parsed;
|
|
32181
|
+
try {
|
|
32182
|
+
parsed = JSON.parse(value);
|
|
32183
|
+
} catch {
|
|
32184
|
+
throw new CliError("invalid_value", `${label} contains invalid JSON.`);
|
|
32185
|
+
}
|
|
31634
32186
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31635
|
-
throw new
|
|
32187
|
+
throw new CliError("invalid_value", `${label} must be a JSON object.`);
|
|
31636
32188
|
}
|
|
31637
32189
|
return parsed;
|
|
31638
32190
|
}
|
|
@@ -31644,6 +32196,7 @@ function joinRest(rest, startIndex) {
|
|
|
31644
32196
|
function renderOperationOutput(operation, result, input) {
|
|
31645
32197
|
switch (operation) {
|
|
31646
32198
|
case "session.open":
|
|
32199
|
+
case "page.activate":
|
|
31647
32200
|
case "page.goto":
|
|
31648
32201
|
return renderJson(formatNavigationOutput(result));
|
|
31649
32202
|
case "page.snapshot":
|
|
@@ -31652,14 +32205,14 @@ function renderOperationOutput(operation, result, input) {
|
|
|
31652
32205
|
case "dom.hover":
|
|
31653
32206
|
case "dom.input":
|
|
31654
32207
|
case "dom.scroll":
|
|
31655
|
-
return renderJson(formatActionOutput(result
|
|
32208
|
+
return renderJson(formatActionOutput(result));
|
|
31656
32209
|
case "dom.extract":
|
|
31657
32210
|
return renderJson(formatExtractOutput(result));
|
|
31658
32211
|
case "page.list":
|
|
31659
|
-
case "page.new":
|
|
31660
|
-
case "page.activate":
|
|
31661
32212
|
case "page.close":
|
|
31662
32213
|
return formatTabOutput(result);
|
|
32214
|
+
case "page.new":
|
|
32215
|
+
return renderJson(formatCreatedPageOutput(result));
|
|
31663
32216
|
case "network.query":
|
|
31664
32217
|
return formatNetworkQueryOutput(result, input);
|
|
31665
32218
|
case "network.detail":
|
|
@@ -31697,6 +32250,12 @@ function formatNavigationOutput(result) {
|
|
|
31697
32250
|
...readStringField(result, "title") === void 0 ? {} : { title: readStringField(result, "title") }
|
|
31698
32251
|
};
|
|
31699
32252
|
}
|
|
32253
|
+
function formatCreatedPageOutput(result) {
|
|
32254
|
+
return {
|
|
32255
|
+
...readStringField(result, "pageRef") === void 0 ? {} : { pageRef: readStringField(result, "pageRef") },
|
|
32256
|
+
...formatNavigationOutput(result)
|
|
32257
|
+
};
|
|
32258
|
+
}
|
|
31700
32259
|
function formatSnapshotOutput(result) {
|
|
31701
32260
|
if (result !== null && typeof result === "object" && typeof result.html === "string") {
|
|
31702
32261
|
return `${result.html}
|
|
@@ -31704,36 +32263,11 @@ function formatSnapshotOutput(result) {
|
|
|
31704
32263
|
}
|
|
31705
32264
|
return renderJson(result);
|
|
31706
32265
|
}
|
|
31707
|
-
function formatActionOutput(result
|
|
31708
|
-
|
|
31709
|
-
|
|
31710
|
-
...readStringField(
|
|
31711
|
-
...readStringField(target, "pathHint") === void 0 ? {} : { pathHint: readStringField(target, "pathHint") }
|
|
32266
|
+
function formatActionOutput(result) {
|
|
32267
|
+
return {
|
|
32268
|
+
...readStringField(result, "tagName") === void 0 ? {} : { tagName: readStringField(result, "tagName") },
|
|
32269
|
+
...readStringField(result, "persist") === void 0 ? {} : { persist: readStringField(result, "persist") }
|
|
31712
32270
|
};
|
|
31713
|
-
const point = readObjectField(result, "point");
|
|
31714
|
-
if (point !== void 0) {
|
|
31715
|
-
output.point = {
|
|
31716
|
-
...readNumberField(point, "x") === void 0 ? {} : { x: readNumberField(point, "x") },
|
|
31717
|
-
...readNumberField(point, "y") === void 0 ? {} : { y: readNumberField(point, "y") }
|
|
31718
|
-
};
|
|
31719
|
-
}
|
|
31720
|
-
const persist = readStringField(target, "persist");
|
|
31721
|
-
if (persist !== void 0) {
|
|
31722
|
-
output.persist = persist;
|
|
31723
|
-
}
|
|
31724
|
-
const text = readStringField(input, "text");
|
|
31725
|
-
if (text !== void 0) {
|
|
31726
|
-
output.text = text;
|
|
31727
|
-
}
|
|
31728
|
-
const direction = readStringField(input, "direction");
|
|
31729
|
-
if (direction !== void 0) {
|
|
31730
|
-
output.direction = direction;
|
|
31731
|
-
}
|
|
31732
|
-
const amount = readNumberField(input, "amount");
|
|
31733
|
-
if (amount !== void 0) {
|
|
31734
|
-
output.amount = amount;
|
|
31735
|
-
}
|
|
31736
|
-
return output;
|
|
31737
32271
|
}
|
|
31738
32272
|
function formatExtractOutput(result) {
|
|
31739
32273
|
const data = readUnknownField(result, "data");
|
|
@@ -31965,20 +32499,18 @@ function formatStateOutput(result) {
|
|
|
31965
32499
|
`;
|
|
31966
32500
|
}
|
|
31967
32501
|
function formatComputerOutput(result) {
|
|
31968
|
-
const action = readObjectField(result, "action");
|
|
31969
32502
|
const screenshot = readObjectField(result, "screenshot");
|
|
31970
32503
|
const payload = readObjectField(screenshot, "payload");
|
|
31971
|
-
const timing = readObjectField(result, "timing");
|
|
31972
32504
|
return {
|
|
31973
|
-
...
|
|
32505
|
+
...readStringField(result, "url") === void 0 ? {} : { url: readStringField(result, "url") },
|
|
32506
|
+
...readStringField(result, "title") === void 0 ? {} : { title: readStringField(result, "title") },
|
|
31974
32507
|
...payload === void 0 ? {} : {
|
|
31975
32508
|
screenshot: {
|
|
31976
32509
|
...readStringField(payload, "uri") === void 0 ? {} : { uri: readStringField(payload, "uri") },
|
|
31977
32510
|
...readStringField(screenshot, "format") === void 0 ? {} : { format: readStringField(screenshot, "format") },
|
|
31978
32511
|
...readObjectField(screenshot, "size") === void 0 ? {} : { size: readObjectField(screenshot, "size") }
|
|
31979
32512
|
}
|
|
31980
|
-
}
|
|
31981
|
-
...timing === void 0 ? {} : { timingMs: timing }
|
|
32513
|
+
}
|
|
31982
32514
|
};
|
|
31983
32515
|
}
|
|
31984
32516
|
function formatScriptsCaptureOutput(result) {
|
|
@@ -32640,7 +33172,7 @@ async function collectOpensteerStatus(input) {
|
|
|
32640
33172
|
...output,
|
|
32641
33173
|
rootPath,
|
|
32642
33174
|
lanes: {
|
|
32643
|
-
local: describeLocalLane(localRecord, input.provider.mode === "local"),
|
|
33175
|
+
local: await describeLocalLane(localRecord, input.provider.mode === "local"),
|
|
32644
33176
|
cloud: await describeCloudLane({
|
|
32645
33177
|
record: cloudRecord,
|
|
32646
33178
|
current: input.provider.mode === "cloud",
|
|
@@ -32692,8 +33224,38 @@ async function readWorkspaceCloudRecord(rootPath) {
|
|
|
32692
33224
|
}
|
|
32693
33225
|
return readPersistedCloudSessionRecord(rootPath);
|
|
32694
33226
|
}
|
|
32695
|
-
function describeLocalLane(record, current) {
|
|
32696
|
-
if (record === void 0
|
|
33227
|
+
async function describeLocalLane(record, current) {
|
|
33228
|
+
if (record === void 0) {
|
|
33229
|
+
return {
|
|
33230
|
+
provider: "local",
|
|
33231
|
+
status: "idle",
|
|
33232
|
+
current,
|
|
33233
|
+
summary: "none"
|
|
33234
|
+
};
|
|
33235
|
+
}
|
|
33236
|
+
if (getPersistedLocalBrowserSessionOwnership(record) === "attached") {
|
|
33237
|
+
if (!await isAttachedLocalBrowserSessionReachable(record)) {
|
|
33238
|
+
return {
|
|
33239
|
+
provider: "local",
|
|
33240
|
+
status: "stale",
|
|
33241
|
+
current,
|
|
33242
|
+
summary: "attached browser unavailable",
|
|
33243
|
+
detail: record.engine,
|
|
33244
|
+
engine: record.engine
|
|
33245
|
+
};
|
|
33246
|
+
}
|
|
33247
|
+
const browser2 = record.executablePath ? path10__default.default.basename(record.executablePath).replace(/\.[A-Za-z0-9]+$/u, "") : void 0;
|
|
33248
|
+
return {
|
|
33249
|
+
provider: "local",
|
|
33250
|
+
status: "active",
|
|
33251
|
+
current,
|
|
33252
|
+
summary: "attached browser",
|
|
33253
|
+
detail: browser2 ?? record.engine,
|
|
33254
|
+
engine: record.engine,
|
|
33255
|
+
...browser2 === void 0 ? {} : { browser: browser2 }
|
|
33256
|
+
};
|
|
33257
|
+
}
|
|
33258
|
+
if (!isProcessRunning(record.pid)) {
|
|
32697
33259
|
return {
|
|
32698
33260
|
provider: "local",
|
|
32699
33261
|
status: "idle",
|
|
@@ -32844,13 +33406,13 @@ async function resolveSessionSummary(manifest) {
|
|
|
32844
33406
|
return {
|
|
32845
33407
|
sessionId: manifest.sessionId,
|
|
32846
33408
|
label: manifest.workspace ?? (path10__default.default.basename(manifest.rootPath) || manifest.sessionId),
|
|
32847
|
-
status: isProcessRunning(record.pid) ? "live" : "stale",
|
|
33409
|
+
status: getPersistedLocalBrowserSessionOwnership(record) === "attached" || isProcessRunning(record.pid) ? "live" : "stale",
|
|
32848
33410
|
...manifest.workspace === void 0 ? {} : { workspace: manifest.workspace },
|
|
32849
33411
|
rootPath: manifest.rootPath,
|
|
32850
33412
|
engine: record.engine,
|
|
32851
33413
|
ownership: manifest.ownership,
|
|
32852
|
-
pid: record.pid,
|
|
32853
33414
|
startedAt: record.startedAt,
|
|
33415
|
+
...record.pid > 0 ? { pid: record.pid } : {},
|
|
32854
33416
|
...browserName === void 0 ? {} : { browserName }
|
|
32855
33417
|
};
|
|
32856
33418
|
}
|
|
@@ -32878,7 +33440,16 @@ async function readLiveRecord(manifest) {
|
|
|
32878
33440
|
if (!record) {
|
|
32879
33441
|
return void 0;
|
|
32880
33442
|
}
|
|
32881
|
-
if (
|
|
33443
|
+
if (buildLocalViewSessionIdForRecord({
|
|
33444
|
+
rootPath: manifest.rootPath,
|
|
33445
|
+
live: record
|
|
33446
|
+
}) !== manifest.sessionId || record.startedAt !== manifest.startedAt || record.engine !== manifest.engine || getPersistedLocalBrowserSessionOwnership(record) !== manifest.ownership) {
|
|
33447
|
+
return void 0;
|
|
33448
|
+
}
|
|
33449
|
+
if (getPersistedLocalBrowserSessionOwnership(record) === "attached") {
|
|
33450
|
+
return await isAttachedLocalBrowserSessionReachable(record) ? record : void 0;
|
|
33451
|
+
}
|
|
33452
|
+
if (record.pid !== manifest.pid || !isProcessRunning(record.pid)) {
|
|
32882
33453
|
return void 0;
|
|
32883
33454
|
}
|
|
32884
33455
|
return record;
|
|
@@ -34610,7 +35181,7 @@ async function handleViewCommand(parsed, options = {}) {
|
|
|
34610
35181
|
return;
|
|
34611
35182
|
}
|
|
34612
35183
|
if (subcommand !== void 0) {
|
|
34613
|
-
throw new
|
|
35184
|
+
throw new CliError("unknown_command", `Unknown view command: view ${subcommand}`);
|
|
34614
35185
|
}
|
|
34615
35186
|
if (parsed.options.localViewMode !== void 0) {
|
|
34616
35187
|
const preference = await setLocalViewMode(parsed.options.localViewMode);
|
|
@@ -34647,18 +35218,27 @@ async function resolveWorkspaceSessionId(input) {
|
|
|
34647
35218
|
workspace: input.workspace
|
|
34648
35219
|
});
|
|
34649
35220
|
const live = await readPersistedLocalBrowserSessionRecord(rootPath);
|
|
34650
|
-
if (!live
|
|
35221
|
+
if (!live) {
|
|
34651
35222
|
return void 0;
|
|
34652
35223
|
}
|
|
34653
|
-
|
|
35224
|
+
if (getPersistedLocalBrowserSessionOwnership(live) === "attached") {
|
|
35225
|
+
if (!await isAttachedLocalBrowserSessionReachable(live)) {
|
|
35226
|
+
return void 0;
|
|
35227
|
+
}
|
|
35228
|
+
} else if (!isProcessRunning(live.pid)) {
|
|
35229
|
+
return void 0;
|
|
35230
|
+
}
|
|
35231
|
+
return buildLocalViewSessionIdForRecord({
|
|
34654
35232
|
rootPath,
|
|
34655
|
-
|
|
34656
|
-
startedAt: live.startedAt
|
|
35233
|
+
live
|
|
34657
35234
|
});
|
|
34658
35235
|
}
|
|
34659
35236
|
function assertNoViewPreferenceFlag(parsed) {
|
|
34660
35237
|
if (parsed.options.localViewMode !== void 0) {
|
|
34661
|
-
throw new
|
|
35238
|
+
throw new CliError(
|
|
35239
|
+
"invalid_option",
|
|
35240
|
+
"View preference flags cannot be combined with this subcommand."
|
|
35241
|
+
);
|
|
34662
35242
|
}
|
|
34663
35243
|
}
|
|
34664
35244
|
function writeViewOutput(parsed, value) {
|
|
@@ -34743,10 +35323,10 @@ async function main() {
|
|
|
34743
35323
|
}
|
|
34744
35324
|
const operation = resolveOperation(parsed.command);
|
|
34745
35325
|
if (!operation) {
|
|
34746
|
-
throw new
|
|
35326
|
+
throw new CliError("unknown_command", `Unknown command: ${parsed.command.join(" ")}`);
|
|
34747
35327
|
}
|
|
34748
35328
|
if (parsed.options.workspace === void 0) {
|
|
34749
|
-
throw new
|
|
35329
|
+
throw new CliError("missing_workspace", 'Stateful commands require "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
34750
35330
|
}
|
|
34751
35331
|
const { engineName, provider, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
34752
35332
|
if (operation === "session.close") {
|
|
@@ -34768,24 +35348,39 @@ async function main() {
|
|
|
34768
35348
|
let renderOperation = operation;
|
|
34769
35349
|
try {
|
|
34770
35350
|
const input = await buildOperationInput(operation, parsed, runtime);
|
|
34771
|
-
|
|
35351
|
+
const rawResult = await dispatchSemanticOperation(runtime, operation, input);
|
|
34772
35352
|
if (parsed.command[0] === "tab" && operation !== "page.list") {
|
|
34773
35353
|
renderOperation = "page.list";
|
|
34774
35354
|
result = await runtime.listPages({});
|
|
35355
|
+
} else {
|
|
35356
|
+
result = rawResult;
|
|
35357
|
+
}
|
|
35358
|
+
let warning;
|
|
35359
|
+
if (result !== null && typeof result === "object" && "warning" in result) {
|
|
35360
|
+
const { warning: w, ...rest } = result;
|
|
35361
|
+
if (typeof w === "string") {
|
|
35362
|
+
warning = w;
|
|
35363
|
+
result = rest;
|
|
35364
|
+
}
|
|
34775
35365
|
}
|
|
34776
35366
|
process4__default.default.stdout.write(renderOperationOutput(renderOperation, result, input));
|
|
35367
|
+
if (warning !== void 0) {
|
|
35368
|
+
emitWarning(warning);
|
|
35369
|
+
}
|
|
34777
35370
|
} finally {
|
|
34778
35371
|
await runtime.disconnect().catch(() => void 0);
|
|
34779
35372
|
}
|
|
34780
35373
|
}
|
|
34781
35374
|
async function handleExecCommand(parsed) {
|
|
34782
35375
|
if (parsed.options.workspace === void 0) {
|
|
34783
|
-
throw new
|
|
35376
|
+
throw new CliError("missing_workspace", 'exec requires "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
34784
35377
|
}
|
|
34785
35378
|
const expression = parsed.rest.join(" ");
|
|
34786
35379
|
if (!expression) {
|
|
34787
|
-
throw new
|
|
34788
|
-
|
|
35380
|
+
throw new CliError(
|
|
35381
|
+
"missing_arguments",
|
|
35382
|
+
"exec requires an expression.",
|
|
35383
|
+
"opensteer exec <expression>"
|
|
34789
35384
|
);
|
|
34790
35385
|
}
|
|
34791
35386
|
const { engineName, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
@@ -34821,8 +35416,10 @@ async function handleBrowserCommand(parsed) {
|
|
|
34821
35416
|
if (subcommand === "inspect") {
|
|
34822
35417
|
const endpoint = parsed.options.attachEndpoint ?? parsed.rest[0];
|
|
34823
35418
|
if (!endpoint) {
|
|
34824
|
-
throw new
|
|
34825
|
-
|
|
35419
|
+
throw new CliError(
|
|
35420
|
+
"missing_arguments",
|
|
35421
|
+
'browser inspect requires "--attach-endpoint <url>" or a positional endpoint.',
|
|
35422
|
+
"opensteer browser inspect <endpoint>"
|
|
34826
35423
|
);
|
|
34827
35424
|
}
|
|
34828
35425
|
const result = await inspectCdpEndpoint({
|
|
@@ -34835,7 +35432,8 @@ async function handleBrowserCommand(parsed) {
|
|
|
34835
35432
|
return;
|
|
34836
35433
|
}
|
|
34837
35434
|
if (parsed.options.workspace === void 0) {
|
|
34838
|
-
throw new
|
|
35435
|
+
throw new CliError(
|
|
35436
|
+
"missing_workspace",
|
|
34839
35437
|
'Browser workspace commands require "--workspace <id>" or OPENSTEER_WORKSPACE.'
|
|
34840
35438
|
);
|
|
34841
35439
|
}
|
|
@@ -34858,7 +35456,11 @@ async function handleBrowserCommand(parsed) {
|
|
|
34858
35456
|
case "clone": {
|
|
34859
35457
|
const sourceUserDataDir = parsed.options.sourceUserDataDir;
|
|
34860
35458
|
if (!sourceUserDataDir) {
|
|
34861
|
-
throw new
|
|
35459
|
+
throw new CliError(
|
|
35460
|
+
"missing_arguments",
|
|
35461
|
+
'browser clone requires "--source-user-data-dir <path>".',
|
|
35462
|
+
"opensteer browser clone --source-user-data-dir <path>"
|
|
35463
|
+
);
|
|
34862
35464
|
}
|
|
34863
35465
|
const result = await manager.clonePersistentBrowser({
|
|
34864
35466
|
sourceUserDataDir,
|
|
@@ -34881,7 +35483,7 @@ async function handleBrowserCommand(parsed) {
|
|
|
34881
35483
|
return;
|
|
34882
35484
|
}
|
|
34883
35485
|
default:
|
|
34884
|
-
throw new
|
|
35486
|
+
throw new CliError("unknown_command", `Unknown browser command: ${parsed.command.join(" ")}`);
|
|
34885
35487
|
}
|
|
34886
35488
|
}
|
|
34887
35489
|
async function handleCloseCommand(parsed, engineName, providerMode, runtimeProvider) {
|
|
@@ -34914,23 +35516,27 @@ async function handleCloseCommand(parsed, engineName, providerMode, runtimeProvi
|
|
|
34914
35516
|
}
|
|
34915
35517
|
async function handleRecordCommandEntry(parsed) {
|
|
34916
35518
|
if (parsed.options.workspace === void 0) {
|
|
34917
|
-
throw new
|
|
35519
|
+
throw new CliError("missing_workspace", 'record requires "--workspace <id>" or OPENSTEER_WORKSPACE.');
|
|
34918
35520
|
}
|
|
34919
35521
|
const url = parsed.options.url ?? parsed.rest[0];
|
|
34920
35522
|
if (url === void 0) {
|
|
34921
|
-
throw new
|
|
35523
|
+
throw new CliError(
|
|
35524
|
+
"missing_arguments",
|
|
35525
|
+
'record requires "--url <value>" or a positional URL.',
|
|
35526
|
+
"opensteer record --url <url> --workspace <id>"
|
|
35527
|
+
);
|
|
34922
35528
|
}
|
|
34923
35529
|
const provider = resolveCliProvider(parsed);
|
|
34924
35530
|
assertCloudCliOptionsMatchProvider(parsed, provider.mode);
|
|
34925
35531
|
const engineName = resolveCliEngineName(parsed);
|
|
34926
35532
|
if (engineName !== "playwright") {
|
|
34927
|
-
throw new
|
|
35533
|
+
throw new CliError("config_conflict", "record requires engine=playwright.");
|
|
34928
35534
|
}
|
|
34929
35535
|
const rootDir = process4__default.default.cwd();
|
|
34930
35536
|
const recordBrowser = parsed.options.browser;
|
|
34931
35537
|
if (provider.mode === "cloud") {
|
|
34932
35538
|
if (typeof recordBrowser === "object") {
|
|
34933
|
-
throw new
|
|
35539
|
+
throw new CliError("config_conflict", 'record does not support browser.mode="attach".');
|
|
34934
35540
|
}
|
|
34935
35541
|
const runtimeProvider = buildCliRuntimeProvider(parsed, provider.mode);
|
|
34936
35542
|
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
@@ -34950,10 +35556,10 @@ async function handleRecordCommandEntry(parsed) {
|
|
|
34950
35556
|
return;
|
|
34951
35557
|
}
|
|
34952
35558
|
if (parsed.options.launch?.headless === true) {
|
|
34953
|
-
throw new
|
|
35559
|
+
throw new CliError("config_conflict", 'record requires a headed browser. Remove "--headless true".');
|
|
34954
35560
|
}
|
|
34955
35561
|
if (typeof recordBrowser === "object") {
|
|
34956
|
-
throw new
|
|
35562
|
+
throw new CliError("config_conflict", 'record does not support browser.mode="attach".');
|
|
34957
35563
|
}
|
|
34958
35564
|
const launch = {
|
|
34959
35565
|
...parsed.options.launch ?? {},
|
|
@@ -35022,7 +35628,7 @@ function resolveCliBootstrapAction(argv) {
|
|
|
35022
35628
|
}
|
|
35023
35629
|
function buildCliBrowserProfile(parsed) {
|
|
35024
35630
|
if (parsed.options.cloudProfileReuseIfActive === true && parsed.options.cloudProfileId === void 0) {
|
|
35025
|
-
throw new
|
|
35631
|
+
throw new CliError("invalid_option", '"--cloud-profile-reuse-if-active" requires "--cloud-profile-id <id>".');
|
|
35026
35632
|
}
|
|
35027
35633
|
return parsed.options.cloudProfileId === void 0 ? void 0 : {
|
|
35028
35634
|
profileId: parsed.options.cloudProfileId,
|
|
@@ -35083,7 +35689,8 @@ function buildCliRuntimeProvider(parsed, providerMode) {
|
|
|
35083
35689
|
}
|
|
35084
35690
|
function assertCloudCliOptionsMatchProvider(parsed, providerMode) {
|
|
35085
35691
|
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
|
|
35692
|
+
throw new CliError(
|
|
35693
|
+
"config_conflict",
|
|
35087
35694
|
'Cloud-specific options require provider=cloud. Set "--provider cloud" or OPENSTEER_PROVIDER=cloud.'
|
|
35088
35695
|
);
|
|
35089
35696
|
}
|
|
@@ -35117,17 +35724,7 @@ function printVersion() {
|
|
|
35117
35724
|
`);
|
|
35118
35725
|
}
|
|
35119
35726
|
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
|
-
};
|
|
35727
|
+
const payload = formatCliErrorOutput(error);
|
|
35131
35728
|
process4__default.default.stderr.write(`${JSON.stringify(payload)}
|
|
35132
35729
|
`);
|
|
35133
35730
|
process4__default.default.exitCode = 1;
|