opensteer 0.9.6 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{chunk-3I3A5OLB.js → chunk-BPGXP3RF.js} +257 -24
- package/dist/chunk-BPGXP3RF.js.map +1 -0
- package/dist/{chunk-3XBQRZZC.js → chunk-EXXRLPLI.js} +158 -46
- package/dist/chunk-EXXRLPLI.js.map +1 -0
- package/dist/{chunk-T5P2QGZ3.js → chunk-GKYBP3KD.js} +154 -13
- package/dist/chunk-GKYBP3KD.js.map +1 -0
- package/dist/{chunk-BVRIPCWA.js → chunk-LFWP5RXF.js} +500 -513
- package/dist/chunk-LFWP5RXF.js.map +1 -0
- package/dist/{chunk-L4NF74KI.js → chunk-SOJEWKSW.js} +5 -5
- package/dist/{chunk-L4NF74KI.js.map → chunk-SOJEWKSW.js.map} +1 -1
- package/dist/cli/bin.cjs +1230 -660
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +166 -72
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +793 -565
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -51
- package/dist/index.d.ts +36 -51
- package/dist/index.js +4 -4
- package/dist/local-view/public/assets/app.js +10 -1
- package/dist/local-view/serve-entry.cjs +1022 -591
- package/dist/local-view/serve-entry.cjs.map +1 -1
- package/dist/local-view/serve-entry.js +2 -2
- package/dist/opensteer-XLPY343Y.js +6 -0
- package/dist/{opensteer-UGA6YBRN.js.map → opensteer-XLPY343Y.js.map} +1 -1
- package/dist/{session-control-U3L5H2ZI.js → session-control-FVKKD45R.js} +4 -4
- package/dist/{session-control-U3L5H2ZI.js.map → session-control-FVKKD45R.js.map} +1 -1
- package/package.json +5 -5
- package/skills/recorder/SKILL.md +2 -2
- package/dist/chunk-3I3A5OLB.js.map +0 -1
- package/dist/chunk-3XBQRZZC.js.map +0 -1
- package/dist/chunk-BVRIPCWA.js.map +0 -1
- package/dist/chunk-T5P2QGZ3.js.map +0 -1
- package/dist/opensteer-UGA6YBRN.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}`;
|
|
@@ -2840,6 +2940,9 @@ var init_metadata2 = __esm({
|
|
|
2840
2940
|
{
|
|
2841
2941
|
pageRef: pageRefSchema,
|
|
2842
2942
|
sessionRef: sessionRefSchema,
|
|
2943
|
+
targetId: stringSchema({
|
|
2944
|
+
description: "Underlying browser target identifier when available."
|
|
2945
|
+
}),
|
|
2843
2946
|
openerPageRef: pageRefSchema,
|
|
2844
2947
|
url: stringSchema({
|
|
2845
2948
|
description: "Current main-frame URL."
|
|
@@ -6677,15 +6780,15 @@ function assertValidSemanticOperationInput(name, input) {
|
|
|
6677
6780
|
}
|
|
6678
6781
|
);
|
|
6679
6782
|
}
|
|
6680
|
-
var opensteerComputerAnnotationNames, opensteerExposedSemanticOperationNames, opensteerPackageRunnableSemanticOperationNames, snapshotModeSchema, viewportSchema, opensteerBrowserLaunchOptionsSchema, attachBrowserOptionsSchema, opensteerBrowserOptionsSchema, opensteerBrowserContextOptionsSchema, targetByElementSchema2, targetByPersistSchema2, targetBySelectorSchema2, opensteerTargetInputSchema,
|
|
6783
|
+
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;
|
|
6681
6784
|
var init_semantic = __esm({
|
|
6682
6785
|
"../protocol/src/semantic.ts"() {
|
|
6683
6786
|
init_json2();
|
|
6684
6787
|
init_errors2();
|
|
6788
|
+
init_binary_location();
|
|
6685
6789
|
init_identity2();
|
|
6686
6790
|
init_geometry2();
|
|
6687
6791
|
init_metadata2();
|
|
6688
|
-
init_events2();
|
|
6689
6792
|
init_envelopes();
|
|
6690
6793
|
init_snapshots2();
|
|
6691
6794
|
init_artifacts2();
|
|
@@ -6909,39 +7012,14 @@ var init_semantic = __esm({
|
|
|
6909
7012
|
title: "OpensteerTargetInput"
|
|
6910
7013
|
}
|
|
6911
7014
|
);
|
|
6912
|
-
opensteerResolvedTargetSchema = objectSchema(
|
|
6913
|
-
{
|
|
6914
|
-
pageRef: pageRefSchema,
|
|
6915
|
-
frameRef: frameRefSchema,
|
|
6916
|
-
documentRef: documentRefSchema,
|
|
6917
|
-
documentEpoch: documentEpochSchema,
|
|
6918
|
-
nodeRef: nodeRefSchema,
|
|
6919
|
-
tagName: stringSchema(),
|
|
6920
|
-
pathHint: stringSchema(),
|
|
6921
|
-
persist: stringSchema(),
|
|
6922
|
-
selectorUsed: stringSchema()
|
|
6923
|
-
},
|
|
6924
|
-
{
|
|
6925
|
-
title: "OpensteerResolvedTarget",
|
|
6926
|
-
required: [
|
|
6927
|
-
"pageRef",
|
|
6928
|
-
"frameRef",
|
|
6929
|
-
"documentRef",
|
|
6930
|
-
"documentEpoch",
|
|
6931
|
-
"nodeRef",
|
|
6932
|
-
"tagName",
|
|
6933
|
-
"pathHint"
|
|
6934
|
-
]
|
|
6935
|
-
}
|
|
6936
|
-
);
|
|
6937
7015
|
opensteerActionResultSchema = objectSchema(
|
|
6938
7016
|
{
|
|
6939
|
-
|
|
6940
|
-
|
|
7017
|
+
tagName: stringSchema({ minLength: 1 }),
|
|
7018
|
+
persist: stringSchema({ minLength: 1 })
|
|
6941
7019
|
},
|
|
6942
7020
|
{
|
|
6943
7021
|
title: "OpensteerActionResult",
|
|
6944
|
-
required: ["
|
|
7022
|
+
required: ["tagName"]
|
|
6945
7023
|
}
|
|
6946
7024
|
);
|
|
6947
7025
|
opensteerSnapshotCounterSchema = objectSchema(
|
|
@@ -6987,16 +7065,14 @@ var init_semantic = __esm({
|
|
|
6987
7065
|
]
|
|
6988
7066
|
}
|
|
6989
7067
|
);
|
|
6990
|
-
|
|
7068
|
+
opensteerNavigationSummarySchema = objectSchema(
|
|
6991
7069
|
{
|
|
6992
|
-
sessionRef: sessionRefSchema,
|
|
6993
|
-
pageRef: pageRefSchema,
|
|
6994
7070
|
url: stringSchema(),
|
|
6995
7071
|
title: stringSchema()
|
|
6996
7072
|
},
|
|
6997
7073
|
{
|
|
6998
|
-
title: "
|
|
6999
|
-
required: ["
|
|
7074
|
+
title: "OpensteerNavigationSummary",
|
|
7075
|
+
required: ["url", "title"]
|
|
7000
7076
|
}
|
|
7001
7077
|
);
|
|
7002
7078
|
opensteerOpenInputSchema = objectSchema(
|
|
@@ -7064,6 +7140,17 @@ var init_semantic = __esm({
|
|
|
7064
7140
|
required: ["closedPageRef", "pages"]
|
|
7065
7141
|
}
|
|
7066
7142
|
);
|
|
7143
|
+
opensteerPageNewOutputSchema = objectSchema(
|
|
7144
|
+
{
|
|
7145
|
+
pageRef: pageRefSchema,
|
|
7146
|
+
url: stringSchema(),
|
|
7147
|
+
title: stringSchema()
|
|
7148
|
+
},
|
|
7149
|
+
{
|
|
7150
|
+
title: "OpensteerPageNewOutput",
|
|
7151
|
+
required: ["pageRef", "url", "title"]
|
|
7152
|
+
}
|
|
7153
|
+
);
|
|
7067
7154
|
opensteerPageGotoInputSchema = objectSchema(
|
|
7068
7155
|
{
|
|
7069
7156
|
url: stringSchema(),
|
|
@@ -7450,72 +7537,28 @@ var init_semantic = __esm({
|
|
|
7450
7537
|
required: ["action"]
|
|
7451
7538
|
}
|
|
7452
7539
|
);
|
|
7453
|
-
|
|
7454
|
-
{
|
|
7455
|
-
role: enumSchema(["point", "start", "end"]),
|
|
7456
|
-
point: pointSchema,
|
|
7457
|
-
hitTest: hitTestResultSchema,
|
|
7458
|
-
target: opensteerResolvedTargetSchema
|
|
7459
|
-
},
|
|
7460
|
-
{
|
|
7461
|
-
title: "OpensteerComputerTracePoint",
|
|
7462
|
-
required: ["role", "point"]
|
|
7463
|
-
}
|
|
7464
|
-
);
|
|
7465
|
-
opensteerComputerTraceEnrichmentSchema = objectSchema(
|
|
7466
|
-
{
|
|
7467
|
-
points: arraySchema(opensteerComputerTracePointSchema)
|
|
7468
|
-
},
|
|
7469
|
-
{
|
|
7470
|
-
title: "OpensteerComputerTraceEnrichment",
|
|
7471
|
-
required: ["points"]
|
|
7472
|
-
}
|
|
7473
|
-
);
|
|
7474
|
-
opensteerComputerExecuteTimingSchema = objectSchema(
|
|
7475
|
-
{
|
|
7476
|
-
actionMs: integerSchema({ minimum: 0 }),
|
|
7477
|
-
waitMs: integerSchema({ minimum: 0 }),
|
|
7478
|
-
totalMs: integerSchema({ minimum: 0 })
|
|
7479
|
-
},
|
|
7480
|
-
{
|
|
7481
|
-
title: "OpensteerComputerExecuteTiming",
|
|
7482
|
-
required: ["actionMs", "waitMs", "totalMs"]
|
|
7483
|
-
}
|
|
7484
|
-
);
|
|
7485
|
-
opensteerComputerDisplayScaleSchema = objectSchema(
|
|
7540
|
+
opensteerScreenshotSummarySchema = objectSchema(
|
|
7486
7541
|
{
|
|
7487
|
-
|
|
7488
|
-
|
|
7542
|
+
payload: externalBinaryLocationSchema,
|
|
7543
|
+
format: screenshotFormatSchema,
|
|
7544
|
+
size: sizeSchema,
|
|
7545
|
+
coordinateSpace: coordinateSpaceSchema,
|
|
7546
|
+
clip: rectSchema
|
|
7489
7547
|
},
|
|
7490
7548
|
{
|
|
7491
|
-
title: "
|
|
7492
|
-
required: ["
|
|
7549
|
+
title: "OpensteerScreenshotSummary",
|
|
7550
|
+
required: ["payload", "format", "size", "coordinateSpace"]
|
|
7493
7551
|
}
|
|
7494
7552
|
);
|
|
7495
7553
|
opensteerComputerExecuteOutputSchema = objectSchema(
|
|
7496
7554
|
{
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
screenshot:
|
|
7500
|
-
displayViewport: viewportMetricsSchema,
|
|
7501
|
-
nativeViewport: viewportMetricsSchema,
|
|
7502
|
-
displayScale: opensteerComputerDisplayScaleSchema,
|
|
7503
|
-
events: arraySchema(opensteerEventSchema),
|
|
7504
|
-
timing: opensteerComputerExecuteTimingSchema,
|
|
7505
|
-
trace: opensteerComputerTraceEnrichmentSchema
|
|
7555
|
+
url: stringSchema(),
|
|
7556
|
+
title: stringSchema(),
|
|
7557
|
+
screenshot: opensteerScreenshotSummarySchema
|
|
7506
7558
|
},
|
|
7507
7559
|
{
|
|
7508
7560
|
title: "OpensteerComputerExecuteOutput",
|
|
7509
|
-
required: [
|
|
7510
|
-
"action",
|
|
7511
|
-
"pageRef",
|
|
7512
|
-
"screenshot",
|
|
7513
|
-
"displayViewport",
|
|
7514
|
-
"nativeViewport",
|
|
7515
|
-
"displayScale",
|
|
7516
|
-
"events",
|
|
7517
|
-
"timing"
|
|
7518
|
-
]
|
|
7561
|
+
required: ["url", "title", "screenshot"]
|
|
7519
7562
|
}
|
|
7520
7563
|
);
|
|
7521
7564
|
opensteerSemanticOperationSpecificationsBase = [
|
|
@@ -7523,7 +7566,7 @@ var init_semantic = __esm({
|
|
|
7523
7566
|
name: "session.open",
|
|
7524
7567
|
description: "Open or resume the current Opensteer session and primary page.",
|
|
7525
7568
|
inputSchema: opensteerOpenInputSchema,
|
|
7526
|
-
outputSchema:
|
|
7569
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
7527
7570
|
requiredCapabilities: ["sessions.manage", "pages.manage"],
|
|
7528
7571
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["sessions.manage", "pages.manage"] : ["sessions.manage", "pages.manage", "pages.navigate"]
|
|
7529
7572
|
}),
|
|
@@ -7538,7 +7581,7 @@ var init_semantic = __esm({
|
|
|
7538
7581
|
name: "page.new",
|
|
7539
7582
|
description: "Create and optionally navigate a new top-level page in the current session.",
|
|
7540
7583
|
inputSchema: opensteerPageNewInputSchema,
|
|
7541
|
-
outputSchema:
|
|
7584
|
+
outputSchema: opensteerPageNewOutputSchema,
|
|
7542
7585
|
requiredCapabilities: ["pages.manage"],
|
|
7543
7586
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["pages.manage"] : ["pages.manage", "pages.navigate"]
|
|
7544
7587
|
}),
|
|
@@ -7546,7 +7589,7 @@ var init_semantic = __esm({
|
|
|
7546
7589
|
name: "page.activate",
|
|
7547
7590
|
description: "Activate an existing top-level page in the current session.",
|
|
7548
7591
|
inputSchema: opensteerPageActivateInputSchema,
|
|
7549
|
-
outputSchema:
|
|
7592
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
7550
7593
|
requiredCapabilities: ["pages.manage", "inspect.pages"]
|
|
7551
7594
|
}),
|
|
7552
7595
|
defineSemanticOperationSpec({
|
|
@@ -7560,7 +7603,7 @@ var init_semantic = __esm({
|
|
|
7560
7603
|
name: "page.goto",
|
|
7561
7604
|
description: "Navigate the current Opensteer page to a new URL.",
|
|
7562
7605
|
inputSchema: opensteerPageGotoInputSchema,
|
|
7563
|
-
outputSchema:
|
|
7606
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
7564
7607
|
requiredCapabilities: ["pages.navigate"]
|
|
7565
7608
|
}),
|
|
7566
7609
|
defineSemanticOperationSpec({
|
|
@@ -9103,6 +9146,9 @@ var init_observations = __esm({
|
|
|
9103
9146
|
this.store = store;
|
|
9104
9147
|
this.sessionId = sessionId;
|
|
9105
9148
|
}
|
|
9149
|
+
configure(input) {
|
|
9150
|
+
return this.store.configureSession(this.sessionId, input);
|
|
9151
|
+
}
|
|
9106
9152
|
append(input) {
|
|
9107
9153
|
return this.store.appendEvent(this.sessionId, input);
|
|
9108
9154
|
}
|
|
@@ -9133,40 +9179,14 @@ var init_observations = __esm({
|
|
|
9133
9179
|
const sessionId = normalizeNonEmptyString("sessionId", input.sessionId);
|
|
9134
9180
|
const openedAt = normalizeTimestamp("openedAt", input.openedAt ?? Date.now());
|
|
9135
9181
|
const config = normalizeObservabilityConfig(input.config);
|
|
9136
|
-
|
|
9137
|
-
this.redactors.set(sessionId, redactor);
|
|
9138
|
-
const redactedLabels = redactor.redactLabels(config.labels);
|
|
9139
|
-
const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
|
|
9140
|
-
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
9141
|
-
const existing = await this.reconcileSessionManifest(sessionId);
|
|
9142
|
-
if (existing === void 0) {
|
|
9143
|
-
await ensureDirectory(this.sessionEventsDirectory(sessionId));
|
|
9144
|
-
await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
|
|
9145
|
-
const session = {
|
|
9146
|
-
sessionId,
|
|
9147
|
-
profile: config.profile,
|
|
9148
|
-
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
9149
|
-
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
9150
|
-
openedAt,
|
|
9151
|
-
updatedAt: openedAt,
|
|
9152
|
-
currentSequence: 0,
|
|
9153
|
-
eventCount: 0,
|
|
9154
|
-
artifactCount: 0
|
|
9155
|
-
};
|
|
9156
|
-
await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
|
|
9157
|
-
return;
|
|
9158
|
-
}
|
|
9159
|
-
const patched = {
|
|
9160
|
-
...existing,
|
|
9161
|
-
profile: config.profile,
|
|
9162
|
-
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
9163
|
-
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
9164
|
-
updatedAt: Math.max(existing.updatedAt, openedAt)
|
|
9165
|
-
};
|
|
9166
|
-
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
|
|
9167
|
-
});
|
|
9182
|
+
await this.applySessionConfiguration(sessionId, config, openedAt);
|
|
9168
9183
|
return new FilesystemSessionSink(this, sessionId);
|
|
9169
9184
|
}
|
|
9185
|
+
async configureSession(sessionId, input) {
|
|
9186
|
+
const updatedAt = normalizeTimestamp("updatedAt", input.updatedAt ?? Date.now());
|
|
9187
|
+
const config = normalizeObservabilityConfig(input.config);
|
|
9188
|
+
await this.applySessionConfiguration(sessionId, config, updatedAt);
|
|
9189
|
+
}
|
|
9170
9190
|
async getSession(sessionId) {
|
|
9171
9191
|
const manifestPath = this.sessionManifestPath(sessionId);
|
|
9172
9192
|
if (!await pathExists(manifestPath)) {
|
|
@@ -9387,6 +9407,40 @@ var init_observations = __esm({
|
|
|
9387
9407
|
sessionLockPath(sessionId) {
|
|
9388
9408
|
return path10__default.default.join(this.sessionDirectory(sessionId), ".lock");
|
|
9389
9409
|
}
|
|
9410
|
+
async applySessionConfiguration(sessionId, config, timestamp) {
|
|
9411
|
+
const redactor = createObservationRedactor(config);
|
|
9412
|
+
this.redactors.set(sessionId, redactor);
|
|
9413
|
+
const redactedLabels = redactor.redactLabels(config.labels);
|
|
9414
|
+
const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
|
|
9415
|
+
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
9416
|
+
const existing = await this.reconcileSessionManifest(sessionId);
|
|
9417
|
+
if (existing === void 0) {
|
|
9418
|
+
await ensureDirectory(this.sessionEventsDirectory(sessionId));
|
|
9419
|
+
await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
|
|
9420
|
+
const session = {
|
|
9421
|
+
sessionId,
|
|
9422
|
+
profile: config.profile,
|
|
9423
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
9424
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
9425
|
+
openedAt: timestamp,
|
|
9426
|
+
updatedAt: timestamp,
|
|
9427
|
+
currentSequence: 0,
|
|
9428
|
+
eventCount: 0,
|
|
9429
|
+
artifactCount: 0
|
|
9430
|
+
};
|
|
9431
|
+
await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
|
|
9432
|
+
return;
|
|
9433
|
+
}
|
|
9434
|
+
const patched = {
|
|
9435
|
+
...existing,
|
|
9436
|
+
profile: config.profile,
|
|
9437
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
9438
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
9439
|
+
updatedAt: Math.max(existing.updatedAt, timestamp)
|
|
9440
|
+
};
|
|
9441
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
|
|
9442
|
+
});
|
|
9443
|
+
}
|
|
9390
9444
|
async reconcileSessionManifest(sessionId) {
|
|
9391
9445
|
const session = await this.getSession(sessionId);
|
|
9392
9446
|
if (session === void 0) {
|
|
@@ -9802,16 +9856,37 @@ async function writePersistedSessionRecord(rootPath, record) {
|
|
|
9802
9856
|
async function clearPersistedSessionRecord(rootPath, provider) {
|
|
9803
9857
|
await promises.rm(resolveLiveSessionRecordPath(rootPath, provider), { force: true });
|
|
9804
9858
|
}
|
|
9859
|
+
function getPersistedLocalBrowserSessionOwnership(record) {
|
|
9860
|
+
return record.ownership === "attached" ? "attached" : "owned";
|
|
9861
|
+
}
|
|
9862
|
+
async function isAttachedLocalBrowserSessionReachable(record) {
|
|
9863
|
+
if (getPersistedLocalBrowserSessionOwnership(record) !== "attached") {
|
|
9864
|
+
return false;
|
|
9865
|
+
}
|
|
9866
|
+
if (record.engine !== "playwright" || record.endpoint === void 0) {
|
|
9867
|
+
return false;
|
|
9868
|
+
}
|
|
9869
|
+
try {
|
|
9870
|
+
await inspectCdpEndpoint({
|
|
9871
|
+
endpoint: record.endpoint,
|
|
9872
|
+
timeoutMs: 1500
|
|
9873
|
+
});
|
|
9874
|
+
return true;
|
|
9875
|
+
} catch {
|
|
9876
|
+
return false;
|
|
9877
|
+
}
|
|
9878
|
+
}
|
|
9805
9879
|
function isPersistedCloudSessionRecord(value) {
|
|
9806
|
-
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);
|
|
9880
|
+
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "cloud" && typeof value.sessionId === "string" && value.sessionId.length > 0 && (value.activePageUrl === void 0 || typeof value.activePageUrl === "string") && (value.activePageTitle === void 0 || typeof value.activePageTitle === "string") && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
|
|
9807
9881
|
}
|
|
9808
9882
|
function isPersistedLocalBrowserSessionRecord(value) {
|
|
9809
|
-
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;
|
|
9883
|
+
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") && (value.activePageUrl === void 0 || typeof value.activePageUrl === "string") && (value.activePageTitle === void 0 || typeof value.activePageTitle === "string") && 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;
|
|
9810
9884
|
}
|
|
9811
9885
|
var OPENSTEER_LIVE_SESSION_LAYOUT, OPENSTEER_LIVE_SESSION_VERSION;
|
|
9812
9886
|
var init_live_session = __esm({
|
|
9813
9887
|
"src/live-session.ts"() {
|
|
9814
9888
|
init_filesystem2();
|
|
9889
|
+
init_cdp_discovery();
|
|
9815
9890
|
OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
|
|
9816
9891
|
OPENSTEER_LIVE_SESSION_VERSION = 1;
|
|
9817
9892
|
}
|
|
@@ -10300,19 +10375,40 @@ var init_service = __esm({
|
|
|
10300
10375
|
}
|
|
10301
10376
|
});
|
|
10302
10377
|
function buildLocalViewSessionId(input) {
|
|
10378
|
+
const ownership = input.ownership ?? "owned";
|
|
10379
|
+
const identity = ownership === "attached" ? input.endpoint ?? input.remoteDebuggingUrl ?? input.baseUrl ?? "attached" : `pid:${String(input.pid ?? 0)}`;
|
|
10303
10380
|
const hash = crypto.createHash("sha256").update(`${input.rootPath}
|
|
10304
|
-
${
|
|
10381
|
+
${ownership}
|
|
10382
|
+
${identity}
|
|
10305
10383
|
${String(input.startedAt)}`).digest("hex");
|
|
10306
10384
|
return `local_${hash.slice(0, 24)}`;
|
|
10307
10385
|
}
|
|
10386
|
+
function buildLocalViewSessionIdForRecord(input) {
|
|
10387
|
+
const ownership = getPersistedLocalBrowserSessionOwnership(input.live);
|
|
10388
|
+
if (ownership === "attached") {
|
|
10389
|
+
return buildLocalViewSessionId({
|
|
10390
|
+
rootPath: input.rootPath,
|
|
10391
|
+
ownership,
|
|
10392
|
+
startedAt: input.live.startedAt,
|
|
10393
|
+
...input.live.endpoint === void 0 ? {} : { endpoint: input.live.endpoint },
|
|
10394
|
+
...input.live.baseUrl === void 0 ? {} : { baseUrl: input.live.baseUrl },
|
|
10395
|
+
...input.live.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: input.live.remoteDebuggingUrl }
|
|
10396
|
+
});
|
|
10397
|
+
}
|
|
10398
|
+
return buildLocalViewSessionId({
|
|
10399
|
+
rootPath: input.rootPath,
|
|
10400
|
+
ownership,
|
|
10401
|
+
startedAt: input.live.startedAt,
|
|
10402
|
+
pid: input.live.pid
|
|
10403
|
+
});
|
|
10404
|
+
}
|
|
10308
10405
|
function createLocalViewSessionManifest(input) {
|
|
10309
10406
|
return {
|
|
10310
10407
|
layout: OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT,
|
|
10311
10408
|
version: OPENSTEER_LOCAL_VIEW_SESSION_VERSION,
|
|
10312
|
-
sessionId:
|
|
10409
|
+
sessionId: buildLocalViewSessionIdForRecord({
|
|
10313
10410
|
rootPath: input.rootPath,
|
|
10314
|
-
|
|
10315
|
-
startedAt: input.live.startedAt
|
|
10411
|
+
live: input.live
|
|
10316
10412
|
}),
|
|
10317
10413
|
rootPath: input.rootPath,
|
|
10318
10414
|
...input.workspace === void 0 ? {} : { workspace: input.workspace },
|
|
@@ -10363,6 +10459,7 @@ var OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT, OPENSTEER_LOCAL_VIEW_SESSION_VERSION;
|
|
|
10363
10459
|
var init_session_manifest = __esm({
|
|
10364
10460
|
"src/local-view/session-manifest.ts"() {
|
|
10365
10461
|
init_filesystem2();
|
|
10462
|
+
init_live_session();
|
|
10366
10463
|
init_runtime_dir();
|
|
10367
10464
|
OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT = "opensteer-local-view-session";
|
|
10368
10465
|
OPENSTEER_LOCAL_VIEW_SESSION_VERSION = 1;
|
|
@@ -10531,6 +10628,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
10531
10628
|
version: 1,
|
|
10532
10629
|
provider: "local",
|
|
10533
10630
|
...workspace === void 0 ? {} : { workspace },
|
|
10631
|
+
ownership: live.ownership,
|
|
10534
10632
|
engine: live.engine,
|
|
10535
10633
|
...live.endpoint === void 0 ? {} : { endpoint: live.endpoint },
|
|
10536
10634
|
...live.baseUrl === void 0 ? {} : { baseUrl: live.baseUrl },
|
|
@@ -10546,6 +10644,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
10546
10644
|
function toWorkspaceLiveBrowserRecord(record) {
|
|
10547
10645
|
return {
|
|
10548
10646
|
mode: "persistent",
|
|
10647
|
+
ownership: getPersistedLocalBrowserSessionOwnership(record),
|
|
10549
10648
|
engine: record.engine,
|
|
10550
10649
|
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
10551
10650
|
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
@@ -10572,7 +10671,12 @@ function isAttachBrowserOptions(browser) {
|
|
|
10572
10671
|
async function resolveAttachEndpoint(browser) {
|
|
10573
10672
|
const endpoint = browser?.endpoint?.trim();
|
|
10574
10673
|
if (endpoint && endpoint.length > 0) {
|
|
10575
|
-
|
|
10674
|
+
const inspected = await inspectCdpEndpoint({
|
|
10675
|
+
endpoint,
|
|
10676
|
+
...browser?.headers === void 0 ? {} : { headers: browser.headers },
|
|
10677
|
+
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
10678
|
+
});
|
|
10679
|
+
return inspected.endpoint;
|
|
10576
10680
|
}
|
|
10577
10681
|
const selection = await selectAttachBrowserCandidate({
|
|
10578
10682
|
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
@@ -10998,7 +11102,7 @@ var init_browser_manager = __esm({
|
|
|
10998
11102
|
}
|
|
10999
11103
|
const liveRecord = await this.readLivePersistentBrowser(await this.ensureWorkspaceStore());
|
|
11000
11104
|
return {
|
|
11001
|
-
mode: this.mode,
|
|
11105
|
+
mode: liveRecord?.ownership === "attached" ? "attach" : this.mode,
|
|
11002
11106
|
engine: liveRecord?.engine ?? this.engineName,
|
|
11003
11107
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11004
11108
|
live: liveRecord !== void 0
|
|
@@ -11126,6 +11230,7 @@ var init_browser_manager = __esm({
|
|
|
11126
11230
|
});
|
|
11127
11231
|
const liveRecord = {
|
|
11128
11232
|
mode: "persistent",
|
|
11233
|
+
ownership: "owned",
|
|
11129
11234
|
engine: "abp",
|
|
11130
11235
|
baseUrl: launched.baseUrl,
|
|
11131
11236
|
remoteDebuggingUrl: launched.remoteDebuggingUrl,
|
|
@@ -11212,11 +11317,78 @@ var init_browser_manager = __esm({
|
|
|
11212
11317
|
}
|
|
11213
11318
|
async createAttachEngine() {
|
|
11214
11319
|
const endpoint = await resolveAttachEndpoint(this.browserOptions);
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11320
|
+
if (this.workspace === void 0) {
|
|
11321
|
+
return this.createAttachedEngine({
|
|
11322
|
+
endpoint,
|
|
11323
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
11324
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
11325
|
+
onDispose: async () => void 0
|
|
11326
|
+
});
|
|
11327
|
+
}
|
|
11328
|
+
const workspace = await this.ensureWorkspaceStore();
|
|
11329
|
+
return workspace.lock(async () => {
|
|
11330
|
+
const live = await this.readLivePersistentBrowser(workspace);
|
|
11331
|
+
if (live) {
|
|
11332
|
+
if (live.engine !== "playwright") {
|
|
11333
|
+
throw new Error(
|
|
11334
|
+
`workspace "${this.workspace}" already has a live ${live.engine} browser. Close it before attaching a Playwright browser.`
|
|
11335
|
+
);
|
|
11336
|
+
}
|
|
11337
|
+
if (live.ownership !== "attached") {
|
|
11338
|
+
throw new Error(
|
|
11339
|
+
`workspace "${this.workspace}" already has a live Opensteer-owned browser. Close it before attaching another browser.`
|
|
11340
|
+
);
|
|
11341
|
+
}
|
|
11342
|
+
if (live.endpoint === void 0) {
|
|
11343
|
+
throw new Error("workspace live browser record is missing a DevTools endpoint.");
|
|
11344
|
+
}
|
|
11345
|
+
if (live.endpoint !== endpoint) {
|
|
11346
|
+
throw new Error(
|
|
11347
|
+
`workspace "${this.workspace}" is already attached to a different browser endpoint. Close it before reattaching.`
|
|
11348
|
+
);
|
|
11349
|
+
}
|
|
11350
|
+
await bestEffortRegisterLocalViewSession({
|
|
11351
|
+
rootPath: workspace.rootPath,
|
|
11352
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11353
|
+
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
11354
|
+
ownership: "attached"
|
|
11355
|
+
});
|
|
11356
|
+
return this.createAttachedEngine({
|
|
11357
|
+
endpoint: live.endpoint,
|
|
11358
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
11359
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
11360
|
+
onDispose: async () => void 0
|
|
11361
|
+
});
|
|
11362
|
+
}
|
|
11363
|
+
const liveRecord = {
|
|
11364
|
+
mode: "persistent",
|
|
11365
|
+
ownership: "attached",
|
|
11366
|
+
engine: "playwright",
|
|
11367
|
+
endpoint,
|
|
11368
|
+
pid: 0,
|
|
11369
|
+
startedAt: Date.now(),
|
|
11370
|
+
userDataDir: workspace.browserUserDataDir
|
|
11371
|
+
};
|
|
11372
|
+
await this.writeLivePersistentBrowser(workspace, liveRecord);
|
|
11373
|
+
const persistedLiveRecord = toPersistedLocalBrowserSessionRecord(this.workspace, liveRecord);
|
|
11374
|
+
await bestEffortRegisterLocalViewSession({
|
|
11375
|
+
rootPath: workspace.rootPath,
|
|
11376
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11377
|
+
live: persistedLiveRecord,
|
|
11378
|
+
ownership: "attached"
|
|
11379
|
+
});
|
|
11380
|
+
try {
|
|
11381
|
+
return await this.createAttachedEngine({
|
|
11382
|
+
endpoint,
|
|
11383
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
11384
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
11385
|
+
onDispose: async () => void 0
|
|
11386
|
+
});
|
|
11387
|
+
} catch (error) {
|
|
11388
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
|
|
11389
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11390
|
+
throw error;
|
|
11391
|
+
}
|
|
11220
11392
|
});
|
|
11221
11393
|
}
|
|
11222
11394
|
async createPersistentEngine() {
|
|
@@ -11236,7 +11408,7 @@ var init_browser_manager = __esm({
|
|
|
11236
11408
|
rootPath: workspace.rootPath,
|
|
11237
11409
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
11238
11410
|
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
11239
|
-
ownership:
|
|
11411
|
+
ownership: live.ownership
|
|
11240
11412
|
});
|
|
11241
11413
|
return this.createAttachedEngine({
|
|
11242
11414
|
endpoint: live.endpoint,
|
|
@@ -11252,6 +11424,7 @@ var init_browser_manager = __esm({
|
|
|
11252
11424
|
});
|
|
11253
11425
|
const liveRecord = {
|
|
11254
11426
|
mode: "persistent",
|
|
11427
|
+
ownership: "owned",
|
|
11255
11428
|
engine: "playwright",
|
|
11256
11429
|
endpoint: launched.endpoint,
|
|
11257
11430
|
pid: launched.pid,
|
|
@@ -11381,7 +11554,20 @@ var init_browser_manager = __esm({
|
|
|
11381
11554
|
if (live === void 0) {
|
|
11382
11555
|
return void 0;
|
|
11383
11556
|
}
|
|
11557
|
+
if (live.ownership === "attached") {
|
|
11558
|
+
const attachedRecord = toPersistedLocalBrowserSessionRecord(this.workspace, live);
|
|
11559
|
+
if (!await isAttachedLocalBrowserSessionReachable(attachedRecord)) {
|
|
11560
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, attachedRecord);
|
|
11561
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11562
|
+
return void 0;
|
|
11563
|
+
}
|
|
11564
|
+
return live;
|
|
11565
|
+
}
|
|
11384
11566
|
if (!isProcessRunning(live.pid)) {
|
|
11567
|
+
await this.unregisterLocalViewSessionForRecord(
|
|
11568
|
+
workspace.rootPath,
|
|
11569
|
+
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
11570
|
+
);
|
|
11385
11571
|
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11386
11572
|
return void 0;
|
|
11387
11573
|
}
|
|
@@ -11429,6 +11615,10 @@ var init_browser_manager = __esm({
|
|
|
11429
11615
|
workspace.rootPath,
|
|
11430
11616
|
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
11431
11617
|
);
|
|
11618
|
+
if (live.ownership === "attached") {
|
|
11619
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
11620
|
+
return;
|
|
11621
|
+
}
|
|
11432
11622
|
if (live.engine === "playwright") {
|
|
11433
11623
|
if (live.endpoint !== void 0) {
|
|
11434
11624
|
await requestBrowserClose(live.endpoint).catch(() => void 0);
|
|
@@ -11457,10 +11647,18 @@ var init_browser_manager = __esm({
|
|
|
11457
11647
|
}
|
|
11458
11648
|
async unregisterLocalViewSessionForRecord(rootPath, record) {
|
|
11459
11649
|
await bestEffortUnregisterLocalViewSession(
|
|
11460
|
-
buildLocalViewSessionId({
|
|
11650
|
+
getPersistedLocalBrowserSessionOwnership(record) === "attached" ? buildLocalViewSessionId({
|
|
11651
|
+
rootPath,
|
|
11652
|
+
startedAt: record.startedAt,
|
|
11653
|
+
ownership: "attached",
|
|
11654
|
+
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
11655
|
+
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
11656
|
+
...record.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: record.remoteDebuggingUrl }
|
|
11657
|
+
}) : buildLocalViewSessionId({
|
|
11461
11658
|
rootPath,
|
|
11462
|
-
|
|
11463
|
-
|
|
11659
|
+
startedAt: record.startedAt,
|
|
11660
|
+
ownership: "owned",
|
|
11661
|
+
pid: record.pid
|
|
11464
11662
|
})
|
|
11465
11663
|
);
|
|
11466
11664
|
}
|
|
@@ -11961,11 +12159,11 @@ function delay2(ms) {
|
|
|
11961
12159
|
function wrapCloudFetchError(error, input) {
|
|
11962
12160
|
if (!(error instanceof Error)) {
|
|
11963
12161
|
return new Error(
|
|
11964
|
-
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check
|
|
12162
|
+
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check the configured Opensteer cloud base URL and network reachability from this environment.`
|
|
11965
12163
|
);
|
|
11966
12164
|
}
|
|
11967
12165
|
const wrapped = new Error(
|
|
11968
|
-
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check
|
|
12166
|
+
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check the configured Opensteer cloud base URL and network reachability from this environment.`,
|
|
11969
12167
|
{
|
|
11970
12168
|
cause: error
|
|
11971
12169
|
}
|
|
@@ -12240,34 +12438,40 @@ function resolveCloudConfig(input = {}) {
|
|
|
12240
12438
|
return void 0;
|
|
12241
12439
|
}
|
|
12242
12440
|
const cloudProvider = input.provider?.mode === "cloud" ? input.provider : void 0;
|
|
12243
|
-
const apiKey = cloudProvider?.apiKey ?? input.environment?.OPENSTEER_API_KEY;
|
|
12244
|
-
if (
|
|
12441
|
+
const apiKey = normalizeOptionalCloudConfigValue(cloudProvider?.apiKey) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_API_KEY);
|
|
12442
|
+
if (apiKey === void 0) {
|
|
12245
12443
|
throw new Error("provider=cloud requires OPENSTEER_API_KEY or provider.apiKey.");
|
|
12246
12444
|
}
|
|
12247
|
-
const baseUrl = cloudProvider?.baseUrl ?? input.environment?.OPENSTEER_BASE_URL;
|
|
12248
|
-
|
|
12249
|
-
throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
|
|
12250
|
-
}
|
|
12251
|
-
const appBaseUrl = cloudProvider?.appBaseUrl ?? input.environment?.OPENSTEER_CLOUD_APP_BASE_URL;
|
|
12445
|
+
const baseUrl = normalizeOptionalCloudConfigValue(cloudProvider?.baseUrl) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_BASE_URL) ?? DEFAULT_OPENSTEER_CLOUD_BASE_URL;
|
|
12446
|
+
const appBaseUrl = normalizeOptionalCloudConfigValue(cloudProvider?.appBaseUrl) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_CLOUD_APP_BASE_URL);
|
|
12252
12447
|
return {
|
|
12253
|
-
apiKey
|
|
12254
|
-
baseUrl
|
|
12255
|
-
...appBaseUrl === void 0
|
|
12448
|
+
apiKey,
|
|
12449
|
+
baseUrl,
|
|
12450
|
+
...appBaseUrl === void 0 ? {} : { appBaseUrl },
|
|
12256
12451
|
...cloudProvider?.browserProfile === void 0 ? {} : { browserProfile: cloudProvider.browserProfile }
|
|
12257
12452
|
};
|
|
12258
12453
|
}
|
|
12259
12454
|
function requireCloudAppBaseUrl(cloudConfig) {
|
|
12260
|
-
const appBaseUrl = cloudConfig.appBaseUrl;
|
|
12261
|
-
if (
|
|
12455
|
+
const appBaseUrl = normalizeOptionalCloudConfigValue(cloudConfig.appBaseUrl);
|
|
12456
|
+
if (appBaseUrl === void 0) {
|
|
12262
12457
|
throw new Error(
|
|
12263
12458
|
'record with provider=cloud requires OPENSTEER_CLOUD_APP_BASE_URL or "--cloud-app-base-url".'
|
|
12264
12459
|
);
|
|
12265
12460
|
}
|
|
12266
|
-
return appBaseUrl
|
|
12461
|
+
return appBaseUrl;
|
|
12462
|
+
}
|
|
12463
|
+
function normalizeOptionalCloudConfigValue(value) {
|
|
12464
|
+
if (typeof value !== "string") {
|
|
12465
|
+
return void 0;
|
|
12466
|
+
}
|
|
12467
|
+
const normalized = value.trim().replace(/\/+$/, "");
|
|
12468
|
+
return normalized.length === 0 ? void 0 : normalized;
|
|
12267
12469
|
}
|
|
12470
|
+
var DEFAULT_OPENSTEER_CLOUD_BASE_URL;
|
|
12268
12471
|
var init_config2 = __esm({
|
|
12269
12472
|
"src/cloud/config.ts"() {
|
|
12270
12473
|
init_config();
|
|
12474
|
+
DEFAULT_OPENSTEER_CLOUD_BASE_URL = "https://api.opensteer.com";
|
|
12271
12475
|
}
|
|
12272
12476
|
});
|
|
12273
12477
|
|
|
@@ -12277,7 +12481,7 @@ var init_package = __esm({
|
|
|
12277
12481
|
"../runtime-core/package.json"() {
|
|
12278
12482
|
package_default2 = {
|
|
12279
12483
|
name: "@opensteer/runtime-core",
|
|
12280
|
-
version: "0.2.
|
|
12484
|
+
version: "0.2.7",
|
|
12281
12485
|
description: "Shared semantic runtime for Opensteer local and cloud execution.",
|
|
12282
12486
|
license: "MIT",
|
|
12283
12487
|
type: "module",
|
|
@@ -12459,14 +12663,14 @@ var init_defaults = __esm({
|
|
|
12459
12663
|
snapshot: 0
|
|
12460
12664
|
};
|
|
12461
12665
|
DOM_ACTION_VISUAL_STABILITY_PROFILES = {
|
|
12462
|
-
"dom.click": { settleMs: 750, scope: "
|
|
12463
|
-
"dom.input": { settleMs: 750, scope: "
|
|
12464
|
-
"dom.scroll": { settleMs: 600, scope: "
|
|
12666
|
+
"dom.click": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
12667
|
+
"dom.input": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
12668
|
+
"dom.scroll": { settleMs: 600, scope: "main-frame", timeoutMs: 7e3 },
|
|
12465
12669
|
"dom.hover": { settleMs: 200, scope: "main-frame", timeoutMs: 2500 }
|
|
12466
12670
|
};
|
|
12467
12671
|
DEFAULT_DOM_ACTION_VISUAL_STABILITY_PROFILE = {
|
|
12468
12672
|
settleMs: 750,
|
|
12469
|
-
scope: "
|
|
12673
|
+
scope: "main-frame",
|
|
12470
12674
|
timeoutMs: 7e3
|
|
12471
12675
|
};
|
|
12472
12676
|
NAVIGATION_VISUAL_STABILITY_PROFILE = {
|
|
@@ -12490,6 +12694,7 @@ var init_defaults = __esm({
|
|
|
12490
12694
|
pageRef: input.pageRef,
|
|
12491
12695
|
timeoutMs: effectiveTimeout,
|
|
12492
12696
|
settleMs: profile.settleMs,
|
|
12697
|
+
...input.observedMutationQuietMs === void 0 ? {} : { initialQuietMs: input.observedMutationQuietMs },
|
|
12493
12698
|
scope: profile.scope
|
|
12494
12699
|
});
|
|
12495
12700
|
return true;
|
|
@@ -12510,15 +12715,20 @@ var init_defaults = __esm({
|
|
|
12510
12715
|
return false;
|
|
12511
12716
|
}
|
|
12512
12717
|
try {
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12718
|
+
let visualTimeout = effectiveTimeout;
|
|
12719
|
+
let initialQuietMs = input.observedMutationQuietMs ?? 0;
|
|
12720
|
+
if (!input.postLoadHandled) {
|
|
12721
|
+
const startedAt = Date.now();
|
|
12722
|
+
await input.engine.waitForPostLoadQuiet({
|
|
12723
|
+
pageRef: input.pageRef,
|
|
12724
|
+
timeoutMs: effectiveTimeout,
|
|
12725
|
+
quietMs: DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS,
|
|
12726
|
+
captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
|
|
12727
|
+
signal: input.signal
|
|
12728
|
+
});
|
|
12729
|
+
visualTimeout = Math.max(0, effectiveTimeout - (Date.now() - startedAt));
|
|
12730
|
+
initialQuietMs = Math.max(initialQuietMs, DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS);
|
|
12731
|
+
}
|
|
12522
12732
|
if (visualTimeout <= 0) {
|
|
12523
12733
|
return true;
|
|
12524
12734
|
}
|
|
@@ -12526,6 +12736,7 @@ var init_defaults = __esm({
|
|
|
12526
12736
|
pageRef: input.pageRef,
|
|
12527
12737
|
timeoutMs: visualTimeout,
|
|
12528
12738
|
settleMs: profile.settleMs,
|
|
12739
|
+
...initialQuietMs <= 0 ? {} : { initialQuietMs },
|
|
12529
12740
|
scope: profile.scope
|
|
12530
12741
|
});
|
|
12531
12742
|
return true;
|
|
@@ -13141,7 +13352,9 @@ function resolveExtractedValueInContext(normalizedValue, options) {
|
|
|
13141
13352
|
function stripPositionClauses(nodes) {
|
|
13142
13353
|
return (nodes || []).map((node) => ({
|
|
13143
13354
|
...node,
|
|
13144
|
-
match: (node.match || []).filter(
|
|
13355
|
+
match: (node.match || []).filter(
|
|
13356
|
+
(clause) => clause.kind !== "position" && clause.kind !== "text"
|
|
13357
|
+
)
|
|
13145
13358
|
}));
|
|
13146
13359
|
}
|
|
13147
13360
|
function dedupeSelectors(selectors) {
|
|
@@ -14693,7 +14906,7 @@ var init_executor = __esm({
|
|
|
14693
14906
|
...snapshot === void 0 ? {} : { snapshot },
|
|
14694
14907
|
signal: timeout.signal,
|
|
14695
14908
|
remainingMs: () => timeout.remainingMs(),
|
|
14696
|
-
policySettle: async (targetPageRef, trigger) => {
|
|
14909
|
+
policySettle: async (targetPageRef, trigger, boundary2) => {
|
|
14697
14910
|
try {
|
|
14698
14911
|
await settleWithPolicy(this.options.policy.settle, {
|
|
14699
14912
|
operation,
|
|
@@ -14701,7 +14914,9 @@ var init_executor = __esm({
|
|
|
14701
14914
|
engine: this.options.engine,
|
|
14702
14915
|
pageRef: targetPageRef,
|
|
14703
14916
|
signal: timeout.signal,
|
|
14704
|
-
remainingMs: timeout.remainingMs()
|
|
14917
|
+
remainingMs: timeout.remainingMs(),
|
|
14918
|
+
...boundary2?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary2.observedMutationQuietMs },
|
|
14919
|
+
...boundary2?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
14705
14920
|
});
|
|
14706
14921
|
} catch (error) {
|
|
14707
14922
|
if (snapshot !== void 0 && isSoftSettleTimeoutError(error, timeout.signal)) {
|
|
@@ -15448,7 +15663,9 @@ var init_runtime = __esm({
|
|
|
15448
15663
|
`Unable to resolve structural anchor "${buildPathSelectorHint(anchor)}" in the current session`
|
|
15449
15664
|
);
|
|
15450
15665
|
}
|
|
15451
|
-
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, {
|
|
15666
|
+
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, {
|
|
15667
|
+
enableTextMatch: true
|
|
15668
|
+
});
|
|
15452
15669
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
15453
15670
|
...persist === void 0 ? {} : { persist },
|
|
15454
15671
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -15959,12 +16176,16 @@ function toOpensteerResolvedTarget(target) {
|
|
|
15959
16176
|
documentRef: target.documentRef,
|
|
15960
16177
|
documentEpoch: target.documentEpoch,
|
|
15961
16178
|
nodeRef: target.nodeRef,
|
|
15962
|
-
tagName: target.node.nodeName
|
|
16179
|
+
tagName: toOpensteerTagName(target.node.nodeName),
|
|
15963
16180
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
15964
16181
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
15965
16182
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
15966
16183
|
};
|
|
15967
16184
|
}
|
|
16185
|
+
function toOpensteerTagName(nodeName) {
|
|
16186
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
16187
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
16188
|
+
}
|
|
15968
16189
|
var init_trace_enrichment = __esm({
|
|
15969
16190
|
"../runtime-core/src/runtimes/computer-use/trace-enrichment.ts"() {
|
|
15970
16191
|
init_src();
|
|
@@ -16020,7 +16241,7 @@ var init_runtime2 = __esm({
|
|
|
16020
16241
|
screenshot,
|
|
16021
16242
|
signal: input.timeout.signal,
|
|
16022
16243
|
remainingMs: () => input.timeout.remainingMs(),
|
|
16023
|
-
policySettle: async (pageRef, trigger) => {
|
|
16244
|
+
policySettle: async (pageRef, trigger, boundary) => {
|
|
16024
16245
|
try {
|
|
16025
16246
|
await settleWithPolicy(this.options.policy.settle, {
|
|
16026
16247
|
operation: "computer.execute",
|
|
@@ -16028,7 +16249,9 @@ var init_runtime2 = __esm({
|
|
|
16028
16249
|
engine: this.options.engine,
|
|
16029
16250
|
pageRef,
|
|
16030
16251
|
signal: input.timeout.signal,
|
|
16031
|
-
remainingMs: input.timeout.remainingMs()
|
|
16252
|
+
remainingMs: input.timeout.remainingMs(),
|
|
16253
|
+
...boundary?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary.observedMutationQuietMs },
|
|
16254
|
+
...boundary?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
16032
16255
|
});
|
|
16033
16256
|
} catch (error) {
|
|
16034
16257
|
if (pageRef === input.pageRef && isSoftSettleTimeoutError(error, input.timeout.signal)) {
|
|
@@ -17024,29 +17247,29 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
17024
17247
|
const keyStats = /* @__PURE__ */ new Map();
|
|
17025
17248
|
for (const descriptor of descriptors) {
|
|
17026
17249
|
for (const field of descriptor.fields) {
|
|
17027
|
-
const
|
|
17250
|
+
const stat3 = keyStats.get(field.path) ?? {
|
|
17028
17251
|
indices: /* @__PURE__ */ new Set(),
|
|
17029
17252
|
pathNodes: [],
|
|
17030
17253
|
attributes: [],
|
|
17031
17254
|
sources: []
|
|
17032
17255
|
};
|
|
17033
|
-
|
|
17256
|
+
stat3.indices.add(descriptor.index);
|
|
17034
17257
|
if (isPersistedOpensteerExtractionValueNode(field.node)) {
|
|
17035
|
-
|
|
17036
|
-
|
|
17258
|
+
stat3.pathNodes.push(field.node.$path);
|
|
17259
|
+
stat3.attributes.push(field.node.attribute);
|
|
17037
17260
|
} else if (isPersistedOpensteerExtractionSourceNode(field.node)) {
|
|
17038
|
-
|
|
17261
|
+
stat3.sources.push("current_url");
|
|
17039
17262
|
}
|
|
17040
|
-
keyStats.set(field.path,
|
|
17263
|
+
keyStats.set(field.path, stat3);
|
|
17041
17264
|
}
|
|
17042
17265
|
}
|
|
17043
17266
|
const mergedFields = [];
|
|
17044
|
-
for (const [fieldPath,
|
|
17045
|
-
if (
|
|
17267
|
+
for (const [fieldPath, stat3] of keyStats) {
|
|
17268
|
+
if (stat3.indices.size < threshold) {
|
|
17046
17269
|
continue;
|
|
17047
17270
|
}
|
|
17048
|
-
if (
|
|
17049
|
-
let mergedFieldPath =
|
|
17271
|
+
if (stat3.pathNodes.length >= threshold) {
|
|
17272
|
+
let mergedFieldPath = stat3.pathNodes.length === 1 ? sanitizeElementPath(stat3.pathNodes[0]) : mergeElementPathsByMajority(stat3.pathNodes);
|
|
17050
17273
|
if (!mergedFieldPath) {
|
|
17051
17274
|
continue;
|
|
17052
17275
|
}
|
|
@@ -17054,8 +17277,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
17054
17277
|
mergedFieldPath = relaxPathForSingleSample(mergedFieldPath, "field");
|
|
17055
17278
|
}
|
|
17056
17279
|
mergedFieldPath = minimizePathMatchClauses(mergedFieldPath, "field");
|
|
17057
|
-
const attrThreshold =
|
|
17058
|
-
const attribute = pickModeString(
|
|
17280
|
+
const attrThreshold = stat3.pathNodes.length === 1 ? 1 : majorityThreshold(stat3.pathNodes.length);
|
|
17281
|
+
const attribute = pickModeString(stat3.attributes, attrThreshold);
|
|
17059
17282
|
mergedFields.push({
|
|
17060
17283
|
path: fieldPath,
|
|
17061
17284
|
node: createValueNode({
|
|
@@ -17065,7 +17288,7 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
17065
17288
|
});
|
|
17066
17289
|
continue;
|
|
17067
17290
|
}
|
|
17068
|
-
const dominantSource = pickModeString(
|
|
17291
|
+
const dominantSource = pickModeString(stat3.sources, threshold);
|
|
17069
17292
|
if (dominantSource === "current_url") {
|
|
17070
17293
|
mergedFields.push({
|
|
17071
17294
|
path: fieldPath,
|
|
@@ -19173,28 +19396,24 @@ function restoreBoundedAttr(el, attr, value) {
|
|
|
19173
19396
|
}
|
|
19174
19397
|
setBoundedAttr(el, attr, value);
|
|
19175
19398
|
}
|
|
19176
|
-
function
|
|
19399
|
+
function deduplicateImagesInDom($) {
|
|
19177
19400
|
const seen = /* @__PURE__ */ new Set();
|
|
19178
|
-
|
|
19179
|
-
|
|
19180
|
-
|
|
19181
|
-
|
|
19182
|
-
const srcMatch = attrContent.match(/\bsrc\s*=\s*(["']?)(.*?)\1/);
|
|
19183
|
-
const srcsetMatch = attrContent.match(/\bsrcset\s*=\s*(["'])(.*?)\1/);
|
|
19184
|
-
let src = null;
|
|
19185
|
-
if (srcMatch && srcMatch[2]) {
|
|
19186
|
-
src = srcMatch[2].trim();
|
|
19187
|
-
} else if (srcsetMatch && srcsetMatch[2]) {
|
|
19188
|
-
src = srcsetMatch[2].split(",")[0]?.trim().split(" ")[0] ?? null;
|
|
19401
|
+
$("img").each(function deduplicateDomImage() {
|
|
19402
|
+
const el = $(this);
|
|
19403
|
+
if (el.attr("c") !== void 0) {
|
|
19404
|
+
return;
|
|
19189
19405
|
}
|
|
19406
|
+
const srcValue = el.attr("src")?.trim();
|
|
19407
|
+
const srcsetValue = el.attr("srcset");
|
|
19408
|
+
const src = srcValue && srcValue.length > 0 ? srcValue : srcsetValue?.split(",")[0]?.trim().split(/\s+/u)[0];
|
|
19190
19409
|
if (!src) {
|
|
19191
|
-
return
|
|
19410
|
+
return;
|
|
19192
19411
|
}
|
|
19193
19412
|
if (seen.has(src)) {
|
|
19194
|
-
|
|
19413
|
+
el.remove();
|
|
19414
|
+
return;
|
|
19195
19415
|
}
|
|
19196
19416
|
seen.add(src);
|
|
19197
|
-
return full;
|
|
19198
19417
|
});
|
|
19199
19418
|
}
|
|
19200
19419
|
function hasAttribute2(node, attr) {
|
|
@@ -19252,23 +19471,6 @@ function isPreservedImageElement(node) {
|
|
|
19252
19471
|
function getElementsInReverseDocumentOrder($) {
|
|
19253
19472
|
return $.root().find("*").toArray().reverse().filter((node) => node.type === "tag");
|
|
19254
19473
|
}
|
|
19255
|
-
function getNodeDepth(node) {
|
|
19256
|
-
let depth = 0;
|
|
19257
|
-
let current = node.parent;
|
|
19258
|
-
while (current) {
|
|
19259
|
-
depth++;
|
|
19260
|
-
current = current.parent;
|
|
19261
|
-
}
|
|
19262
|
-
return depth;
|
|
19263
|
-
}
|
|
19264
|
-
function getElementsByDepthDescending($) {
|
|
19265
|
-
const elements = $.root().find("*").toArray().filter((node) => node.type === "tag");
|
|
19266
|
-
const depths = /* @__PURE__ */ new Map();
|
|
19267
|
-
for (const el of elements) {
|
|
19268
|
-
depths.set(el, getNodeDepth(el));
|
|
19269
|
-
}
|
|
19270
|
-
return elements.sort((a, b) => (depths.get(b) ?? 0) - (depths.get(a) ?? 0));
|
|
19271
|
-
}
|
|
19272
19474
|
function flattenExtractionTree($) {
|
|
19273
19475
|
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
19274
19476
|
const el = $(node);
|
|
@@ -19286,19 +19488,6 @@ function flattenExtractionTree($) {
|
|
|
19286
19488
|
el.replaceWith(el.contents());
|
|
19287
19489
|
}
|
|
19288
19490
|
}
|
|
19289
|
-
function hasMarkedAncestor(el, attr) {
|
|
19290
|
-
let current = el[0]?.parent;
|
|
19291
|
-
while (current) {
|
|
19292
|
-
if (!isElementLikeNode(current)) {
|
|
19293
|
-
return false;
|
|
19294
|
-
}
|
|
19295
|
-
if (current.attribs?.[attr] !== void 0) {
|
|
19296
|
-
return true;
|
|
19297
|
-
}
|
|
19298
|
-
current = current.parent;
|
|
19299
|
-
}
|
|
19300
|
-
return false;
|
|
19301
|
-
}
|
|
19302
19491
|
function isIndicatorImage(node) {
|
|
19303
19492
|
return (node?.tagName || "").toLowerCase() === "img" && (hasAttribute2(node, "alt") || hasAttribute2(node, "src") || hasAttribute2(node, "srcset"));
|
|
19304
19493
|
}
|
|
@@ -19416,7 +19605,7 @@ function serializeForExtraction($, root) {
|
|
|
19416
19605
|
traverse(root, 0);
|
|
19417
19606
|
return lines.map((l) => l.trim()).filter((l) => l.length > 0).join("");
|
|
19418
19607
|
}
|
|
19419
|
-
function isClickable(
|
|
19608
|
+
function isClickable(el, context) {
|
|
19420
19609
|
if (context.hasPreMarked) {
|
|
19421
19610
|
return el.attr(OPENSTEER_INTERACTIVE_ATTR) !== void 0;
|
|
19422
19611
|
}
|
|
@@ -19450,21 +19639,17 @@ function isClickable($, el, context) {
|
|
|
19450
19639
|
}
|
|
19451
19640
|
return false;
|
|
19452
19641
|
}
|
|
19453
|
-
function
|
|
19642
|
+
function prepareExtractionSnapshotDom(html) {
|
|
19454
19643
|
if (!html.trim()) {
|
|
19455
|
-
return
|
|
19644
|
+
return void 0;
|
|
19456
19645
|
}
|
|
19457
19646
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
19458
19647
|
removeNoise($);
|
|
19459
19648
|
removeComments($);
|
|
19460
19649
|
markInlineSelfHiddenFallback($);
|
|
19461
19650
|
pruneSelfHiddenNodes($);
|
|
19462
|
-
|
|
19463
|
-
|
|
19464
|
-
{ xmlMode: false }
|
|
19465
|
-
);
|
|
19466
|
-
$clean("*").each(function stripAndRestoreExtractionAttrs() {
|
|
19467
|
-
const el = $clean(this);
|
|
19651
|
+
$("*").each(function stripAndRestoreExtractionAttrs() {
|
|
19652
|
+
const el = $(this);
|
|
19468
19653
|
const node = el[0];
|
|
19469
19654
|
if (!node) {
|
|
19470
19655
|
return;
|
|
@@ -19505,16 +19690,20 @@ function cleanForExtraction(html) {
|
|
|
19505
19690
|
restoreBoundedAttr(el, "href", hrefValue);
|
|
19506
19691
|
}
|
|
19507
19692
|
});
|
|
19508
|
-
flattenExtractionTree($
|
|
19509
|
-
|
|
19693
|
+
flattenExtractionTree($);
|
|
19694
|
+
deduplicateImagesInDom($);
|
|
19695
|
+
return $;
|
|
19696
|
+
}
|
|
19697
|
+
function serializePreparedExtractionSnapshot($) {
|
|
19698
|
+
const root = $.root()[0];
|
|
19510
19699
|
if (root === void 0) {
|
|
19511
19700
|
return "";
|
|
19512
19701
|
}
|
|
19513
|
-
return
|
|
19702
|
+
return serializeForExtraction($, root);
|
|
19514
19703
|
}
|
|
19515
|
-
function
|
|
19704
|
+
function prepareActionSnapshotDom(html) {
|
|
19516
19705
|
if (!html.trim()) {
|
|
19517
|
-
return
|
|
19706
|
+
return void 0;
|
|
19518
19707
|
}
|
|
19519
19708
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
19520
19709
|
removeNoise($);
|
|
@@ -19523,13 +19712,12 @@ function cleanForAction(html) {
|
|
|
19523
19712
|
pruneSelfHiddenNodes($);
|
|
19524
19713
|
const clickableMark = "data-clickable-marker";
|
|
19525
19714
|
const indicatorMark = "data-keep-indicator";
|
|
19526
|
-
const branchMark = "data-keep-branch";
|
|
19527
19715
|
const context = {
|
|
19528
19716
|
hasPreMarked: $(`[${OPENSTEER_INTERACTIVE_ATTR}]`).length > 0
|
|
19529
19717
|
};
|
|
19530
19718
|
$("*").each(function markClickables() {
|
|
19531
19719
|
const el = $(this);
|
|
19532
|
-
if (isClickable(
|
|
19720
|
+
if (isClickable(el, context)) {
|
|
19533
19721
|
el.attr(clickableMark, "1");
|
|
19534
19722
|
}
|
|
19535
19723
|
});
|
|
@@ -19559,25 +19747,7 @@ function cleanForAction(html) {
|
|
|
19559
19747
|
el.remove();
|
|
19560
19748
|
}
|
|
19561
19749
|
});
|
|
19562
|
-
|
|
19563
|
-
let current = $(this).parent();
|
|
19564
|
-
while (current.length > 0) {
|
|
19565
|
-
const node = current[0];
|
|
19566
|
-
if (!node || node.type !== "tag") {
|
|
19567
|
-
break;
|
|
19568
|
-
}
|
|
19569
|
-
const ancestor = current;
|
|
19570
|
-
const tag = (node.tagName || "").toLowerCase();
|
|
19571
|
-
if (ROOT_TAGS.has(tag) || ancestor.attr(clickableMark) !== void 0) {
|
|
19572
|
-
break;
|
|
19573
|
-
}
|
|
19574
|
-
if (!isBoundaryTag(tag)) {
|
|
19575
|
-
ancestor.attr(branchMark, "1");
|
|
19576
|
-
}
|
|
19577
|
-
current = ancestor.parent();
|
|
19578
|
-
}
|
|
19579
|
-
});
|
|
19580
|
-
for (const node of getElementsByDepthDescending($)) {
|
|
19750
|
+
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
19581
19751
|
const el = $(node);
|
|
19582
19752
|
const tag = (node.tagName || "").toLowerCase();
|
|
19583
19753
|
if (ROOT_TAGS.has(tag) || isBoundaryTag(tag)) {
|
|
@@ -19586,17 +19756,7 @@ function cleanForAction(html) {
|
|
|
19586
19756
|
if (el.attr(clickableMark) !== void 0 || el.attr(indicatorMark) !== void 0) {
|
|
19587
19757
|
continue;
|
|
19588
19758
|
}
|
|
19589
|
-
const insideClickable = hasMarkedAncestor(el, clickableMark);
|
|
19590
|
-
const preserveBranch = el.attr(branchMark) !== void 0;
|
|
19591
19759
|
const hasContent = hasElementChildren(node) || hasDirectText(node);
|
|
19592
|
-
if (insideClickable || preserveBranch) {
|
|
19593
|
-
if (!hasContent) {
|
|
19594
|
-
el.remove();
|
|
19595
|
-
} else {
|
|
19596
|
-
unwrapActionNode($, el);
|
|
19597
|
-
}
|
|
19598
|
-
continue;
|
|
19599
|
-
}
|
|
19600
19760
|
if (!hasContent) {
|
|
19601
19761
|
el.remove();
|
|
19602
19762
|
continue;
|
|
@@ -19697,13 +19857,20 @@ function cleanForAction(html) {
|
|
|
19697
19857
|
}
|
|
19698
19858
|
el.removeAttr(clickableMark);
|
|
19699
19859
|
el.removeAttr(indicatorMark);
|
|
19700
|
-
el.removeAttr(branchMark);
|
|
19701
19860
|
el.removeAttr(OPENSTEER_INTERACTIVE_ATTR);
|
|
19702
19861
|
el.removeAttr(OPENSTEER_HIDDEN_ATTR);
|
|
19703
19862
|
el.removeAttr(OPENSTEER_SCROLLABLE_ATTR);
|
|
19704
19863
|
el.removeAttr(OPENSTEER_SELF_HIDDEN_ATTR);
|
|
19705
19864
|
});
|
|
19706
|
-
|
|
19865
|
+
deduplicateImagesInDom($);
|
|
19866
|
+
return $;
|
|
19867
|
+
}
|
|
19868
|
+
function serializePreparedActionSnapshot($) {
|
|
19869
|
+
const normalized = compactHtml($.html());
|
|
19870
|
+
if (normalized.length === 0) {
|
|
19871
|
+
return "";
|
|
19872
|
+
}
|
|
19873
|
+
return cheerio__namespace.load(normalized, { xmlMode: false }).html();
|
|
19707
19874
|
}
|
|
19708
19875
|
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;
|
|
19709
19876
|
var init_cleaner = __esm({
|
|
@@ -19764,23 +19931,27 @@ async function markLiveSnapshotSemantics(options) {
|
|
|
19764
19931
|
const frames = await options.engine.listFrames({
|
|
19765
19932
|
pageRef: options.pageRef
|
|
19766
19933
|
});
|
|
19767
|
-
|
|
19768
|
-
|
|
19769
|
-
|
|
19770
|
-
frame.frameRef,
|
|
19771
|
-
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
19772
|
-
SNAPSHOT_SEMANTIC_ARGS
|
|
19773
|
-
);
|
|
19774
|
-
}
|
|
19775
|
-
return async () => {
|
|
19776
|
-
for (const frame of frames) {
|
|
19777
|
-
await evaluateFrameBestEffort(
|
|
19934
|
+
await Promise.all(
|
|
19935
|
+
frames.map(
|
|
19936
|
+
(frame) => evaluateFrameBestEffort(
|
|
19778
19937
|
options.engine,
|
|
19779
19938
|
frame.frameRef,
|
|
19780
|
-
|
|
19781
|
-
|
|
19782
|
-
)
|
|
19783
|
-
|
|
19939
|
+
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
19940
|
+
SNAPSHOT_SEMANTIC_ARGS
|
|
19941
|
+
)
|
|
19942
|
+
)
|
|
19943
|
+
);
|
|
19944
|
+
return async () => {
|
|
19945
|
+
await Promise.all(
|
|
19946
|
+
frames.map(
|
|
19947
|
+
(frame) => evaluateFrameBestEffort(
|
|
19948
|
+
options.engine,
|
|
19949
|
+
frame.frameRef,
|
|
19950
|
+
CLEAR_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
19951
|
+
CLEAR_SNAPSHOT_SEMANTIC_ARGS
|
|
19952
|
+
)
|
|
19953
|
+
)
|
|
19954
|
+
);
|
|
19784
19955
|
};
|
|
19785
19956
|
}
|
|
19786
19957
|
var MARK_SNAPSHOT_SEMANTICS_SCRIPT, CLEAR_SNAPSHOT_SEMANTICS_SCRIPT, SNAPSHOT_SEMANTIC_ARGS, CLEAR_SNAPSHOT_SEMANTIC_ARGS;
|
|
@@ -19978,6 +20149,8 @@ var init_marking = __esm({
|
|
|
19978
20149
|
];
|
|
19979
20150
|
}
|
|
19980
20151
|
});
|
|
20152
|
+
|
|
20153
|
+
// ../runtime-core/src/sdk/snapshot/compiler.ts
|
|
19981
20154
|
function isLiveCounterSyncError(error) {
|
|
19982
20155
|
return error instanceof LiveCounterSyncError;
|
|
19983
20156
|
}
|
|
@@ -20015,20 +20188,22 @@ function ensureSparseCountersForAllRecords(counterRecords) {
|
|
|
20015
20188
|
async function clearOpensteerLiveCounters(engine, pageRef) {
|
|
20016
20189
|
const frames = await engine.listFrames({ pageRef });
|
|
20017
20190
|
const failures = [];
|
|
20018
|
-
|
|
20019
|
-
|
|
20020
|
-
|
|
20021
|
-
|
|
20022
|
-
|
|
20023
|
-
|
|
20024
|
-
|
|
20025
|
-
|
|
20026
|
-
|
|
20027
|
-
|
|
20191
|
+
await Promise.all(
|
|
20192
|
+
frames.map(async (frame) => {
|
|
20193
|
+
try {
|
|
20194
|
+
await engine.evaluateFrame({
|
|
20195
|
+
frameRef: frame.frameRef,
|
|
20196
|
+
script: CLEAR_LIVE_COUNTERS_SCRIPT,
|
|
20197
|
+
args: [{ sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR }]
|
|
20198
|
+
});
|
|
20199
|
+
} catch (error) {
|
|
20200
|
+
if (isDetachedFrameSyncError(error)) {
|
|
20201
|
+
return;
|
|
20202
|
+
}
|
|
20203
|
+
failures.push(`frame ${frame.frameRef} could not be cleared (${describeError(error)}).`);
|
|
20028
20204
|
}
|
|
20029
|
-
|
|
20030
|
-
|
|
20031
|
-
}
|
|
20205
|
+
})
|
|
20206
|
+
);
|
|
20032
20207
|
if (failures.length > 0) {
|
|
20033
20208
|
throw buildLiveCounterSyncError("clear live counters", failures);
|
|
20034
20209
|
}
|
|
@@ -20077,25 +20252,29 @@ async function syncDenseCountersToLiveDom(engine, pageRef, sparseToDirectMapping
|
|
|
20077
20252
|
denseCounter
|
|
20078
20253
|
])
|
|
20079
20254
|
);
|
|
20080
|
-
|
|
20081
|
-
|
|
20082
|
-
|
|
20083
|
-
|
|
20084
|
-
|
|
20085
|
-
|
|
20086
|
-
|
|
20087
|
-
|
|
20088
|
-
|
|
20089
|
-
|
|
20090
|
-
|
|
20091
|
-
|
|
20092
|
-
|
|
20093
|
-
|
|
20094
|
-
|
|
20255
|
+
await Promise.all(
|
|
20256
|
+
frames.map(async (frame) => {
|
|
20257
|
+
try {
|
|
20258
|
+
await engine.evaluateFrame({
|
|
20259
|
+
frameRef: frame.frameRef,
|
|
20260
|
+
script: APPLY_DENSE_COUNTERS_SCRIPT,
|
|
20261
|
+
args: [
|
|
20262
|
+
{
|
|
20263
|
+
sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR,
|
|
20264
|
+
mapping: mappingObj
|
|
20265
|
+
}
|
|
20266
|
+
]
|
|
20267
|
+
});
|
|
20268
|
+
} catch (error) {
|
|
20269
|
+
if (isDetachedFrameSyncError(error)) {
|
|
20270
|
+
return;
|
|
20271
|
+
}
|
|
20272
|
+
failures.push(
|
|
20273
|
+
`frame ${frame.frameRef} could not be synchronized (${describeError(error)}).`
|
|
20274
|
+
);
|
|
20095
20275
|
}
|
|
20096
|
-
|
|
20097
|
-
|
|
20098
|
-
}
|
|
20276
|
+
})
|
|
20277
|
+
);
|
|
20099
20278
|
if (failures.length > 0) {
|
|
20100
20279
|
throw buildLiveCounterSyncError("synchronize dense counters", failures);
|
|
20101
20280
|
}
|
|
@@ -20113,26 +20292,26 @@ async function compileOpensteerSnapshot(options) {
|
|
|
20113
20292
|
await clearOpensteerLiveCounters(options.engine, options.pageRef);
|
|
20114
20293
|
await assignSparseCountersToLiveDom(options.engine, options.pageRef);
|
|
20115
20294
|
const pageInfo = await options.engine.getPageInfo({ pageRef: options.pageRef });
|
|
20116
|
-
const mainSnapshot = await
|
|
20117
|
-
|
|
20295
|
+
const { mainSnapshot, snapshotsByDocumentRef } = await getPageDocumentSnapshots(
|
|
20296
|
+
options.engine,
|
|
20297
|
+
options.pageRef
|
|
20298
|
+
);
|
|
20118
20299
|
await cleanupLiveSemantics();
|
|
20119
20300
|
cleanupLiveSemantics = async () => {
|
|
20120
20301
|
};
|
|
20121
|
-
const snapshotIndices = /* @__PURE__ */ new Map();
|
|
20122
20302
|
const renderedNodes = /* @__PURE__ */ new Map();
|
|
20123
20303
|
const rawHtml = renderDocumentSnapshot(
|
|
20124
20304
|
mainSnapshot.documentRef,
|
|
20125
20305
|
snapshotsByDocumentRef,
|
|
20126
|
-
snapshotIndices,
|
|
20127
20306
|
renderedNodes,
|
|
20128
20307
|
{
|
|
20129
20308
|
iframeDepth: 0,
|
|
20130
20309
|
shadowDepth: 0
|
|
20131
20310
|
}
|
|
20132
20311
|
);
|
|
20133
|
-
const
|
|
20134
|
-
const compiledHtml =
|
|
20135
|
-
const finalHtml = options.mode === "extraction" ?
|
|
20312
|
+
const preparedSnapshotDom = options.mode === "extraction" ? prepareExtractionSnapshotDom(rawHtml) : prepareActionSnapshotDom(rawHtml);
|
|
20313
|
+
const compiledHtml = assignCountersInDom(preparedSnapshotDom, renderedNodes, options.mode);
|
|
20314
|
+
const finalHtml = preparedSnapshotDom === void 0 ? "" : options.mode === "extraction" ? serializePreparedExtractionSnapshot(preparedSnapshotDom) : serializePreparedActionSnapshot(preparedSnapshotDom);
|
|
20136
20315
|
ensureSparseCountersForAllRecords(compiledHtml.counterRecords);
|
|
20137
20316
|
await syncDenseCountersToLiveDom(
|
|
20138
20317
|
options.engine,
|
|
@@ -20167,6 +20346,25 @@ async function getMainDocumentSnapshot(engine, pageRef) {
|
|
|
20167
20346
|
}
|
|
20168
20347
|
return engine.getDomSnapshot({ frameRef: mainFrame.frameRef });
|
|
20169
20348
|
}
|
|
20349
|
+
async function getPageDocumentSnapshots(engine, pageRef) {
|
|
20350
|
+
const bundleEngine = engine;
|
|
20351
|
+
const bundledSnapshots = await bundleEngine.getPageDomSnapshots?.({ pageRef });
|
|
20352
|
+
if (bundledSnapshots && bundledSnapshots.length > 0) {
|
|
20353
|
+
const mainSnapshot2 = bundledSnapshots.find((snapshot) => snapshot.parentDocumentRef === void 0) ?? bundledSnapshots[0];
|
|
20354
|
+
return {
|
|
20355
|
+
mainSnapshot: mainSnapshot2,
|
|
20356
|
+
snapshotsByDocumentRef: new Map(
|
|
20357
|
+
bundledSnapshots.map((snapshot) => [snapshot.documentRef, snapshot])
|
|
20358
|
+
)
|
|
20359
|
+
};
|
|
20360
|
+
}
|
|
20361
|
+
const mainSnapshot = await getMainDocumentSnapshot(engine, pageRef);
|
|
20362
|
+
const snapshotsByDocumentRef = await collectDocumentSnapshots(engine, mainSnapshot);
|
|
20363
|
+
return {
|
|
20364
|
+
mainSnapshot,
|
|
20365
|
+
snapshotsByDocumentRef
|
|
20366
|
+
};
|
|
20367
|
+
}
|
|
20170
20368
|
async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
20171
20369
|
const snapshotsByDocumentRef = /* @__PURE__ */ new Map([
|
|
20172
20370
|
[mainSnapshot.documentRef, mainSnapshot]
|
|
@@ -20185,7 +20383,7 @@ async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
|
20185
20383
|
}
|
|
20186
20384
|
return snapshotsByDocumentRef;
|
|
20187
20385
|
}
|
|
20188
|
-
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef,
|
|
20386
|
+
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
20189
20387
|
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
20190
20388
|
if (!snapshot) {
|
|
20191
20389
|
return "";
|
|
@@ -20197,17 +20395,9 @@ function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, snapshotInd
|
|
|
20197
20395
|
`snapshot ${snapshot.documentRef} is missing root node ${String(snapshot.rootSnapshotNodeId)}`
|
|
20198
20396
|
);
|
|
20199
20397
|
}
|
|
20200
|
-
return renderNode(
|
|
20201
|
-
snapshot,
|
|
20202
|
-
rootNode,
|
|
20203
|
-
nodesById,
|
|
20204
|
-
snapshotsByDocumentRef,
|
|
20205
|
-
snapshotIndices,
|
|
20206
|
-
renderedNodes,
|
|
20207
|
-
depth
|
|
20208
|
-
);
|
|
20398
|
+
return renderNode(snapshot, rootNode, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20209
20399
|
}
|
|
20210
|
-
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
20400
|
+
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
20211
20401
|
if (node.nodeType === 3) {
|
|
20212
20402
|
return escapeHtml(node.nodeValue || node.textContent || "");
|
|
20213
20403
|
}
|
|
@@ -20215,56 +20405,26 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20215
20405
|
return "";
|
|
20216
20406
|
}
|
|
20217
20407
|
if (node.nodeType === 9 || node.nodeType === 11) {
|
|
20218
|
-
return renderChildren(
|
|
20219
|
-
snapshot,
|
|
20220
|
-
node,
|
|
20221
|
-
nodesById,
|
|
20222
|
-
snapshotsByDocumentRef,
|
|
20223
|
-
snapshotIndices,
|
|
20224
|
-
renderedNodes,
|
|
20225
|
-
depth
|
|
20226
|
-
);
|
|
20408
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20227
20409
|
}
|
|
20228
20410
|
if (node.nodeType !== 1) {
|
|
20229
|
-
return renderChildren(
|
|
20230
|
-
snapshot,
|
|
20231
|
-
node,
|
|
20232
|
-
nodesById,
|
|
20233
|
-
snapshotsByDocumentRef,
|
|
20234
|
-
snapshotIndices,
|
|
20235
|
-
renderedNodes,
|
|
20236
|
-
depth
|
|
20237
|
-
);
|
|
20411
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20238
20412
|
}
|
|
20239
20413
|
const tagName = normalizeTagName(node.nodeName);
|
|
20240
20414
|
if (isPseudoElementTagName(tagName)) {
|
|
20241
|
-
return renderChildren(
|
|
20242
|
-
snapshot,
|
|
20243
|
-
node,
|
|
20244
|
-
nodesById,
|
|
20245
|
-
snapshotsByDocumentRef,
|
|
20246
|
-
snapshotIndices,
|
|
20247
|
-
renderedNodes,
|
|
20248
|
-
depth
|
|
20249
|
-
);
|
|
20415
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20250
20416
|
}
|
|
20251
20417
|
if ((depth.iframeDepth > 0 || depth.shadowDepth > 0) && (tagName === "html" || tagName === "head" || tagName === "body")) {
|
|
20252
|
-
return renderChildren(
|
|
20253
|
-
snapshot,
|
|
20254
|
-
node,
|
|
20255
|
-
nodesById,
|
|
20256
|
-
snapshotsByDocumentRef,
|
|
20257
|
-
snapshotIndices,
|
|
20258
|
-
renderedNodes,
|
|
20259
|
-
depth
|
|
20260
|
-
);
|
|
20418
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
20261
20419
|
}
|
|
20262
20420
|
const snapshotAttributes = normalizeNodeAttributes(node.attributes);
|
|
20421
|
+
const snapshotAttributeIndex = indexNodeAttributes(snapshotAttributes);
|
|
20263
20422
|
const authoredAttributes = stripInternalSnapshotAttributes(snapshotAttributes);
|
|
20423
|
+
const authoredAttributeIndex = indexNodeAttributes(authoredAttributes);
|
|
20264
20424
|
const attributes = [...authoredAttributes];
|
|
20265
|
-
const subtreeHidden =
|
|
20266
|
-
const selfHidden = !subtreeHidden && (
|
|
20267
|
-
const interactive = !subtreeHidden && !selfHidden && (
|
|
20425
|
+
const subtreeHidden = snapshotAttributeIndex.has(OPENSTEER_HIDDEN_ATTR) || isLikelySubtreeHidden(node);
|
|
20426
|
+
const selfHidden = !subtreeHidden && (snapshotAttributeIndex.has(OPENSTEER_SELF_HIDDEN_ATTR) || isLikelySelfHidden(node, nodesById));
|
|
20427
|
+
const interactive = !subtreeHidden && !selfHidden && (snapshotAttributeIndex.has(OPENSTEER_INTERACTIVE_ATTR) || isLikelyInteractive(tagName, node, authoredAttributes, authoredAttributeIndex));
|
|
20268
20428
|
if (interactive) {
|
|
20269
20429
|
attributes.push({ name: OPENSTEER_INTERACTIVE_ATTR, value: "1" });
|
|
20270
20430
|
}
|
|
@@ -20273,7 +20433,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20273
20433
|
} else if (selfHidden) {
|
|
20274
20434
|
attributes.push({ name: OPENSTEER_SELF_HIDDEN_ATTR, value: "1" });
|
|
20275
20435
|
}
|
|
20276
|
-
const sparseCounter =
|
|
20436
|
+
const sparseCounter = snapshotAttributeIndex.get(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20277
20437
|
if (sparseCounter !== void 0) {
|
|
20278
20438
|
attributes.push({ name: OPENSTEER_SPARSE_COUNTER_ATTR, value: sparseCounter });
|
|
20279
20439
|
}
|
|
@@ -20284,21 +20444,18 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20284
20444
|
const syntheticNodeId = buildSyntheticNodeId(snapshot, node);
|
|
20285
20445
|
attributes.push({ name: OPENSTEER_NODE_ID_ATTR, value: syntheticNodeId });
|
|
20286
20446
|
renderedNodes.set(syntheticNodeId, {
|
|
20287
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
20288
|
-
anchor: buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices),
|
|
20289
20447
|
pageRef: snapshot.pageRef,
|
|
20290
20448
|
frameRef: snapshot.frameRef,
|
|
20291
20449
|
documentRef: snapshot.documentRef,
|
|
20292
20450
|
documentEpoch: snapshot.documentEpoch,
|
|
20293
20451
|
nodeRef: node.nodeRef,
|
|
20294
20452
|
tagName: tagName.toUpperCase(),
|
|
20295
|
-
pathHint: buildPathHint(tagName, authoredAttributes),
|
|
20296
|
-
...buildTextSnippet(node.textContent) === void 0 ? {} : { text: buildTextSnippet(node.textContent) },
|
|
20297
20453
|
...authoredAttributes.length === 0 ? {} : { attributes: authoredAttributes },
|
|
20298
20454
|
iframeDepth: depth.iframeDepth,
|
|
20299
20455
|
shadowDepth: depth.shadowDepth,
|
|
20300
20456
|
interactive,
|
|
20301
|
-
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById)
|
|
20457
|
+
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById),
|
|
20458
|
+
...node.textContent === void 0 ? {} : { textContent: node.textContent }
|
|
20302
20459
|
});
|
|
20303
20460
|
}
|
|
20304
20461
|
const attributeText = attributesToHtml(attributes);
|
|
@@ -20307,7 +20464,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20307
20464
|
node,
|
|
20308
20465
|
nodesById,
|
|
20309
20466
|
snapshotsByDocumentRef,
|
|
20310
|
-
snapshotIndices,
|
|
20311
20467
|
renderedNodes,
|
|
20312
20468
|
depth
|
|
20313
20469
|
);
|
|
@@ -20318,7 +20474,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20318
20474
|
const iframeHtml = renderDocumentSnapshot(
|
|
20319
20475
|
node.contentDocumentRef,
|
|
20320
20476
|
snapshotsByDocumentRef,
|
|
20321
|
-
snapshotIndices,
|
|
20322
20477
|
renderedNodes,
|
|
20323
20478
|
{
|
|
20324
20479
|
iframeDepth: depth.iframeDepth + 1,
|
|
@@ -20330,7 +20485,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
20330
20485
|
}
|
|
20331
20486
|
return `${elementHtml}<${OPENSTEER_IFRAME_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="iframe">${iframeHtml}</${OPENSTEER_IFRAME_BOUNDARY_TAG}>`;
|
|
20332
20487
|
}
|
|
20333
|
-
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
20488
|
+
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
20334
20489
|
const regularChildren = [];
|
|
20335
20490
|
const shadowChildren = [];
|
|
20336
20491
|
for (const childSnapshotNodeId of node.childSnapshotNodeIds) {
|
|
@@ -20347,18 +20502,10 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
20347
20502
|
const chunks = [];
|
|
20348
20503
|
if (shadowChildren.length > 0) {
|
|
20349
20504
|
const shadowHtml = shadowChildren.map(
|
|
20350
|
-
(child) => renderNode(
|
|
20351
|
-
|
|
20352
|
-
|
|
20353
|
-
|
|
20354
|
-
snapshotsByDocumentRef,
|
|
20355
|
-
snapshotIndices,
|
|
20356
|
-
renderedNodes,
|
|
20357
|
-
{
|
|
20358
|
-
iframeDepth: depth.iframeDepth,
|
|
20359
|
-
shadowDepth: depth.shadowDepth + 1
|
|
20360
|
-
}
|
|
20361
|
-
)
|
|
20505
|
+
(child) => renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, {
|
|
20506
|
+
iframeDepth: depth.iframeDepth,
|
|
20507
|
+
shadowDepth: depth.shadowDepth + 1
|
|
20508
|
+
})
|
|
20362
20509
|
).join("");
|
|
20363
20510
|
chunks.push(
|
|
20364
20511
|
`<${OPENSTEER_SHADOW_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="shadow">${shadowHtml}</${OPENSTEER_SHADOW_BOUNDARY_TAG}>`
|
|
@@ -20366,24 +20513,21 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
20366
20513
|
}
|
|
20367
20514
|
for (const child of regularChildren) {
|
|
20368
20515
|
chunks.push(
|
|
20369
|
-
renderNode(
|
|
20370
|
-
snapshot,
|
|
20371
|
-
child,
|
|
20372
|
-
nodesById,
|
|
20373
|
-
snapshotsByDocumentRef,
|
|
20374
|
-
snapshotIndices,
|
|
20375
|
-
renderedNodes,
|
|
20376
|
-
depth
|
|
20377
|
-
)
|
|
20516
|
+
renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, depth)
|
|
20378
20517
|
);
|
|
20379
20518
|
}
|
|
20380
20519
|
return chunks.join("");
|
|
20381
20520
|
}
|
|
20382
|
-
function
|
|
20383
|
-
const $ = cheerio__namespace.load(cleanedHtml, { xmlMode: false });
|
|
20521
|
+
function assignCountersInDom($, renderedNodes, mode) {
|
|
20384
20522
|
const counterRecords = /* @__PURE__ */ new Map();
|
|
20385
20523
|
const sparseToDirectMapping = /* @__PURE__ */ new Map();
|
|
20386
20524
|
let nextCounter = 1;
|
|
20525
|
+
if (!$) {
|
|
20526
|
+
return {
|
|
20527
|
+
counterRecords,
|
|
20528
|
+
sparseToDirectMapping
|
|
20529
|
+
};
|
|
20530
|
+
}
|
|
20387
20531
|
$("*").each(function assignElementCounter() {
|
|
20388
20532
|
const el = $(this);
|
|
20389
20533
|
const syntheticNodeId = el.attr(OPENSTEER_NODE_ID_ATTR);
|
|
@@ -20395,14 +20539,24 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
20395
20539
|
if (!rendered) {
|
|
20396
20540
|
return;
|
|
20397
20541
|
}
|
|
20542
|
+
if (mode === "extraction" && EXTRACTION_SKIPPED_COUNTER_TAGS.has(rendered.tagName.toLowerCase())) {
|
|
20543
|
+
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20544
|
+
return;
|
|
20545
|
+
}
|
|
20398
20546
|
const rawSparseCounter = el.attr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20399
20547
|
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
20400
20548
|
const sparseCounter = rawSparseCounter ? Number.parseInt(rawSparseCounter, 10) : void 0;
|
|
20549
|
+
const replayableSparseCounter = typeof sparseCounter === "number" && Number.isFinite(sparseCounter) ? sparseCounter : void 0;
|
|
20550
|
+
if (rendered.liveCounterSyncEligible && replayableSparseCounter === void 0) {
|
|
20551
|
+
return;
|
|
20552
|
+
}
|
|
20401
20553
|
const counter = nextCounter++;
|
|
20402
20554
|
el.attr("c", String(counter));
|
|
20403
|
-
if (
|
|
20404
|
-
sparseToDirectMapping.set(
|
|
20555
|
+
if (replayableSparseCounter !== void 0) {
|
|
20556
|
+
sparseToDirectMapping.set(replayableSparseCounter, counter);
|
|
20405
20557
|
}
|
|
20558
|
+
const pathHint = buildPathHint(rendered.tagName.toLowerCase(), rendered.attributes ?? []);
|
|
20559
|
+
const text = buildTextSnippet(rendered.textContent);
|
|
20406
20560
|
counterRecords.set(counter, {
|
|
20407
20561
|
element: counter,
|
|
20408
20562
|
pageRef: rendered.pageRef,
|
|
@@ -20411,20 +20565,17 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
20411
20565
|
documentEpoch: rendered.documentEpoch,
|
|
20412
20566
|
nodeRef: rendered.nodeRef,
|
|
20413
20567
|
tagName: rendered.tagName,
|
|
20414
|
-
pathHint
|
|
20415
|
-
...
|
|
20568
|
+
pathHint,
|
|
20569
|
+
...text === void 0 ? {} : { text },
|
|
20416
20570
|
...rendered.attributes === void 0 ? {} : { attributes: rendered.attributes },
|
|
20417
20571
|
iframeDepth: rendered.iframeDepth,
|
|
20418
20572
|
shadowDepth: rendered.shadowDepth,
|
|
20419
20573
|
interactive: rendered.interactive,
|
|
20420
20574
|
liveCounterSyncEligible: rendered.liveCounterSyncEligible,
|
|
20421
|
-
|
|
20422
|
-
anchor: rendered.anchor,
|
|
20423
|
-
...sparseCounter !== void 0 && Number.isFinite(sparseCounter) ? { sparseCounter } : {}
|
|
20575
|
+
...replayableSparseCounter === void 0 ? {} : { sparseCounter: replayableSparseCounter }
|
|
20424
20576
|
});
|
|
20425
20577
|
});
|
|
20426
20578
|
return {
|
|
20427
|
-
html: $.html(),
|
|
20428
20579
|
counterRecords,
|
|
20429
20580
|
sparseToDirectMapping
|
|
20430
20581
|
};
|
|
@@ -20498,28 +20649,28 @@ function isLikelySelfHidden(node, nodesById) {
|
|
|
20498
20649
|
}
|
|
20499
20650
|
return !hasVisibleOutOfFlowChild(node, nodesById);
|
|
20500
20651
|
}
|
|
20501
|
-
function isLikelyInteractive(tagName, node, attributes) {
|
|
20652
|
+
function isLikelyInteractive(tagName, node, attributes, attributeIndex) {
|
|
20502
20653
|
if (NATIVE_INTERACTIVE_TAGS.has(tagName)) {
|
|
20503
|
-
if (tagName === "input" &&
|
|
20654
|
+
if (tagName === "input" && attributeIndex.get("type")?.toLowerCase() === "hidden") {
|
|
20504
20655
|
return false;
|
|
20505
20656
|
}
|
|
20506
20657
|
if (tagName !== "a") {
|
|
20507
20658
|
return true;
|
|
20508
20659
|
}
|
|
20509
20660
|
}
|
|
20510
|
-
if (tagName === "a" &&
|
|
20661
|
+
if (tagName === "a" && attributeIndex.has("href")) {
|
|
20511
20662
|
return true;
|
|
20512
20663
|
}
|
|
20513
|
-
if (
|
|
20664
|
+
if (attributeIndex.has("onclick") || attributeIndex.has("onmousedown") || attributeIndex.has("onmouseup") || attributeIndex.has("data-action") || attributeIndex.has("data-click") || attributeIndex.has("data-toggle")) {
|
|
20514
20665
|
return true;
|
|
20515
20666
|
}
|
|
20516
|
-
if (hasNonNegativeTabIndex(
|
|
20667
|
+
if (hasNonNegativeTabIndex(attributeIndex.get("tabindex"))) {
|
|
20517
20668
|
return true;
|
|
20518
20669
|
}
|
|
20519
|
-
if (
|
|
20670
|
+
if (attributeIndex.get("contenteditable")?.toLowerCase() === "true") {
|
|
20520
20671
|
return true;
|
|
20521
20672
|
}
|
|
20522
|
-
const role =
|
|
20673
|
+
const role = attributeIndex.get("role")?.toLowerCase();
|
|
20523
20674
|
return role !== void 0 && INTERACTIVE_ROLE_SET.has(role);
|
|
20524
20675
|
}
|
|
20525
20676
|
function hasVisibleOutOfFlowChild(node, nodesById) {
|
|
@@ -20582,14 +20733,6 @@ function parseOpacity(value) {
|
|
|
20582
20733
|
const parsed = Number.parseFloat(value);
|
|
20583
20734
|
return Number.isFinite(parsed) ? parsed : Number.NaN;
|
|
20584
20735
|
}
|
|
20585
|
-
function hasAttribute3(attributes, name) {
|
|
20586
|
-
const normalizedName = name.toLowerCase();
|
|
20587
|
-
return attributes.some((attribute) => attribute.name.toLowerCase() === normalizedName);
|
|
20588
|
-
}
|
|
20589
|
-
function unwrapExtractionHtml(html) {
|
|
20590
|
-
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
20591
|
-
return $("body").html()?.trim() || html;
|
|
20592
|
-
}
|
|
20593
20736
|
function buildSyntheticNodeId(snapshot, node) {
|
|
20594
20737
|
return `${snapshot.documentRef}:${String(snapshot.documentEpoch)}:${String(node.snapshotNodeId)}`;
|
|
20595
20738
|
}
|
|
@@ -20636,6 +20779,13 @@ function findAttributeValue(attributes, name) {
|
|
|
20636
20779
|
const normalizedName = name.toLowerCase();
|
|
20637
20780
|
return attributes.find((attribute) => attribute.name.toLowerCase() === normalizedName)?.value;
|
|
20638
20781
|
}
|
|
20782
|
+
function indexNodeAttributes(attributes) {
|
|
20783
|
+
const indexed = /* @__PURE__ */ new Map();
|
|
20784
|
+
for (const attribute of attributes) {
|
|
20785
|
+
indexed.set(attribute.name.toLowerCase(), attribute.value);
|
|
20786
|
+
}
|
|
20787
|
+
return indexed;
|
|
20788
|
+
}
|
|
20639
20789
|
function attributesToHtml(attributes) {
|
|
20640
20790
|
if (attributes.length === 0) {
|
|
20641
20791
|
return "";
|
|
@@ -20645,68 +20795,16 @@ function attributesToHtml(attributes) {
|
|
|
20645
20795
|
function escapeAttribute(value) {
|
|
20646
20796
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
20647
20797
|
}
|
|
20648
|
-
function buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices) {
|
|
20649
|
-
const index = getSnapshotIndex(snapshot.documentRef, snapshotsByDocumentRef, snapshotIndices);
|
|
20650
|
-
const localAnchor = buildLocalStructuralElementAnchor(index, node);
|
|
20651
|
-
return prefixIframeContext(snapshot, localAnchor, snapshotsByDocumentRef, snapshotIndices);
|
|
20652
|
-
}
|
|
20653
|
-
function prefixIframeContext(snapshot, localPath, snapshotsByDocumentRef, snapshotIndices) {
|
|
20654
|
-
if (snapshot.parentDocumentRef === void 0) {
|
|
20655
|
-
return sanitizeStructuralElementAnchor(localPath);
|
|
20656
|
-
}
|
|
20657
|
-
const parentSnapshot = snapshotsByDocumentRef.get(snapshot.parentDocumentRef);
|
|
20658
|
-
if (!parentSnapshot) {
|
|
20659
|
-
throw new Error(
|
|
20660
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no parent snapshot`
|
|
20661
|
-
);
|
|
20662
|
-
}
|
|
20663
|
-
const parentIndex = getSnapshotIndex(
|
|
20664
|
-
parentSnapshot.documentRef,
|
|
20665
|
-
snapshotsByDocumentRef,
|
|
20666
|
-
snapshotIndices
|
|
20667
|
-
);
|
|
20668
|
-
const iframeHost = findIframeHostNode(parentIndex, snapshot.documentRef);
|
|
20669
|
-
if (!iframeHost) {
|
|
20670
|
-
throw new Error(
|
|
20671
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no iframe host`
|
|
20672
|
-
);
|
|
20673
|
-
}
|
|
20674
|
-
const hostPath = buildSnapshotElementAnchor(
|
|
20675
|
-
parentSnapshot,
|
|
20676
|
-
iframeHost,
|
|
20677
|
-
snapshotsByDocumentRef,
|
|
20678
|
-
snapshotIndices
|
|
20679
|
-
);
|
|
20680
|
-
return sanitizeStructuralElementAnchor({
|
|
20681
|
-
context: [...hostPath.context, { kind: "iframe", host: hostPath.nodes }, ...localPath.context],
|
|
20682
|
-
nodes: localPath.nodes
|
|
20683
|
-
});
|
|
20684
|
-
}
|
|
20685
|
-
function getSnapshotIndex(documentRef, snapshotsByDocumentRef, snapshotIndices) {
|
|
20686
|
-
const existing = snapshotIndices.get(documentRef);
|
|
20687
|
-
if (existing) {
|
|
20688
|
-
return existing;
|
|
20689
|
-
}
|
|
20690
|
-
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
20691
|
-
if (!snapshot) {
|
|
20692
|
-
throw new Error(`missing DOM snapshot for ${documentRef}`);
|
|
20693
|
-
}
|
|
20694
|
-
const index = createSnapshotIndex(snapshot);
|
|
20695
|
-
snapshotIndices.set(documentRef, index);
|
|
20696
|
-
return index;
|
|
20697
|
-
}
|
|
20698
20798
|
function escapeHtml(value) {
|
|
20699
20799
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
20700
20800
|
}
|
|
20701
|
-
var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES, MAX_LIVE_COUNTER_SYNC_ATTEMPTS, CLEAR_LIVE_COUNTERS_SCRIPT, ASSIGN_SPARSE_COUNTERS_SCRIPT, APPLY_DENSE_COUNTERS_SCRIPT, LiveCounterSyncError;
|
|
20801
|
+
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;
|
|
20702
20802
|
var init_compiler = __esm({
|
|
20703
20803
|
"../runtime-core/src/sdk/snapshot/compiler.ts"() {
|
|
20704
|
-
init_src();
|
|
20705
|
-
init_path();
|
|
20706
|
-
init_selectors();
|
|
20707
20804
|
init_cleaner();
|
|
20708
20805
|
init_constants();
|
|
20709
20806
|
init_marking();
|
|
20807
|
+
EXTRACTION_SKIPPED_COUNTER_TAGS = /* @__PURE__ */ new Set(["html", "head", "body"]);
|
|
20710
20808
|
INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
|
|
20711
20809
|
"c",
|
|
20712
20810
|
OPENSTEER_BOUNDARY_ATTR,
|
|
@@ -20721,7 +20819,7 @@ var init_compiler = __esm({
|
|
|
20721
20819
|
MAX_LIVE_COUNTER_SYNC_ATTEMPTS = 4;
|
|
20722
20820
|
CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
|
|
20723
20821
|
const walk = (root) => {
|
|
20724
|
-
for (const child of root
|
|
20822
|
+
for (const child of Array.from(root?.children || [])) {
|
|
20725
20823
|
child.removeAttribute("c");
|
|
20726
20824
|
child.removeAttribute(sparseCounterAttr);
|
|
20727
20825
|
walk(child);
|
|
@@ -20737,7 +20835,7 @@ var init_compiler = __esm({
|
|
|
20737
20835
|
ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
|
|
20738
20836
|
let counter = startCounter;
|
|
20739
20837
|
const walk = (root) => {
|
|
20740
|
-
for (const child of root
|
|
20838
|
+
for (const child of Array.from(root?.children || [])) {
|
|
20741
20839
|
child.setAttribute(sparseCounterAttr, String(counter++));
|
|
20742
20840
|
walk(child);
|
|
20743
20841
|
if (child.shadowRoot) {
|
|
@@ -20751,7 +20849,7 @@ var init_compiler = __esm({
|
|
|
20751
20849
|
})`;
|
|
20752
20850
|
APPLY_DENSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, mapping }) => {
|
|
20753
20851
|
const walk = (root) => {
|
|
20754
|
-
for (const child of root
|
|
20852
|
+
for (const child of Array.from(root?.children || [])) {
|
|
20755
20853
|
child.removeAttribute("c");
|
|
20756
20854
|
const sparse = child.getAttribute(sparseCounterAttr);
|
|
20757
20855
|
if (sparse !== null) {
|
|
@@ -22935,15 +23033,10 @@ function normalizeNamespace2(value) {
|
|
|
22935
23033
|
const normalized = String(value ?? "default").trim();
|
|
22936
23034
|
return normalized.length === 0 ? "default" : normalized;
|
|
22937
23035
|
}
|
|
22938
|
-
function toOpensteerActionResult(
|
|
23036
|
+
function toOpensteerActionResult(target) {
|
|
22939
23037
|
return {
|
|
22940
|
-
|
|
22941
|
-
...
|
|
22942
|
-
point: {
|
|
22943
|
-
x: result.point.x,
|
|
22944
|
-
y: result.point.y
|
|
22945
|
-
}
|
|
22946
|
-
}
|
|
23038
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
23039
|
+
...target.persist === void 0 ? {} : { persist: target.persist }
|
|
22947
23040
|
};
|
|
22948
23041
|
}
|
|
22949
23042
|
function toOpensteerResolvedTarget2(target) {
|
|
@@ -22953,12 +23046,16 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
22953
23046
|
documentRef: target.documentRef,
|
|
22954
23047
|
documentEpoch: target.documentEpoch,
|
|
22955
23048
|
nodeRef: target.nodeRef,
|
|
22956
|
-
tagName: target.node.nodeName
|
|
23049
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
22957
23050
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
22958
23051
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
22959
23052
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
22960
23053
|
};
|
|
22961
23054
|
}
|
|
23055
|
+
function toOpensteerTagName2(nodeName) {
|
|
23056
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
23057
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
23058
|
+
}
|
|
22962
23059
|
function normalizeOpensteerError(error) {
|
|
22963
23060
|
return normalizeThrownOpensteerError(error, "Unknown Opensteer runtime failure");
|
|
22964
23061
|
}
|
|
@@ -23196,7 +23293,10 @@ var init_runtime3 = __esm({
|
|
|
23196
23293
|
sessionRef;
|
|
23197
23294
|
pageRef;
|
|
23198
23295
|
runId;
|
|
23199
|
-
|
|
23296
|
+
observationSessions = /* @__PURE__ */ new Map();
|
|
23297
|
+
openingObservationSessions = /* @__PURE__ */ new Map();
|
|
23298
|
+
openedObservationSessions = /* @__PURE__ */ new Set();
|
|
23299
|
+
observationSessionStorage = new async_hooks.AsyncLocalStorage();
|
|
23200
23300
|
operationEventStorage = new async_hooks.AsyncLocalStorage();
|
|
23201
23301
|
pendingOperationEventCaptures = [];
|
|
23202
23302
|
ownsEngine = false;
|
|
@@ -23248,18 +23348,26 @@ var init_runtime3 = __esm({
|
|
|
23248
23348
|
}
|
|
23249
23349
|
async setObservabilityConfig(input) {
|
|
23250
23350
|
this.observationConfig = normalizeObservabilityConfig(input);
|
|
23251
|
-
|
|
23252
|
-
if (observationSessionId === void 0) {
|
|
23253
|
-
return this.observationConfig;
|
|
23254
|
-
}
|
|
23255
|
-
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
23256
|
-
this.observations = await sink.openSession({
|
|
23257
|
-
sessionId: observationSessionId,
|
|
23258
|
-
openedAt: Date.now(),
|
|
23259
|
-
config: this.observationConfig
|
|
23260
|
-
});
|
|
23351
|
+
await this.ensureConfiguredObservationSession();
|
|
23261
23352
|
return this.observationConfig;
|
|
23262
23353
|
}
|
|
23354
|
+
async withObservationSessionId(sessionId, task) {
|
|
23355
|
+
return await this.observationSessionStorage.run(
|
|
23356
|
+
{
|
|
23357
|
+
mode: "session",
|
|
23358
|
+
sessionId: normalizeNonEmptyString("sessionId", sessionId)
|
|
23359
|
+
},
|
|
23360
|
+
task
|
|
23361
|
+
);
|
|
23362
|
+
}
|
|
23363
|
+
async withoutObservationSession(task) {
|
|
23364
|
+
return await this.observationSessionStorage.run(
|
|
23365
|
+
{
|
|
23366
|
+
mode: "disabled"
|
|
23367
|
+
},
|
|
23368
|
+
task
|
|
23369
|
+
);
|
|
23370
|
+
}
|
|
23263
23371
|
async open(input = {}, options = {}) {
|
|
23264
23372
|
assertValidSemanticOperationInput("session.open", input);
|
|
23265
23373
|
if (input.workspace !== void 0 && normalizeNamespace2(input.workspace) !== this.workspace) {
|
|
@@ -23276,7 +23384,7 @@ var init_runtime3 = __esm({
|
|
|
23276
23384
|
options
|
|
23277
23385
|
);
|
|
23278
23386
|
}
|
|
23279
|
-
return this.
|
|
23387
|
+
return this.readNavigationSummary();
|
|
23280
23388
|
}
|
|
23281
23389
|
const startedAt = Date.now();
|
|
23282
23390
|
const root = await this.ensureRoot();
|
|
@@ -23297,7 +23405,8 @@ var init_runtime3 = __esm({
|
|
|
23297
23405
|
openedSessionRef = sessionRef;
|
|
23298
23406
|
const createdPage = await timeout.runStep(
|
|
23299
23407
|
() => engine.createPage({
|
|
23300
|
-
sessionRef
|
|
23408
|
+
sessionRef,
|
|
23409
|
+
...input.url === void 0 ? {} : { url: input.url }
|
|
23301
23410
|
})
|
|
23302
23411
|
);
|
|
23303
23412
|
openedPageRef = createdPage.data.pageRef;
|
|
@@ -23307,18 +23416,19 @@ var init_runtime3 = __esm({
|
|
|
23307
23416
|
await timeout.runStep(() => this.ensureSemantics());
|
|
23308
23417
|
let frameRef2 = createdPage.frameRef;
|
|
23309
23418
|
if (input.url !== void 0) {
|
|
23310
|
-
|
|
23311
|
-
{
|
|
23419
|
+
await timeout.runStep(
|
|
23420
|
+
() => settleWithPolicy(this.policy.settle, {
|
|
23312
23421
|
operation: "session.open",
|
|
23422
|
+
trigger: "navigation",
|
|
23423
|
+
engine: this.requireEngine(),
|
|
23313
23424
|
pageRef: createdPage.data.pageRef,
|
|
23314
|
-
|
|
23315
|
-
|
|
23316
|
-
|
|
23425
|
+
signal: timeout.signal,
|
|
23426
|
+
remainingMs: timeout.remainingMs()
|
|
23427
|
+
})
|
|
23317
23428
|
);
|
|
23318
|
-
frameRef2 = navigation.data.mainFrame.frameRef;
|
|
23319
23429
|
}
|
|
23320
23430
|
return {
|
|
23321
|
-
state: await timeout.runStep(() => this.
|
|
23431
|
+
state: await timeout.runStep(() => this.readNavigationSummary()),
|
|
23322
23432
|
frameRef: frameRef2
|
|
23323
23433
|
};
|
|
23324
23434
|
},
|
|
@@ -23411,7 +23521,11 @@ var init_runtime3 = __esm({
|
|
|
23411
23521
|
"page.new cannot use openerPageRef before a session exists"
|
|
23412
23522
|
);
|
|
23413
23523
|
}
|
|
23414
|
-
|
|
23524
|
+
const summary = await this.open(input.url === void 0 ? {} : { url: input.url }, options);
|
|
23525
|
+
return {
|
|
23526
|
+
pageRef: await this.ensurePageRef(),
|
|
23527
|
+
...summary
|
|
23528
|
+
};
|
|
23415
23529
|
}
|
|
23416
23530
|
const startedAt = Date.now();
|
|
23417
23531
|
try {
|
|
@@ -23426,7 +23540,7 @@ var init_runtime3 = __esm({
|
|
|
23426
23540
|
})
|
|
23427
23541
|
);
|
|
23428
23542
|
this.pageRef = created.data.pageRef;
|
|
23429
|
-
return this.
|
|
23543
|
+
return this.readCreatedPageOutput(created.data.pageRef);
|
|
23430
23544
|
},
|
|
23431
23545
|
options
|
|
23432
23546
|
);
|
|
@@ -23468,7 +23582,7 @@ var init_runtime3 = __esm({
|
|
|
23468
23582
|
() => this.requireEngine().activatePage({ pageRef: input.pageRef })
|
|
23469
23583
|
);
|
|
23470
23584
|
this.pageRef = input.pageRef;
|
|
23471
|
-
return this.
|
|
23585
|
+
return this.readNavigationSummary(input.pageRef);
|
|
23472
23586
|
},
|
|
23473
23587
|
options
|
|
23474
23588
|
);
|
|
@@ -23594,7 +23708,7 @@ var init_runtime3 = __esm({
|
|
|
23594
23708
|
timeout.throwIfAborted();
|
|
23595
23709
|
return {
|
|
23596
23710
|
navigation: navigation2,
|
|
23597
|
-
state: await timeout.runStep(() => this.
|
|
23711
|
+
state: await timeout.runStep(() => this.readNavigationSummary(pageRef))
|
|
23598
23712
|
};
|
|
23599
23713
|
},
|
|
23600
23714
|
(diagnostics) => {
|
|
@@ -24828,7 +24942,7 @@ var init_runtime3 = __esm({
|
|
|
24828
24942
|
let mutationCaptureDiagnostics;
|
|
24829
24943
|
let boundaryDiagnostics;
|
|
24830
24944
|
try {
|
|
24831
|
-
const { artifacts, output } = await this.runMutationCapturedOperation(
|
|
24945
|
+
const { artifacts, output, result } = await this.runMutationCapturedOperation(
|
|
24832
24946
|
"computer.execute",
|
|
24833
24947
|
{
|
|
24834
24948
|
...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
|
|
@@ -24846,9 +24960,14 @@ var init_runtime3 = __esm({
|
|
|
24846
24960
|
await this.invalidateLiveSnapshotCounters([pageRef, output2.pageRef], timeout);
|
|
24847
24961
|
this.pageRef = output2.pageRef;
|
|
24848
24962
|
const artifacts2 = await this.persistComputerArtifacts(output2, timeout);
|
|
24963
|
+
const result2 = {
|
|
24964
|
+
...await timeout.runStep(() => this.readNavigationSummary(output2.pageRef)),
|
|
24965
|
+
screenshot: artifacts2.screenshot
|
|
24966
|
+
};
|
|
24849
24967
|
return {
|
|
24850
24968
|
artifacts: { manifests: artifacts2.manifests },
|
|
24851
|
-
output:
|
|
24969
|
+
output: output2,
|
|
24970
|
+
result: result2
|
|
24852
24971
|
};
|
|
24853
24972
|
} catch (error) {
|
|
24854
24973
|
boundaryDiagnostics ??= takeActionBoundaryDiagnostics(timeout.signal);
|
|
@@ -24885,7 +25004,7 @@ var init_runtime3 = __esm({
|
|
|
24885
25004
|
documentEpoch: output.screenshot.documentEpoch
|
|
24886
25005
|
})
|
|
24887
25006
|
});
|
|
24888
|
-
return
|
|
25007
|
+
return result;
|
|
24889
25008
|
} catch (error) {
|
|
24890
25009
|
await this.appendTrace({
|
|
24891
25010
|
operation: "computer.execute",
|
|
@@ -25033,8 +25152,9 @@ var init_runtime3 = __esm({
|
|
|
25033
25152
|
mutationCaptureDiagnostics = diagnostics;
|
|
25034
25153
|
}
|
|
25035
25154
|
);
|
|
25036
|
-
const output = toOpensteerActionResult(executed.result);
|
|
25155
|
+
const output = toOpensteerActionResult(executed.result.resolved);
|
|
25037
25156
|
const actionEvents = "events" in executed.result ? executed.result.events : void 0;
|
|
25157
|
+
const resolvedTarget = toOpensteerResolvedTarget2(executed.result.resolved);
|
|
25038
25158
|
await this.appendTrace({
|
|
25039
25159
|
operation,
|
|
25040
25160
|
startedAt,
|
|
@@ -25042,8 +25162,13 @@ var init_runtime3 = __esm({
|
|
|
25042
25162
|
outcome: "ok",
|
|
25043
25163
|
...actionEvents === void 0 ? {} : { events: actionEvents },
|
|
25044
25164
|
data: {
|
|
25045
|
-
target:
|
|
25046
|
-
...
|
|
25165
|
+
target: resolvedTarget,
|
|
25166
|
+
..."point" in executed.result && executed.result.point !== void 0 ? {
|
|
25167
|
+
point: {
|
|
25168
|
+
x: executed.result.point.x,
|
|
25169
|
+
y: executed.result.point.y
|
|
25170
|
+
}
|
|
25171
|
+
} : {},
|
|
25047
25172
|
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
25048
25173
|
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
25049
25174
|
},
|
|
@@ -26508,20 +26633,20 @@ var init_runtime3 = __esm({
|
|
|
26508
26633
|
throw error;
|
|
26509
26634
|
}
|
|
26510
26635
|
}
|
|
26511
|
-
async
|
|
26512
|
-
const pageRef = await this.ensurePageRef();
|
|
26636
|
+
async readNavigationSummary(targetPageRef) {
|
|
26637
|
+
const pageRef = targetPageRef ?? await this.ensurePageRef();
|
|
26513
26638
|
const pageInfo = await this.requireEngine().getPageInfo({ pageRef });
|
|
26514
|
-
const sessionRef = this.sessionRef;
|
|
26515
|
-
if (!sessionRef) {
|
|
26516
|
-
throw new Error("Opensteer session is not initialized");
|
|
26517
|
-
}
|
|
26518
26639
|
return {
|
|
26519
|
-
sessionRef,
|
|
26520
|
-
pageRef,
|
|
26521
26640
|
url: pageInfo.url,
|
|
26522
26641
|
title: pageInfo.title
|
|
26523
26642
|
};
|
|
26524
26643
|
}
|
|
26644
|
+
async readCreatedPageOutput(pageRef) {
|
|
26645
|
+
return {
|
|
26646
|
+
pageRef,
|
|
26647
|
+
...await this.readNavigationSummary(pageRef)
|
|
26648
|
+
};
|
|
26649
|
+
}
|
|
26525
26650
|
async captureSnapshotArtifacts(pageRef, options, timeout) {
|
|
26526
26651
|
const root = this.requireRoot();
|
|
26527
26652
|
const mainFrame = await timeout.runStep(() => getMainFrame(this.requireEngine(), pageRef));
|
|
@@ -26593,12 +26718,12 @@ var init_runtime3 = __esm({
|
|
|
26593
26718
|
const screenshotPayload = manifestToExternalBinaryLocation(root.rootPath, screenshotManifest);
|
|
26594
26719
|
return {
|
|
26595
26720
|
manifests,
|
|
26596
|
-
|
|
26597
|
-
|
|
26598
|
-
|
|
26599
|
-
|
|
26600
|
-
|
|
26601
|
-
}
|
|
26721
|
+
screenshot: {
|
|
26722
|
+
payload: screenshotPayload,
|
|
26723
|
+
format: output.screenshot.format,
|
|
26724
|
+
size: output.screenshot.size,
|
|
26725
|
+
coordinateSpace: output.screenshot.coordinateSpace,
|
|
26726
|
+
...output.screenshot.clip === void 0 ? {} : { clip: output.screenshot.clip }
|
|
26602
26727
|
}
|
|
26603
26728
|
};
|
|
26604
26729
|
}
|
|
@@ -26686,7 +26811,7 @@ var init_runtime3 = __esm({
|
|
|
26686
26811
|
}
|
|
26687
26812
|
async resetRuntimeState(options) {
|
|
26688
26813
|
const engine = this.engine;
|
|
26689
|
-
const
|
|
26814
|
+
const observationSessions = [...this.openedObservationSessions];
|
|
26690
26815
|
this.networkHistory.clear();
|
|
26691
26816
|
this.sessionRef = void 0;
|
|
26692
26817
|
this.pageRef = void 0;
|
|
@@ -26695,9 +26820,15 @@ var init_runtime3 = __esm({
|
|
|
26695
26820
|
this.computer = void 0;
|
|
26696
26821
|
this.extractionDescriptors = void 0;
|
|
26697
26822
|
this.engine = void 0;
|
|
26698
|
-
this.
|
|
26823
|
+
this.observationSessions.clear();
|
|
26824
|
+
this.openingObservationSessions.clear();
|
|
26825
|
+
this.openedObservationSessions.clear();
|
|
26699
26826
|
this.pendingOperationEventCaptures.length = 0;
|
|
26700
|
-
await
|
|
26827
|
+
await Promise.allSettled(
|
|
26828
|
+
observationSessions.map(
|
|
26829
|
+
(observationSession) => observationSession.close("runtime_reset").catch(() => void 0)
|
|
26830
|
+
)
|
|
26831
|
+
);
|
|
26701
26832
|
if (options.disposeEngine && this.ownsEngine && engine?.dispose) {
|
|
26702
26833
|
await engine.dispose();
|
|
26703
26834
|
}
|
|
@@ -26707,23 +26838,64 @@ var init_runtime3 = __esm({
|
|
|
26707
26838
|
if (this.observationConfig.profile === "off") {
|
|
26708
26839
|
return void 0;
|
|
26709
26840
|
}
|
|
26710
|
-
|
|
26711
|
-
|
|
26841
|
+
const observationSessionId = this.resolveObservationSessionId();
|
|
26842
|
+
if (observationSessionId === void 0) {
|
|
26843
|
+
return void 0;
|
|
26844
|
+
}
|
|
26845
|
+
const existingObservationSession = this.observationSessions.get(observationSessionId);
|
|
26846
|
+
if (existingObservationSession !== void 0) {
|
|
26847
|
+
return existingObservationSession;
|
|
26848
|
+
}
|
|
26849
|
+
const openingObservationSession = this.openingObservationSessions.get(observationSessionId);
|
|
26850
|
+
if (openingObservationSession !== void 0) {
|
|
26851
|
+
return await openingObservationSession;
|
|
26852
|
+
}
|
|
26853
|
+
const openObservationSessionTask = this.openObservationSession(observationSessionId).finally(
|
|
26854
|
+
() => {
|
|
26855
|
+
this.openingObservationSessions.delete(observationSessionId);
|
|
26856
|
+
}
|
|
26857
|
+
);
|
|
26858
|
+
this.openingObservationSessions.set(observationSessionId, openObservationSessionTask);
|
|
26859
|
+
return await openObservationSessionTask;
|
|
26860
|
+
}
|
|
26861
|
+
async ensureConfiguredObservationSession() {
|
|
26862
|
+
if (this.observationConfig.profile === "off") {
|
|
26863
|
+
return void 0;
|
|
26712
26864
|
}
|
|
26713
26865
|
const observationSessionId = this.resolveObservationSessionId();
|
|
26714
26866
|
if (observationSessionId === void 0) {
|
|
26715
26867
|
return void 0;
|
|
26716
26868
|
}
|
|
26869
|
+
const hadObservationSession = this.observationSessions.has(observationSessionId) || this.openingObservationSessions.has(observationSessionId);
|
|
26870
|
+
const observationSession = await this.ensureObservationSession();
|
|
26871
|
+
if (observationSession !== void 0 && hadObservationSession) {
|
|
26872
|
+
await observationSession.configure?.({
|
|
26873
|
+
config: this.observationConfig,
|
|
26874
|
+
updatedAt: Date.now()
|
|
26875
|
+
});
|
|
26876
|
+
}
|
|
26877
|
+
return observationSession;
|
|
26878
|
+
}
|
|
26879
|
+
resolveObservationSessionId() {
|
|
26880
|
+
const scopedSession = this.observationSessionStorage.getStore();
|
|
26881
|
+
if (scopedSession?.mode === "session") {
|
|
26882
|
+
return scopedSession.sessionId;
|
|
26883
|
+
}
|
|
26884
|
+
if (scopedSession?.mode === "disabled") {
|
|
26885
|
+
return void 0;
|
|
26886
|
+
}
|
|
26887
|
+
return this.observationSessionId ?? this.sessionRef;
|
|
26888
|
+
}
|
|
26889
|
+
async openObservationSession(sessionId) {
|
|
26717
26890
|
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
26718
|
-
|
|
26719
|
-
sessionId
|
|
26891
|
+
const observationSession = await sink.openSession({
|
|
26892
|
+
sessionId,
|
|
26720
26893
|
openedAt: Date.now(),
|
|
26721
26894
|
config: this.observationConfig
|
|
26722
26895
|
});
|
|
26723
|
-
|
|
26724
|
-
|
|
26725
|
-
|
|
26726
|
-
return this.observationSessionId ?? this.sessionRef;
|
|
26896
|
+
this.observationSessions.set(sessionId, observationSession);
|
|
26897
|
+
this.openedObservationSessions.add(observationSession);
|
|
26898
|
+
return observationSession;
|
|
26727
26899
|
}
|
|
26728
26900
|
runWithOperationTimeout(operation, callback, options = {}) {
|
|
26729
26901
|
const timeoutPolicy = options.timeoutMs === void 0 ? this.policy.timeout : {
|
|
@@ -28683,7 +28855,11 @@ function generateReplayScript(options) {
|
|
|
28683
28855
|
``,
|
|
28684
28856
|
...renderOpensteerBootstrap(replayTarget),
|
|
28685
28857
|
``,
|
|
28686
|
-
`
|
|
28858
|
+
`await opensteer.open(${JSON.stringify(initialPages[0]?.initialUrl ?? "")});`,
|
|
28859
|
+
`const ${initialPageId} = (await opensteer.listPages()).activePageRef;`,
|
|
28860
|
+
`if (!${initialPageId}) {`,
|
|
28861
|
+
` throw new Error("Opensteer did not report an active page after open().");`,
|
|
28862
|
+
`}`,
|
|
28687
28863
|
`let activePageRef: string | undefined = ${initialPageId};`,
|
|
28688
28864
|
``,
|
|
28689
28865
|
`async function ensureActive(pageRef: string): Promise<void> {`,
|
|
@@ -28887,26 +29063,35 @@ function renderOpensteerBootstrap(replayTarget) {
|
|
|
28887
29063
|
`const opensteer = new Opensteer({`,
|
|
28888
29064
|
` provider: {`,
|
|
28889
29065
|
` mode: "cloud",`,
|
|
28890
|
-
` baseUrl: requireEnv(${JSON.stringify(replayTarget.baseUrlEnvVar ?? "OPENSTEER_BASE_URL")}),`,
|
|
28891
29066
|
` apiKey: requireEnv(${JSON.stringify(replayTarget.apiKeyEnvVar ?? "OPENSTEER_API_KEY")}),`,
|
|
29067
|
+
...renderCloudBaseUrl(replayTarget),
|
|
28892
29068
|
...renderCloudBrowserProfile(replayTarget),
|
|
28893
29069
|
` },`,
|
|
28894
29070
|
`});`
|
|
28895
29071
|
];
|
|
28896
29072
|
}
|
|
28897
29073
|
function renderRequireEnvHelper(replayTarget) {
|
|
28898
|
-
const baseUrlEnvVar = replayTarget.baseUrlEnvVar ?? "OPENSTEER_BASE_URL";
|
|
28899
29074
|
const apiKeyEnvVar = replayTarget.apiKeyEnvVar ?? "OPENSTEER_API_KEY";
|
|
29075
|
+
const requiredEnvVars = [
|
|
29076
|
+
...replayTarget.baseUrlEnvVar === void 0 ? [] : [replayTarget.baseUrlEnvVar],
|
|
29077
|
+
apiKeyEnvVar
|
|
29078
|
+
];
|
|
28900
29079
|
return [
|
|
28901
29080
|
`function requireEnv(name: string): string {`,
|
|
28902
29081
|
` const value = process.env[name];`,
|
|
28903
29082
|
` if (typeof value === "string" && value.trim().length > 0) {`,
|
|
28904
29083
|
` return value;`,
|
|
28905
29084
|
` }`,
|
|
28906
|
-
` throw new Error(\`Missing environment variable \${name}. Set ${
|
|
29085
|
+
` throw new Error(\`Missing environment variable \${name}. Set ${requiredEnvVars.join(" and ")} before replaying this recording.\`);`,
|
|
28907
29086
|
`}`
|
|
28908
29087
|
].join("\n");
|
|
28909
29088
|
}
|
|
29089
|
+
function renderCloudBaseUrl(replayTarget) {
|
|
29090
|
+
if (replayTarget.baseUrlEnvVar === void 0) {
|
|
29091
|
+
return [];
|
|
29092
|
+
}
|
|
29093
|
+
return [` baseUrl: requireEnv(${JSON.stringify(replayTarget.baseUrlEnvVar)}),`];
|
|
29094
|
+
}
|
|
28910
29095
|
function renderCloudBrowserProfile(replayTarget) {
|
|
28911
29096
|
if (replayTarget.browserProfileId === void 0) {
|
|
28912
29097
|
return [];
|
|
@@ -30169,6 +30354,41 @@ var init_session_proxy = __esm({
|
|
|
30169
30354
|
};
|
|
30170
30355
|
}
|
|
30171
30356
|
});
|
|
30357
|
+
async function persistLocalActivePageHint(runtime, rootPath) {
|
|
30358
|
+
try {
|
|
30359
|
+
await syncPersistedLocalActivePageHint(runtime, rootPath);
|
|
30360
|
+
} catch {
|
|
30361
|
+
}
|
|
30362
|
+
}
|
|
30363
|
+
async function syncPersistedLocalActivePageHint(runtime, rootPath) {
|
|
30364
|
+
const record = await readPersistedLocalBrowserSessionRecord(rootPath);
|
|
30365
|
+
if (!record) {
|
|
30366
|
+
return;
|
|
30367
|
+
}
|
|
30368
|
+
const sessionInfo = await runtime.info();
|
|
30369
|
+
const activePageRef = sessionInfo.activePageRef;
|
|
30370
|
+
let activePageUrl;
|
|
30371
|
+
let activePageTitle;
|
|
30372
|
+
if (activePageRef !== void 0) {
|
|
30373
|
+
const pages = await runtime.listPages();
|
|
30374
|
+
const activePage = pages.pages.find((page) => page.pageRef === activePageRef);
|
|
30375
|
+
activePageUrl = activePage?.url;
|
|
30376
|
+
activePageTitle = activePage?.title;
|
|
30377
|
+
}
|
|
30378
|
+
const {
|
|
30379
|
+
activePageRef: _previousActivePageRef,
|
|
30380
|
+
activePageUrl: _previousActivePageUrl,
|
|
30381
|
+
activePageTitle: _previousActivePageTitle,
|
|
30382
|
+
...restRecord
|
|
30383
|
+
} = record;
|
|
30384
|
+
await writePersistedSessionRecord(rootPath, {
|
|
30385
|
+
...restRecord,
|
|
30386
|
+
updatedAt: Date.now(),
|
|
30387
|
+
...activePageRef === void 0 ? {} : { activePageRef },
|
|
30388
|
+
...activePageUrl === void 0 ? {} : { activePageUrl },
|
|
30389
|
+
...activePageTitle === void 0 ? {} : { activePageTitle }
|
|
30390
|
+
});
|
|
30391
|
+
}
|
|
30172
30392
|
function buildSharedRuntimeOptions(input) {
|
|
30173
30393
|
const ownership = resolveOwnership(input.browser);
|
|
30174
30394
|
const engineFactory = input.engineFactory ?? ((factoryOptions) => new OpensteerBrowserManager({
|
|
@@ -30215,14 +30435,37 @@ function normalizeWorkspace2(workspace) {
|
|
|
30215
30435
|
function resolveOwnership(browser) {
|
|
30216
30436
|
return typeof browser === "object" && browser.mode === "attach" ? "attached" : "owned";
|
|
30217
30437
|
}
|
|
30218
|
-
var OpensteerRuntime;
|
|
30438
|
+
var LocalActivePageHintRuntime, OpensteerRuntime;
|
|
30219
30439
|
var init_runtime4 = __esm({
|
|
30220
30440
|
"src/sdk/runtime.ts"() {
|
|
30221
30441
|
init_src3();
|
|
30222
30442
|
init_browser_manager();
|
|
30223
30443
|
init_engine_selection2();
|
|
30444
|
+
init_live_session();
|
|
30224
30445
|
init_root2();
|
|
30225
|
-
|
|
30446
|
+
LocalActivePageHintRuntime = class extends OpensteerSessionRuntime {
|
|
30447
|
+
async completeWithLocalActivePageHint(operation) {
|
|
30448
|
+
const output = await operation();
|
|
30449
|
+
await persistLocalActivePageHint(this, this.rootPath);
|
|
30450
|
+
return output;
|
|
30451
|
+
}
|
|
30452
|
+
async open(input = {}, options = {}) {
|
|
30453
|
+
return this.completeWithLocalActivePageHint(() => super.open(input, options));
|
|
30454
|
+
}
|
|
30455
|
+
async newPage(input = {}, options = {}) {
|
|
30456
|
+
return this.completeWithLocalActivePageHint(() => super.newPage(input, options));
|
|
30457
|
+
}
|
|
30458
|
+
async activatePage(input, options = {}) {
|
|
30459
|
+
return this.completeWithLocalActivePageHint(() => super.activatePage(input, options));
|
|
30460
|
+
}
|
|
30461
|
+
async closePage(input = {}, options = {}) {
|
|
30462
|
+
return this.completeWithLocalActivePageHint(() => super.closePage(input, options));
|
|
30463
|
+
}
|
|
30464
|
+
async goto(input, options = {}) {
|
|
30465
|
+
return this.completeWithLocalActivePageHint(() => super.goto(input, options));
|
|
30466
|
+
}
|
|
30467
|
+
};
|
|
30468
|
+
OpensteerRuntime = class extends LocalActivePageHintRuntime {
|
|
30226
30469
|
constructor(options = {}) {
|
|
30227
30470
|
const publicWorkspace = normalizeWorkspace2(options.workspace);
|
|
30228
30471
|
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ? path10__default.default.resolve(options.rootDir ?? process.cwd(), ".opensteer", "temporary", crypto.randomUUID()) : resolveFilesystemWorkspacePath({
|
|
@@ -30944,7 +31187,7 @@ var init_opensteer = __esm({
|
|
|
30944
31187
|
|
|
30945
31188
|
// package.json
|
|
30946
31189
|
var package_default = {
|
|
30947
|
-
version: "0.9.
|
|
31190
|
+
version: "0.9.8"};
|
|
30948
31191
|
|
|
30949
31192
|
// src/cli/bin.ts
|
|
30950
31193
|
init_browser_manager();
|
|
@@ -31599,14 +31842,22 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31599
31842
|
return parsed.rest[0] === void 0 ? {} : { mode: parsed.rest[0] };
|
|
31600
31843
|
case "page.evaluate":
|
|
31601
31844
|
if (parsed.rest[0] === void 0) {
|
|
31602
|
-
throw new CliError(
|
|
31845
|
+
throw new CliError(
|
|
31846
|
+
"missing_arguments",
|
|
31847
|
+
"evaluate requires a script.",
|
|
31848
|
+
CLI_USAGE_HINTS[operation]
|
|
31849
|
+
);
|
|
31603
31850
|
}
|
|
31604
31851
|
return {
|
|
31605
31852
|
script: joinRest(parsed.rest, 0)
|
|
31606
31853
|
};
|
|
31607
31854
|
case "page.add-init-script":
|
|
31608
31855
|
if (parsed.rest[0] === void 0) {
|
|
31609
|
-
throw new CliError(
|
|
31856
|
+
throw new CliError(
|
|
31857
|
+
"missing_arguments",
|
|
31858
|
+
"init-script requires a script.",
|
|
31859
|
+
CLI_USAGE_HINTS[operation]
|
|
31860
|
+
);
|
|
31610
31861
|
}
|
|
31611
31862
|
return {
|
|
31612
31863
|
script: joinRest(parsed.rest, 0)
|
|
@@ -31622,7 +31873,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31622
31873
|
return buildElementTargetInput(parsed, "hover");
|
|
31623
31874
|
case "dom.input": {
|
|
31624
31875
|
if (parsed.rest[1] === void 0) {
|
|
31625
|
-
throw new CliError(
|
|
31876
|
+
throw new CliError(
|
|
31877
|
+
"missing_arguments",
|
|
31878
|
+
"input requires an element number and text.",
|
|
31879
|
+
CLI_USAGE_HINTS[operation]
|
|
31880
|
+
);
|
|
31626
31881
|
}
|
|
31627
31882
|
const pressEnter = readOptionalBoolean(parsed.rawOptions, "press-enter");
|
|
31628
31883
|
return {
|
|
@@ -31653,7 +31908,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31653
31908
|
}
|
|
31654
31909
|
case "dom.extract": {
|
|
31655
31910
|
if (parsed.rest[0] === void 0) {
|
|
31656
|
-
throw new CliError(
|
|
31911
|
+
throw new CliError(
|
|
31912
|
+
"missing_arguments",
|
|
31913
|
+
"extract requires a template.",
|
|
31914
|
+
CLI_USAGE_HINTS[operation]
|
|
31915
|
+
);
|
|
31657
31916
|
}
|
|
31658
31917
|
const persist = readPersistKey(parsed, "extract");
|
|
31659
31918
|
return {
|
|
@@ -31689,7 +31948,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31689
31948
|
}
|
|
31690
31949
|
case "network.detail": {
|
|
31691
31950
|
if (parsed.rest[0] === void 0) {
|
|
31692
|
-
throw new CliError(
|
|
31951
|
+
throw new CliError(
|
|
31952
|
+
"missing_arguments",
|
|
31953
|
+
"network detail requires a record id.",
|
|
31954
|
+
CLI_USAGE_HINTS[operation]
|
|
31955
|
+
);
|
|
31693
31956
|
}
|
|
31694
31957
|
const probeFlag = readOptionalBoolean(parsed.rawOptions, "probe");
|
|
31695
31958
|
return {
|
|
@@ -31700,7 +31963,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31700
31963
|
case "session.fetch": {
|
|
31701
31964
|
const url = parsed.rest[0];
|
|
31702
31965
|
if (url === void 0) {
|
|
31703
|
-
throw new CliError(
|
|
31966
|
+
throw new CliError(
|
|
31967
|
+
"missing_arguments",
|
|
31968
|
+
"fetch requires a URL.",
|
|
31969
|
+
CLI_USAGE_HINTS[operation]
|
|
31970
|
+
);
|
|
31704
31971
|
}
|
|
31705
31972
|
const bodyJson = readJsonValue(parsed.rawOptions, "body");
|
|
31706
31973
|
const bodyText = readSingle(parsed.rawOptions, "body-text");
|
|
@@ -31739,7 +32006,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31739
32006
|
const siteKey = readSingle(parsed.rawOptions, "site-key");
|
|
31740
32007
|
const pageUrl = readSingle(parsed.rawOptions, "page-url");
|
|
31741
32008
|
if (provider === void 0 || apiKey === void 0) {
|
|
31742
|
-
throw new CliError(
|
|
32009
|
+
throw new CliError(
|
|
32010
|
+
"missing_arguments",
|
|
32011
|
+
'captcha solve requires "--provider" and "--api-key".',
|
|
32012
|
+
CLI_USAGE_HINTS[operation]
|
|
32013
|
+
);
|
|
31743
32014
|
}
|
|
31744
32015
|
return {
|
|
31745
32016
|
provider: readCaptchaProvider(provider),
|
|
@@ -31769,7 +32040,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31769
32040
|
case "scripts.beautify":
|
|
31770
32041
|
case "scripts.deobfuscate": {
|
|
31771
32042
|
if (parsed.rest[0] === void 0) {
|
|
31772
|
-
throw new CliError(
|
|
32043
|
+
throw new CliError(
|
|
32044
|
+
"missing_arguments",
|
|
32045
|
+
`${parsed.command.join(" ")} requires an artifact id.`,
|
|
32046
|
+
CLI_USAGE_HINTS[operation]
|
|
32047
|
+
);
|
|
31773
32048
|
}
|
|
31774
32049
|
const persist = readOptionalBoolean(parsed.rawOptions, "persist");
|
|
31775
32050
|
return {
|
|
@@ -31779,7 +32054,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31779
32054
|
}
|
|
31780
32055
|
case "scripts.sandbox":
|
|
31781
32056
|
if (parsed.rest[0] === void 0) {
|
|
31782
|
-
throw new CliError(
|
|
32057
|
+
throw new CliError(
|
|
32058
|
+
"missing_arguments",
|
|
32059
|
+
"scripts sandbox requires an artifact id.",
|
|
32060
|
+
CLI_USAGE_HINTS[operation]
|
|
32061
|
+
);
|
|
31783
32062
|
}
|
|
31784
32063
|
{
|
|
31785
32064
|
const fidelity = readSingle(parsed.rawOptions, "fidelity");
|
|
@@ -31828,14 +32107,22 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31828
32107
|
case "interaction.get":
|
|
31829
32108
|
case "interaction.replay":
|
|
31830
32109
|
if (parsed.rest[0] === void 0) {
|
|
31831
|
-
throw new CliError(
|
|
32110
|
+
throw new CliError(
|
|
32111
|
+
"missing_arguments",
|
|
32112
|
+
`${parsed.command.join(" ")} requires a trace id.`,
|
|
32113
|
+
CLI_USAGE_HINTS[operation]
|
|
32114
|
+
);
|
|
31832
32115
|
}
|
|
31833
32116
|
return {
|
|
31834
32117
|
traceId: parsed.rest[0]
|
|
31835
32118
|
};
|
|
31836
32119
|
case "interaction.diff":
|
|
31837
32120
|
if (parsed.rest[0] === void 0 || parsed.rest[1] === void 0) {
|
|
31838
|
-
throw new CliError(
|
|
32121
|
+
throw new CliError(
|
|
32122
|
+
"missing_arguments",
|
|
32123
|
+
"interaction diff requires two trace ids.",
|
|
32124
|
+
CLI_USAGE_HINTS[operation]
|
|
32125
|
+
);
|
|
31839
32126
|
}
|
|
31840
32127
|
return {
|
|
31841
32128
|
leftTraceId: parsed.rest[0],
|
|
@@ -31843,7 +32130,11 @@ async function buildOperationInput(operation, parsed, runtime) {
|
|
|
31843
32130
|
};
|
|
31844
32131
|
case "artifact.read":
|
|
31845
32132
|
if (parsed.rest[0] === void 0) {
|
|
31846
|
-
throw new CliError(
|
|
32133
|
+
throw new CliError(
|
|
32134
|
+
"missing_arguments",
|
|
32135
|
+
"artifact read requires an artifact id.",
|
|
32136
|
+
CLI_USAGE_HINTS[operation]
|
|
32137
|
+
);
|
|
31847
32138
|
}
|
|
31848
32139
|
return {
|
|
31849
32140
|
artifactId: parsed.rest[0]
|
|
@@ -31981,7 +32272,10 @@ function buildComputerExecuteInput(parsed) {
|
|
|
31981
32272
|
}
|
|
31982
32273
|
};
|
|
31983
32274
|
default:
|
|
31984
|
-
throw new CliError(
|
|
32275
|
+
throw new CliError(
|
|
32276
|
+
"unknown_command",
|
|
32277
|
+
`Unknown computer command: ${parsed.command.join(" ")}`
|
|
32278
|
+
);
|
|
31985
32279
|
}
|
|
31986
32280
|
}
|
|
31987
32281
|
async function resolvePageRefByIndex(runtime, index) {
|
|
@@ -32011,7 +32305,10 @@ function readRequiredNumber(value, message) {
|
|
|
32011
32305
|
}
|
|
32012
32306
|
function readSingleDirection(value) {
|
|
32013
32307
|
if (value === void 0 || !SCROLL_DIRECTIONS.has(value)) {
|
|
32014
|
-
throw new CliError(
|
|
32308
|
+
throw new CliError(
|
|
32309
|
+
"missing_arguments",
|
|
32310
|
+
"scroll requires a direction: up, down, left, or right."
|
|
32311
|
+
);
|
|
32015
32312
|
}
|
|
32016
32313
|
return value;
|
|
32017
32314
|
}
|
|
@@ -32038,13 +32335,19 @@ function readCaptchaProvider(value) {
|
|
|
32038
32335
|
}
|
|
32039
32336
|
function readCaptchaType(value) {
|
|
32040
32337
|
if (value === void 0 || !CAPTCHA_TYPES.has(value)) {
|
|
32041
|
-
throw new CliError(
|
|
32338
|
+
throw new CliError(
|
|
32339
|
+
"invalid_value",
|
|
32340
|
+
'Expected "--type" to be one of: recaptcha-v2, hcaptcha, turnstile.'
|
|
32341
|
+
);
|
|
32042
32342
|
}
|
|
32043
32343
|
return value;
|
|
32044
32344
|
}
|
|
32045
32345
|
function readSandboxFidelity(value) {
|
|
32046
32346
|
if (value === void 0 || !SANDBOX_FIDELITIES.has(value)) {
|
|
32047
|
-
throw new CliError(
|
|
32347
|
+
throw new CliError(
|
|
32348
|
+
"invalid_value",
|
|
32349
|
+
'Expected "--fidelity" to be one of: minimal, standard, full.'
|
|
32350
|
+
);
|
|
32048
32351
|
}
|
|
32049
32352
|
return value;
|
|
32050
32353
|
}
|
|
@@ -32067,7 +32370,10 @@ function readKeyModifiers(value) {
|
|
|
32067
32370
|
}
|
|
32068
32371
|
for (const modifier of modifiers) {
|
|
32069
32372
|
if (!KEY_MODIFIERS.has(modifier)) {
|
|
32070
|
-
throw new CliError(
|
|
32373
|
+
throw new CliError(
|
|
32374
|
+
"invalid_value",
|
|
32375
|
+
'Expected "--modifiers" to contain only: Shift, Control, Alt, Meta.'
|
|
32376
|
+
);
|
|
32071
32377
|
}
|
|
32072
32378
|
}
|
|
32073
32379
|
return [...new Set(modifiers)];
|
|
@@ -32102,6 +32408,7 @@ function joinRest(rest, startIndex) {
|
|
|
32102
32408
|
function renderOperationOutput(operation, result, input) {
|
|
32103
32409
|
switch (operation) {
|
|
32104
32410
|
case "session.open":
|
|
32411
|
+
case "page.activate":
|
|
32105
32412
|
case "page.goto":
|
|
32106
32413
|
return renderJson(formatNavigationOutput(result));
|
|
32107
32414
|
case "page.snapshot":
|
|
@@ -32110,14 +32417,14 @@ function renderOperationOutput(operation, result, input) {
|
|
|
32110
32417
|
case "dom.hover":
|
|
32111
32418
|
case "dom.input":
|
|
32112
32419
|
case "dom.scroll":
|
|
32113
|
-
return renderJson(formatActionOutput(result
|
|
32420
|
+
return renderJson(formatActionOutput(result));
|
|
32114
32421
|
case "dom.extract":
|
|
32115
32422
|
return renderJson(formatExtractOutput(result));
|
|
32116
32423
|
case "page.list":
|
|
32117
|
-
case "page.new":
|
|
32118
|
-
case "page.activate":
|
|
32119
32424
|
case "page.close":
|
|
32120
32425
|
return formatTabOutput(result);
|
|
32426
|
+
case "page.new":
|
|
32427
|
+
return renderJson(formatCreatedPageOutput(result));
|
|
32121
32428
|
case "network.query":
|
|
32122
32429
|
return formatNetworkQueryOutput(result, input);
|
|
32123
32430
|
case "network.detail":
|
|
@@ -32155,6 +32462,12 @@ function formatNavigationOutput(result) {
|
|
|
32155
32462
|
...readStringField(result, "title") === void 0 ? {} : { title: readStringField(result, "title") }
|
|
32156
32463
|
};
|
|
32157
32464
|
}
|
|
32465
|
+
function formatCreatedPageOutput(result) {
|
|
32466
|
+
return {
|
|
32467
|
+
...readStringField(result, "pageRef") === void 0 ? {} : { pageRef: readStringField(result, "pageRef") },
|
|
32468
|
+
...formatNavigationOutput(result)
|
|
32469
|
+
};
|
|
32470
|
+
}
|
|
32158
32471
|
function formatSnapshotOutput(result) {
|
|
32159
32472
|
if (result !== null && typeof result === "object" && typeof result.html === "string") {
|
|
32160
32473
|
return `${result.html}
|
|
@@ -32162,36 +32475,11 @@ function formatSnapshotOutput(result) {
|
|
|
32162
32475
|
}
|
|
32163
32476
|
return renderJson(result);
|
|
32164
32477
|
}
|
|
32165
|
-
function formatActionOutput(result
|
|
32166
|
-
|
|
32167
|
-
|
|
32168
|
-
...readStringField(
|
|
32169
|
-
...readStringField(target, "pathHint") === void 0 ? {} : { pathHint: readStringField(target, "pathHint") }
|
|
32478
|
+
function formatActionOutput(result) {
|
|
32479
|
+
return {
|
|
32480
|
+
...readStringField(result, "tagName") === void 0 ? {} : { tagName: readStringField(result, "tagName") },
|
|
32481
|
+
...readStringField(result, "persist") === void 0 ? {} : { persist: readStringField(result, "persist") }
|
|
32170
32482
|
};
|
|
32171
|
-
const point = readObjectField(result, "point");
|
|
32172
|
-
if (point !== void 0) {
|
|
32173
|
-
output.point = {
|
|
32174
|
-
...readNumberField(point, "x") === void 0 ? {} : { x: readNumberField(point, "x") },
|
|
32175
|
-
...readNumberField(point, "y") === void 0 ? {} : { y: readNumberField(point, "y") }
|
|
32176
|
-
};
|
|
32177
|
-
}
|
|
32178
|
-
const persist = readStringField(target, "persist");
|
|
32179
|
-
if (persist !== void 0) {
|
|
32180
|
-
output.persist = persist;
|
|
32181
|
-
}
|
|
32182
|
-
const text = readStringField(input, "text");
|
|
32183
|
-
if (text !== void 0) {
|
|
32184
|
-
output.text = text;
|
|
32185
|
-
}
|
|
32186
|
-
const direction = readStringField(input, "direction");
|
|
32187
|
-
if (direction !== void 0) {
|
|
32188
|
-
output.direction = direction;
|
|
32189
|
-
}
|
|
32190
|
-
const amount = readNumberField(input, "amount");
|
|
32191
|
-
if (amount !== void 0) {
|
|
32192
|
-
output.amount = amount;
|
|
32193
|
-
}
|
|
32194
|
-
return output;
|
|
32195
32483
|
}
|
|
32196
32484
|
function formatExtractOutput(result) {
|
|
32197
32485
|
const data = readUnknownField(result, "data");
|
|
@@ -32423,20 +32711,18 @@ function formatStateOutput(result) {
|
|
|
32423
32711
|
`;
|
|
32424
32712
|
}
|
|
32425
32713
|
function formatComputerOutput(result) {
|
|
32426
|
-
const action = readObjectField(result, "action");
|
|
32427
32714
|
const screenshot = readObjectField(result, "screenshot");
|
|
32428
32715
|
const payload = readObjectField(screenshot, "payload");
|
|
32429
|
-
const timing = readObjectField(result, "timing");
|
|
32430
32716
|
return {
|
|
32431
|
-
...
|
|
32717
|
+
...readStringField(result, "url") === void 0 ? {} : { url: readStringField(result, "url") },
|
|
32718
|
+
...readStringField(result, "title") === void 0 ? {} : { title: readStringField(result, "title") },
|
|
32432
32719
|
...payload === void 0 ? {} : {
|
|
32433
32720
|
screenshot: {
|
|
32434
32721
|
...readStringField(payload, "uri") === void 0 ? {} : { uri: readStringField(payload, "uri") },
|
|
32435
32722
|
...readStringField(screenshot, "format") === void 0 ? {} : { format: readStringField(screenshot, "format") },
|
|
32436
32723
|
...readObjectField(screenshot, "size") === void 0 ? {} : { size: readObjectField(screenshot, "size") }
|
|
32437
32724
|
}
|
|
32438
|
-
}
|
|
32439
|
-
...timing === void 0 ? {} : { timingMs: timing }
|
|
32725
|
+
}
|
|
32440
32726
|
};
|
|
32441
32727
|
}
|
|
32442
32728
|
function formatScriptsCaptureOutput(result) {
|
|
@@ -33098,7 +33384,7 @@ async function collectOpensteerStatus(input) {
|
|
|
33098
33384
|
...output,
|
|
33099
33385
|
rootPath,
|
|
33100
33386
|
lanes: {
|
|
33101
|
-
local: describeLocalLane(localRecord, input.provider.mode === "local"),
|
|
33387
|
+
local: await describeLocalLane(localRecord, input.provider.mode === "local"),
|
|
33102
33388
|
cloud: await describeCloudLane({
|
|
33103
33389
|
record: cloudRecord,
|
|
33104
33390
|
current: input.provider.mode === "cloud",
|
|
@@ -33150,8 +33436,38 @@ async function readWorkspaceCloudRecord(rootPath) {
|
|
|
33150
33436
|
}
|
|
33151
33437
|
return readPersistedCloudSessionRecord(rootPath);
|
|
33152
33438
|
}
|
|
33153
|
-
function describeLocalLane(record, current) {
|
|
33154
|
-
if (record === void 0
|
|
33439
|
+
async function describeLocalLane(record, current) {
|
|
33440
|
+
if (record === void 0) {
|
|
33441
|
+
return {
|
|
33442
|
+
provider: "local",
|
|
33443
|
+
status: "idle",
|
|
33444
|
+
current,
|
|
33445
|
+
summary: "none"
|
|
33446
|
+
};
|
|
33447
|
+
}
|
|
33448
|
+
if (getPersistedLocalBrowserSessionOwnership(record) === "attached") {
|
|
33449
|
+
if (!await isAttachedLocalBrowserSessionReachable(record)) {
|
|
33450
|
+
return {
|
|
33451
|
+
provider: "local",
|
|
33452
|
+
status: "stale",
|
|
33453
|
+
current,
|
|
33454
|
+
summary: "attached browser unavailable",
|
|
33455
|
+
detail: record.engine,
|
|
33456
|
+
engine: record.engine
|
|
33457
|
+
};
|
|
33458
|
+
}
|
|
33459
|
+
const browser2 = record.executablePath ? path10__default.default.basename(record.executablePath).replace(/\.[A-Za-z0-9]+$/u, "") : void 0;
|
|
33460
|
+
return {
|
|
33461
|
+
provider: "local",
|
|
33462
|
+
status: "active",
|
|
33463
|
+
current,
|
|
33464
|
+
summary: "attached browser",
|
|
33465
|
+
detail: browser2 ?? record.engine,
|
|
33466
|
+
engine: record.engine,
|
|
33467
|
+
...browser2 === void 0 ? {} : { browser: browser2 }
|
|
33468
|
+
};
|
|
33469
|
+
}
|
|
33470
|
+
if (!isProcessRunning(record.pid)) {
|
|
33155
33471
|
return {
|
|
33156
33472
|
provider: "local",
|
|
33157
33473
|
status: "idle",
|
|
@@ -33302,13 +33618,13 @@ async function resolveSessionSummary(manifest) {
|
|
|
33302
33618
|
return {
|
|
33303
33619
|
sessionId: manifest.sessionId,
|
|
33304
33620
|
label: manifest.workspace ?? (path10__default.default.basename(manifest.rootPath) || manifest.sessionId),
|
|
33305
|
-
status: isProcessRunning(record.pid) ? "live" : "stale",
|
|
33621
|
+
status: getPersistedLocalBrowserSessionOwnership(record) === "attached" || isProcessRunning(record.pid) ? "live" : "stale",
|
|
33306
33622
|
...manifest.workspace === void 0 ? {} : { workspace: manifest.workspace },
|
|
33307
33623
|
rootPath: manifest.rootPath,
|
|
33308
33624
|
engine: record.engine,
|
|
33309
33625
|
ownership: manifest.ownership,
|
|
33310
|
-
pid: record.pid,
|
|
33311
33626
|
startedAt: record.startedAt,
|
|
33627
|
+
...record.pid > 0 ? { pid: record.pid } : {},
|
|
33312
33628
|
...browserName === void 0 ? {} : { browserName }
|
|
33313
33629
|
};
|
|
33314
33630
|
}
|
|
@@ -33336,7 +33652,16 @@ async function readLiveRecord(manifest) {
|
|
|
33336
33652
|
if (!record) {
|
|
33337
33653
|
return void 0;
|
|
33338
33654
|
}
|
|
33339
|
-
if (
|
|
33655
|
+
if (buildLocalViewSessionIdForRecord({
|
|
33656
|
+
rootPath: manifest.rootPath,
|
|
33657
|
+
live: record
|
|
33658
|
+
}) !== manifest.sessionId || record.startedAt !== manifest.startedAt || record.engine !== manifest.engine || getPersistedLocalBrowserSessionOwnership(record) !== manifest.ownership) {
|
|
33659
|
+
return void 0;
|
|
33660
|
+
}
|
|
33661
|
+
if (getPersistedLocalBrowserSessionOwnership(record) === "attached") {
|
|
33662
|
+
return await isAttachedLocalBrowserSessionReachable(record) ? record : void 0;
|
|
33663
|
+
}
|
|
33664
|
+
if (record.pid !== manifest.pid || !isProcessRunning(record.pid)) {
|
|
33340
33665
|
return void 0;
|
|
33341
33666
|
}
|
|
33342
33667
|
return record;
|
|
@@ -33630,6 +33955,172 @@ init_process_owner();
|
|
|
33630
33955
|
init_service_state();
|
|
33631
33956
|
init_service_state();
|
|
33632
33957
|
|
|
33958
|
+
// src/local-view/browser-target-order.ts
|
|
33959
|
+
async function readPageTargetId(page) {
|
|
33960
|
+
const cdp = await page.context().newCDPSession(page);
|
|
33961
|
+
try {
|
|
33962
|
+
const result = await cdp.send("Target.getTargetInfo");
|
|
33963
|
+
const targetId = result?.targetInfo?.targetId;
|
|
33964
|
+
return typeof targetId === "string" && targetId.length > 0 ? targetId : null;
|
|
33965
|
+
} finally {
|
|
33966
|
+
await cdp.detach().catch(() => void 0);
|
|
33967
|
+
}
|
|
33968
|
+
}
|
|
33969
|
+
async function readBrowserPageTargetOrder(browserContext) {
|
|
33970
|
+
const browser = browserContext.browser();
|
|
33971
|
+
if (!browser || !hasBrowserCdpSession(browser)) {
|
|
33972
|
+
return [];
|
|
33973
|
+
}
|
|
33974
|
+
const cdp = await browser.newBrowserCDPSession();
|
|
33975
|
+
try {
|
|
33976
|
+
const result = await cdp.send("Target.getTargets");
|
|
33977
|
+
return normalizeBrowserPageTargetOrder(result?.targetInfos ?? []);
|
|
33978
|
+
} catch {
|
|
33979
|
+
return [];
|
|
33980
|
+
} finally {
|
|
33981
|
+
await cdp.detach().catch(() => void 0);
|
|
33982
|
+
}
|
|
33983
|
+
}
|
|
33984
|
+
async function orderPagesByBrowserTargetOrder(browserContext, pages) {
|
|
33985
|
+
if (pages.length < 2) {
|
|
33986
|
+
return pages;
|
|
33987
|
+
}
|
|
33988
|
+
const orderedTargetIds = await readBrowserPageTargetOrder(browserContext);
|
|
33989
|
+
if (orderedTargetIds.length === 0) {
|
|
33990
|
+
return pages;
|
|
33991
|
+
}
|
|
33992
|
+
const rankByTargetId = new Map(orderedTargetIds.map((targetId, index) => [targetId, index]));
|
|
33993
|
+
const targetIds = await Promise.all(
|
|
33994
|
+
pages.map((page) => readPageTargetId(page).catch(() => null))
|
|
33995
|
+
);
|
|
33996
|
+
return pages.map((page, index) => {
|
|
33997
|
+
const targetId = targetIds[index] ?? void 0;
|
|
33998
|
+
return {
|
|
33999
|
+
page,
|
|
34000
|
+
index,
|
|
34001
|
+
rank: targetId === void 0 ? void 0 : rankByTargetId.get(targetId)
|
|
34002
|
+
};
|
|
34003
|
+
}).sort((left, right) => {
|
|
34004
|
+
if (left.rank !== void 0 && right.rank !== void 0) {
|
|
34005
|
+
return left.rank - right.rank;
|
|
34006
|
+
}
|
|
34007
|
+
if (left.rank !== void 0) {
|
|
34008
|
+
return -1;
|
|
34009
|
+
}
|
|
34010
|
+
if (right.rank !== void 0) {
|
|
34011
|
+
return 1;
|
|
34012
|
+
}
|
|
34013
|
+
return left.index - right.index;
|
|
34014
|
+
}).map((entry) => entry.page);
|
|
34015
|
+
}
|
|
34016
|
+
function hasBrowserCdpSession(browser) {
|
|
34017
|
+
return typeof browser.newBrowserCDPSession === "function";
|
|
34018
|
+
}
|
|
34019
|
+
function normalizeBrowserPageTargetOrder(targetInfos) {
|
|
34020
|
+
const reversedPageInfos = [];
|
|
34021
|
+
for (const targetInfo of targetInfos) {
|
|
34022
|
+
if (targetInfo.type !== "page") {
|
|
34023
|
+
continue;
|
|
34024
|
+
}
|
|
34025
|
+
const targetId = typeof targetInfo.targetId === "string" && targetInfo.targetId.length > 0 ? targetInfo.targetId : void 0;
|
|
34026
|
+
if (targetId === void 0) {
|
|
34027
|
+
continue;
|
|
34028
|
+
}
|
|
34029
|
+
reversedPageInfos.push({
|
|
34030
|
+
targetId,
|
|
34031
|
+
openerId: typeof targetInfo.openerId === "string" && targetInfo.openerId.length > 0 ? targetInfo.openerId : void 0
|
|
34032
|
+
});
|
|
34033
|
+
}
|
|
34034
|
+
reversedPageInfos.reverse();
|
|
34035
|
+
const rawTargetInfoById = new Map(
|
|
34036
|
+
reversedPageInfos.map((targetInfo) => [targetInfo.targetId, targetInfo])
|
|
34037
|
+
);
|
|
34038
|
+
const targetInfoById = new Map(
|
|
34039
|
+
reversedPageInfos.map(
|
|
34040
|
+
(targetInfo) => [
|
|
34041
|
+
targetInfo.targetId,
|
|
34042
|
+
{
|
|
34043
|
+
...targetInfo,
|
|
34044
|
+
openerId: resolveAcyclicOpenerId(targetInfo.targetId, rawTargetInfoById)
|
|
34045
|
+
}
|
|
34046
|
+
]
|
|
34047
|
+
)
|
|
34048
|
+
);
|
|
34049
|
+
const orderedTargetIds = [];
|
|
34050
|
+
const placed = /* @__PURE__ */ new Set();
|
|
34051
|
+
const placeTarget = (targetId) => {
|
|
34052
|
+
if (placed.has(targetId)) {
|
|
34053
|
+
return;
|
|
34054
|
+
}
|
|
34055
|
+
const targetInfo = targetInfoById.get(targetId);
|
|
34056
|
+
if (!targetInfo) {
|
|
34057
|
+
return;
|
|
34058
|
+
}
|
|
34059
|
+
const openerId = targetInfo.openerId;
|
|
34060
|
+
if (openerId === void 0) {
|
|
34061
|
+
orderedTargetIds.push(targetId);
|
|
34062
|
+
placed.add(targetId);
|
|
34063
|
+
return;
|
|
34064
|
+
}
|
|
34065
|
+
placeTarget(openerId);
|
|
34066
|
+
const openerIndex = orderedTargetIds.indexOf(openerId);
|
|
34067
|
+
const insertionIndex = openerIndex === -1 ? orderedTargetIds.length : findPopupInsertionIndex(orderedTargetIds, openerIndex, openerId, targetInfoById);
|
|
34068
|
+
orderedTargetIds.splice(insertionIndex, 0, targetId);
|
|
34069
|
+
placed.add(targetId);
|
|
34070
|
+
};
|
|
34071
|
+
for (const targetInfo of reversedPageInfos) {
|
|
34072
|
+
placeTarget(targetInfo.targetId);
|
|
34073
|
+
}
|
|
34074
|
+
return orderedTargetIds;
|
|
34075
|
+
}
|
|
34076
|
+
function resolveAcyclicOpenerId(targetId, targetInfoById) {
|
|
34077
|
+
const openerId = targetInfoById.get(targetId)?.openerId;
|
|
34078
|
+
if (openerId === void 0 || !targetInfoById.has(openerId)) {
|
|
34079
|
+
return void 0;
|
|
34080
|
+
}
|
|
34081
|
+
const visitedTargetIds = /* @__PURE__ */ new Set([targetId]);
|
|
34082
|
+
let currentTargetId = openerId;
|
|
34083
|
+
while (currentTargetId !== void 0) {
|
|
34084
|
+
if (visitedTargetIds.has(currentTargetId)) {
|
|
34085
|
+
return void 0;
|
|
34086
|
+
}
|
|
34087
|
+
visitedTargetIds.add(currentTargetId);
|
|
34088
|
+
currentTargetId = targetInfoById.get(currentTargetId)?.openerId;
|
|
34089
|
+
}
|
|
34090
|
+
return openerId;
|
|
34091
|
+
}
|
|
34092
|
+
function findPopupInsertionIndex(orderedTargetIds, openerIndex, openerTargetId, targetInfoById) {
|
|
34093
|
+
let index = openerIndex + 1;
|
|
34094
|
+
while (index < orderedTargetIds.length) {
|
|
34095
|
+
const candidateTargetId = orderedTargetIds[index];
|
|
34096
|
+
if (!candidateTargetId || !isDescendantTarget(candidateTargetId, openerTargetId, targetInfoById)) {
|
|
34097
|
+
break;
|
|
34098
|
+
}
|
|
34099
|
+
index += 1;
|
|
34100
|
+
}
|
|
34101
|
+
return index;
|
|
34102
|
+
}
|
|
34103
|
+
function isDescendantTarget(targetId, ancestorTargetId, targetInfoById) {
|
|
34104
|
+
const visitedTargetIds = /* @__PURE__ */ new Set();
|
|
34105
|
+
let currentTargetId = targetId;
|
|
34106
|
+
while (currentTargetId !== void 0) {
|
|
34107
|
+
if (visitedTargetIds.has(currentTargetId)) {
|
|
34108
|
+
return false;
|
|
34109
|
+
}
|
|
34110
|
+
visitedTargetIds.add(currentTargetId);
|
|
34111
|
+
const currentTargetInfo = targetInfoById.get(currentTargetId);
|
|
34112
|
+
const openerId = currentTargetInfo?.openerId;
|
|
34113
|
+
if (openerId === void 0) {
|
|
34114
|
+
return false;
|
|
34115
|
+
}
|
|
34116
|
+
if (openerId === ancestorTargetId) {
|
|
34117
|
+
return true;
|
|
34118
|
+
}
|
|
34119
|
+
currentTargetId = openerId;
|
|
34120
|
+
}
|
|
34121
|
+
return false;
|
|
34122
|
+
}
|
|
34123
|
+
|
|
33633
34124
|
// src/local-view/tab-state-tracker.ts
|
|
33634
34125
|
var ACTIVATION_INTENT_DISCOVERY_GRACE_MS = 2e3;
|
|
33635
34126
|
var TabStateTracker = class {
|
|
@@ -33645,6 +34136,7 @@ var TabStateTracker = class {
|
|
|
33645
34136
|
boundContextCleanup = null;
|
|
33646
34137
|
constructor(deps) {
|
|
33647
34138
|
this.deps = deps;
|
|
34139
|
+
this.lastActivePage = deps.initialActivePage ?? null;
|
|
33648
34140
|
}
|
|
33649
34141
|
start() {
|
|
33650
34142
|
if (this.running) {
|
|
@@ -33769,7 +34261,7 @@ var TabStateTracker = class {
|
|
|
33769
34261
|
this.updatePolling(pages.length);
|
|
33770
34262
|
const preferredActivePage = this.lastActivePage ?? pages[0] ?? null;
|
|
33771
34263
|
const pageStates = await Promise.all(
|
|
33772
|
-
pages.map(async (page,
|
|
34264
|
+
pages.map(async (page, originalIndex) => {
|
|
33773
34265
|
const metadata = await this.readPageMetadata(page, {
|
|
33774
34266
|
refresh: args.refreshMetadata
|
|
33775
34267
|
});
|
|
@@ -33779,7 +34271,7 @@ var TabStateTracker = class {
|
|
|
33779
34271
|
};
|
|
33780
34272
|
return {
|
|
33781
34273
|
page,
|
|
33782
|
-
|
|
34274
|
+
originalIndex,
|
|
33783
34275
|
targetId: metadata.targetId,
|
|
33784
34276
|
url: page.url(),
|
|
33785
34277
|
title: metadata.title,
|
|
@@ -33788,17 +34280,18 @@ var TabStateTracker = class {
|
|
|
33788
34280
|
};
|
|
33789
34281
|
})
|
|
33790
34282
|
);
|
|
34283
|
+
const orderedPageStates = await this.orderPageStates(pageStates);
|
|
33791
34284
|
const activePage = this.pickActivePage(
|
|
33792
|
-
|
|
34285
|
+
orderedPageStates,
|
|
33793
34286
|
this.lastActivePage,
|
|
33794
34287
|
preferredActivePage,
|
|
33795
|
-
this.resolveIntentPage(
|
|
34288
|
+
this.resolveIntentPage(orderedPageStates)
|
|
33796
34289
|
);
|
|
33797
34290
|
if (activePage && activePage !== this.lastActivePage) {
|
|
33798
34291
|
this.lastActivePage = activePage;
|
|
33799
34292
|
this.deps.onActivePageChanged(activePage);
|
|
33800
34293
|
}
|
|
33801
|
-
const tabs =
|
|
34294
|
+
const tabs = orderedPageStates.map((state) => ({
|
|
33802
34295
|
index: state.index,
|
|
33803
34296
|
...state.targetId === void 0 ? {} : { targetId: state.targetId },
|
|
33804
34297
|
url: state.url,
|
|
@@ -33848,18 +34341,11 @@ var TabStateTracker = class {
|
|
|
33848
34341
|
if (cached) {
|
|
33849
34342
|
return cached;
|
|
33850
34343
|
}
|
|
33851
|
-
const
|
|
33852
|
-
|
|
33853
|
-
|
|
33854
|
-
const targetId = result?.targetInfo?.targetId;
|
|
33855
|
-
if (typeof targetId === "string" && targetId.length > 0) {
|
|
33856
|
-
this.targetIdByPage.set(page, targetId);
|
|
33857
|
-
return targetId;
|
|
33858
|
-
}
|
|
33859
|
-
return null;
|
|
33860
|
-
} finally {
|
|
33861
|
-
await cdp.detach().catch(() => void 0);
|
|
34344
|
+
const targetId = await readPageTargetId(page);
|
|
34345
|
+
if (targetId) {
|
|
34346
|
+
this.targetIdByPage.set(page, targetId);
|
|
33862
34347
|
}
|
|
34348
|
+
return targetId;
|
|
33863
34349
|
}
|
|
33864
34350
|
async readFocusState(page) {
|
|
33865
34351
|
try {
|
|
@@ -33927,6 +34413,33 @@ var TabStateTracker = class {
|
|
|
33927
34413
|
this.deps.runtimeState.clearPageActivationIntent(this.deps.sessionId, intent.targetId);
|
|
33928
34414
|
return { page: matched.page };
|
|
33929
34415
|
}
|
|
34416
|
+
async orderPageStates(pageStates) {
|
|
34417
|
+
if (pageStates.length < 2) {
|
|
34418
|
+
return pageStates.map(({ originalIndex: _originalIndex, ...state }, index) => ({
|
|
34419
|
+
...state,
|
|
34420
|
+
index
|
|
34421
|
+
}));
|
|
34422
|
+
}
|
|
34423
|
+
const orderedTargetIds = await readBrowserPageTargetOrder(this.deps.browserContext);
|
|
34424
|
+
const rankByTargetId = new Map(orderedTargetIds.map((targetId, index) => [targetId, index]));
|
|
34425
|
+
return [...pageStates].sort((left, right) => {
|
|
34426
|
+
const leftRank = left.targetId === void 0 ? void 0 : rankByTargetId.get(left.targetId);
|
|
34427
|
+
const rightRank = right.targetId === void 0 ? void 0 : rankByTargetId.get(right.targetId);
|
|
34428
|
+
if (leftRank !== void 0 && rightRank !== void 0) {
|
|
34429
|
+
return leftRank - rightRank;
|
|
34430
|
+
}
|
|
34431
|
+
if (leftRank !== void 0) {
|
|
34432
|
+
return -1;
|
|
34433
|
+
}
|
|
34434
|
+
if (rightRank !== void 0) {
|
|
34435
|
+
return 1;
|
|
34436
|
+
}
|
|
34437
|
+
return left.originalIndex - right.originalIndex;
|
|
34438
|
+
}).map(({ originalIndex: _originalIndex, ...state }, index) => ({
|
|
34439
|
+
...state,
|
|
34440
|
+
index
|
|
34441
|
+
}));
|
|
34442
|
+
}
|
|
33930
34443
|
};
|
|
33931
34444
|
|
|
33932
34445
|
// src/local-view/view-stream-capture-policy.ts
|
|
@@ -34290,6 +34803,7 @@ var SessionViewStreamProducer = class {
|
|
|
34290
34803
|
sessionId: this.deps.sessionId,
|
|
34291
34804
|
pollMs: TAB_STATE_POLL_MS,
|
|
34292
34805
|
runtimeState: this.deps.runtimeState,
|
|
34806
|
+
initialActivePage: session.page,
|
|
34293
34807
|
onActivePageChanged: (page) => {
|
|
34294
34808
|
this.activePage = page;
|
|
34295
34809
|
void this.queueBindToPage(page).catch(() => void 0);
|
|
@@ -34388,7 +34902,20 @@ var SessionViewStreamProducer = class {
|
|
|
34388
34902
|
if (!context) {
|
|
34389
34903
|
throw new Error("Connected browser did not expose a Chromium browser context.");
|
|
34390
34904
|
}
|
|
34391
|
-
const
|
|
34905
|
+
const existingPages = context.pages();
|
|
34906
|
+
if (existingPages.length === 0) {
|
|
34907
|
+
const page2 = await context.newPage();
|
|
34908
|
+
return {
|
|
34909
|
+
browser,
|
|
34910
|
+
context,
|
|
34911
|
+
page: page2
|
|
34912
|
+
};
|
|
34913
|
+
}
|
|
34914
|
+
const orderedPages = await orderPagesByBrowserTargetOrder(context, existingPages);
|
|
34915
|
+
const page = await resolvePersistedActivePage(orderedPages, {
|
|
34916
|
+
...resolved.record.activePageUrl === void 0 ? {} : { activePageUrl: resolved.record.activePageUrl },
|
|
34917
|
+
...resolved.record.activePageTitle === void 0 ? {} : { activePageTitle: resolved.record.activePageTitle }
|
|
34918
|
+
}) ?? orderedPages[0];
|
|
34392
34919
|
return {
|
|
34393
34920
|
browser,
|
|
34394
34921
|
context,
|
|
@@ -34733,6 +35260,28 @@ async function disconnectPlaywrightChromiumBrowser2(browser) {
|
|
|
34733
35260
|
const { disconnectPlaywrightChromiumBrowser: disconnect } = await import('@opensteer/engine-playwright');
|
|
34734
35261
|
await disconnect(browser);
|
|
34735
35262
|
}
|
|
35263
|
+
async function resolvePersistedActivePage(pages, input) {
|
|
35264
|
+
if (pages.length === 0) {
|
|
35265
|
+
return null;
|
|
35266
|
+
}
|
|
35267
|
+
if (input.activePageUrl === void 0 && input.activePageTitle === void 0) {
|
|
35268
|
+
return null;
|
|
35269
|
+
}
|
|
35270
|
+
const matchesByUrl = input.activePageUrl === void 0 ? pages : pages.filter((page) => page.url() === input.activePageUrl);
|
|
35271
|
+
if (matchesByUrl.length === 0) {
|
|
35272
|
+
return null;
|
|
35273
|
+
}
|
|
35274
|
+
if (input.activePageTitle === void 0) {
|
|
35275
|
+
return matchesByUrl[0] ?? null;
|
|
35276
|
+
}
|
|
35277
|
+
for (const page of matchesByUrl) {
|
|
35278
|
+
const title = await page.title().catch(() => "");
|
|
35279
|
+
if (title === input.activePageTitle) {
|
|
35280
|
+
return page;
|
|
35281
|
+
}
|
|
35282
|
+
}
|
|
35283
|
+
return matchesByUrl[0] ?? null;
|
|
35284
|
+
}
|
|
34736
35285
|
|
|
34737
35286
|
// src/local-view/server.ts
|
|
34738
35287
|
var DEFAULT_MAX_FPS = 12;
|
|
@@ -35105,13 +35654,19 @@ async function resolveWorkspaceSessionId(input) {
|
|
|
35105
35654
|
workspace: input.workspace
|
|
35106
35655
|
});
|
|
35107
35656
|
const live = await readPersistedLocalBrowserSessionRecord(rootPath);
|
|
35108
|
-
if (!live
|
|
35657
|
+
if (!live) {
|
|
35109
35658
|
return void 0;
|
|
35110
35659
|
}
|
|
35111
|
-
|
|
35660
|
+
if (getPersistedLocalBrowserSessionOwnership(live) === "attached") {
|
|
35661
|
+
if (!await isAttachedLocalBrowserSessionReachable(live)) {
|
|
35662
|
+
return void 0;
|
|
35663
|
+
}
|
|
35664
|
+
} else if (!isProcessRunning(live.pid)) {
|
|
35665
|
+
return void 0;
|
|
35666
|
+
}
|
|
35667
|
+
return buildLocalViewSessionIdForRecord({
|
|
35112
35668
|
rootPath,
|
|
35113
|
-
|
|
35114
|
-
startedAt: live.startedAt
|
|
35669
|
+
live
|
|
35115
35670
|
});
|
|
35116
35671
|
}
|
|
35117
35672
|
function assertNoViewPreferenceFlag(parsed) {
|
|
@@ -35207,7 +35762,10 @@ async function main() {
|
|
|
35207
35762
|
throw new CliError("unknown_command", `Unknown command: ${parsed.command.join(" ")}`);
|
|
35208
35763
|
}
|
|
35209
35764
|
if (parsed.options.workspace === void 0) {
|
|
35210
|
-
throw new CliError(
|
|
35765
|
+
throw new CliError(
|
|
35766
|
+
"missing_workspace",
|
|
35767
|
+
'Stateful commands require "--workspace <id>" or OPENSTEER_WORKSPACE.'
|
|
35768
|
+
);
|
|
35211
35769
|
}
|
|
35212
35770
|
const { engineName, provider, runtimeProvider } = resolveCliRuntimeSelection(parsed);
|
|
35213
35771
|
if (operation === "session.close") {
|
|
@@ -35254,7 +35812,10 @@ async function main() {
|
|
|
35254
35812
|
}
|
|
35255
35813
|
async function handleExecCommand(parsed) {
|
|
35256
35814
|
if (parsed.options.workspace === void 0) {
|
|
35257
|
-
throw new CliError(
|
|
35815
|
+
throw new CliError(
|
|
35816
|
+
"missing_workspace",
|
|
35817
|
+
'exec requires "--workspace <id>" or OPENSTEER_WORKSPACE.'
|
|
35818
|
+
);
|
|
35258
35819
|
}
|
|
35259
35820
|
const expression = parsed.rest.join(" ");
|
|
35260
35821
|
if (!expression) {
|
|
@@ -35397,7 +35958,10 @@ async function handleCloseCommand(parsed, engineName, providerMode, runtimeProvi
|
|
|
35397
35958
|
}
|
|
35398
35959
|
async function handleRecordCommandEntry(parsed) {
|
|
35399
35960
|
if (parsed.options.workspace === void 0) {
|
|
35400
|
-
throw new CliError(
|
|
35961
|
+
throw new CliError(
|
|
35962
|
+
"missing_workspace",
|
|
35963
|
+
'record requires "--workspace <id>" or OPENSTEER_WORKSPACE.'
|
|
35964
|
+
);
|
|
35401
35965
|
}
|
|
35402
35966
|
const url = parsed.options.url ?? parsed.rest[0];
|
|
35403
35967
|
if (url === void 0) {
|
|
@@ -35437,7 +36001,10 @@ async function handleRecordCommandEntry(parsed) {
|
|
|
35437
36001
|
return;
|
|
35438
36002
|
}
|
|
35439
36003
|
if (parsed.options.launch?.headless === true) {
|
|
35440
|
-
throw new CliError(
|
|
36004
|
+
throw new CliError(
|
|
36005
|
+
"config_conflict",
|
|
36006
|
+
'record requires a headed browser. Remove "--headless true".'
|
|
36007
|
+
);
|
|
35441
36008
|
}
|
|
35442
36009
|
if (typeof recordBrowser === "object") {
|
|
35443
36010
|
throw new CliError("config_conflict", 'record does not support browser.mode="attach".');
|
|
@@ -35509,7 +36076,10 @@ function resolveCliBootstrapAction(argv) {
|
|
|
35509
36076
|
}
|
|
35510
36077
|
function buildCliBrowserProfile(parsed) {
|
|
35511
36078
|
if (parsed.options.cloudProfileReuseIfActive === true && parsed.options.cloudProfileId === void 0) {
|
|
35512
|
-
throw new CliError(
|
|
36079
|
+
throw new CliError(
|
|
36080
|
+
"invalid_option",
|
|
36081
|
+
'"--cloud-profile-reuse-if-active" requires "--cloud-profile-id <id>".'
|
|
36082
|
+
);
|
|
35513
36083
|
}
|
|
35514
36084
|
return parsed.options.cloudProfileId === void 0 ? void 0 : {
|
|
35515
36085
|
profileId: parsed.options.cloudProfileId,
|