opensteer 0.9.5 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7LQL5YUR.js → chunk-3OHKIPBD.js} +571 -738
- package/dist/chunk-3OHKIPBD.js.map +1 -0
- package/dist/chunk-52UNH5UW.js +458 -0
- package/dist/chunk-52UNH5UW.js.map +1 -0
- package/dist/{chunk-GSCQQKZZ.js → chunk-PJXN7HED.js} +334 -18
- package/dist/chunk-PJXN7HED.js.map +1 -0
- package/dist/{chunk-ZRF7WMS3.js → chunk-R33BXCMQ.js} +16 -7
- package/dist/chunk-R33BXCMQ.js.map +1 -0
- package/dist/{chunk-T5P2QGZ3.js → chunk-U4BUCIZ4.js} +153 -12
- package/dist/chunk-U4BUCIZ4.js.map +1 -0
- package/dist/cli/bin.cjs +1421 -824
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +286 -129
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +1117 -703
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -53
- package/dist/index.d.ts +58 -53
- package/dist/index.js +4 -4
- package/dist/local-view/public/assets/app.js +10 -1
- package/dist/local-view/serve-entry.cjs +6815 -1272
- package/dist/local-view/serve-entry.cjs.map +1 -1
- package/dist/local-view/serve-entry.js +2 -2
- package/dist/opensteer-CY2QUJEG.js +6 -0
- package/dist/{opensteer-T2JENADR.js.map → opensteer-CY2QUJEG.js.map} +1 -1
- package/dist/{session-control-M3JD7ZKA.js → session-control-FIP6ZJLH.js} +4 -4
- package/dist/{session-control-M3JD7ZKA.js.map → session-control-FIP6ZJLH.js.map} +1 -1
- package/package.json +7 -7
- package/dist/chunk-7D45QUZ3.js +0 -332
- package/dist/chunk-7D45QUZ3.js.map +0 -1
- package/dist/chunk-7LQL5YUR.js.map +0 -1
- package/dist/chunk-GSCQQKZZ.js.map +0 -1
- package/dist/chunk-T5P2QGZ3.js.map +0 -1
- package/dist/chunk-ZRF7WMS3.js.map +0 -1
- package/dist/opensteer-T2JENADR.js +0 -6
package/dist/index.cjs
CHANGED
|
@@ -102,6 +102,11 @@ function stableJsonString(value) {
|
|
|
102
102
|
|
|
103
103
|
// ../runtime-core/src/internal/filesystem.ts
|
|
104
104
|
var LOCK_RETRY_DELAYS_MS = [1, 2, 5, 10, 20, 50];
|
|
105
|
+
var LOCK_METADATA_FILENAME = "owner.json";
|
|
106
|
+
var LOCK_METADATA_VERSION = 1;
|
|
107
|
+
var LOCK_HEARTBEAT_INTERVAL_MS = 1e3;
|
|
108
|
+
var LOCK_ORPHAN_GRACE_MS = 2e3;
|
|
109
|
+
var LOCK_METADATALESS_STALE_MS = 3e4;
|
|
105
110
|
function normalizeNonEmptyString(name, value) {
|
|
106
111
|
const normalized = value.trim();
|
|
107
112
|
if (normalized.length === 0) {
|
|
@@ -207,24 +212,119 @@ function isAlreadyExistsError(error) {
|
|
|
207
212
|
}
|
|
208
213
|
async function withFilesystemLock(lockPath, task) {
|
|
209
214
|
await ensureDirectory(path10__default.default.dirname(lockPath));
|
|
215
|
+
const ownerToken = crypto.randomUUID();
|
|
210
216
|
let attempt = 0;
|
|
211
217
|
while (true) {
|
|
212
218
|
try {
|
|
213
219
|
await promises.mkdir(lockPath);
|
|
220
|
+
const acquiredAt = Date.now();
|
|
221
|
+
await writeLockMetadata(lockPath, {
|
|
222
|
+
version: LOCK_METADATA_VERSION,
|
|
223
|
+
ownerToken,
|
|
224
|
+
pid: process.pid,
|
|
225
|
+
acquiredAt,
|
|
226
|
+
heartbeatAt: acquiredAt
|
|
227
|
+
});
|
|
214
228
|
break;
|
|
215
229
|
} catch (error) {
|
|
216
230
|
if (!isAlreadyExistsError(error)) {
|
|
217
231
|
throw error;
|
|
218
232
|
}
|
|
233
|
+
if (await tryRecoverFilesystemLock(lockPath)) {
|
|
234
|
+
attempt = 0;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
219
237
|
const delayMs = LOCK_RETRY_DELAYS_MS[Math.min(attempt, LOCK_RETRY_DELAYS_MS.length - 1)];
|
|
220
238
|
attempt += 1;
|
|
221
239
|
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
222
240
|
}
|
|
223
241
|
}
|
|
242
|
+
const heartbeatTimer = setInterval(() => {
|
|
243
|
+
void touchLockMetadata(lockPath, ownerToken);
|
|
244
|
+
}, LOCK_HEARTBEAT_INTERVAL_MS);
|
|
245
|
+
heartbeatTimer.unref?.();
|
|
224
246
|
try {
|
|
225
247
|
return await task();
|
|
226
248
|
} finally {
|
|
227
|
-
|
|
249
|
+
clearInterval(heartbeatTimer);
|
|
250
|
+
const metadata = await readLockMetadata(lockPath);
|
|
251
|
+
if (metadata?.ownerToken === ownerToken) {
|
|
252
|
+
await promises.rm(lockPath, { recursive: true, force: true });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function tryRecoverFilesystemLock(lockPath) {
|
|
257
|
+
if (!await shouldRecoverFilesystemLock(lockPath)) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
await promises.rm(lockPath, { recursive: true, force: true });
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
async function shouldRecoverFilesystemLock(lockPath) {
|
|
264
|
+
const metadata = await readLockMetadata(lockPath);
|
|
265
|
+
if (metadata !== void 0) {
|
|
266
|
+
if (isProcessRunning(metadata.pid)) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
return Date.now() - metadata.heartbeatAt >= LOCK_ORPHAN_GRACE_MS;
|
|
270
|
+
}
|
|
271
|
+
const lockStat = await promises.stat(lockPath).catch(() => void 0);
|
|
272
|
+
if (lockStat === void 0) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
return Date.now() - lockStat.mtimeMs >= LOCK_METADATALESS_STALE_MS;
|
|
276
|
+
}
|
|
277
|
+
async function readLockMetadata(lockPath) {
|
|
278
|
+
const metadataPath = path10__default.default.join(lockPath, LOCK_METADATA_FILENAME);
|
|
279
|
+
if (!await pathExists(metadataPath)) {
|
|
280
|
+
return void 0;
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
const parsed = await readJsonFile(metadataPath);
|
|
284
|
+
const pid = parsed.pid;
|
|
285
|
+
const acquiredAt = parsed.acquiredAt;
|
|
286
|
+
const heartbeatAt = parsed.heartbeatAt;
|
|
287
|
+
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)) {
|
|
288
|
+
return void 0;
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
version: LOCK_METADATA_VERSION,
|
|
292
|
+
ownerToken: parsed.ownerToken,
|
|
293
|
+
pid,
|
|
294
|
+
acquiredAt,
|
|
295
|
+
heartbeatAt
|
|
296
|
+
};
|
|
297
|
+
} catch {
|
|
298
|
+
return void 0;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
async function writeLockMetadata(lockPath, metadata) {
|
|
302
|
+
try {
|
|
303
|
+
await writeJsonFileAtomic(path10__default.default.join(lockPath, LOCK_METADATA_FILENAME), metadata);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
await promises.rm(lockPath, { recursive: true, force: true }).catch(() => void 0);
|
|
306
|
+
throw error;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
async function touchLockMetadata(lockPath, ownerToken) {
|
|
310
|
+
const metadata = await readLockMetadata(lockPath);
|
|
311
|
+
if (metadata === void 0 || metadata.ownerToken !== ownerToken) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
await writeJsonFileAtomic(path10__default.default.join(lockPath, LOCK_METADATA_FILENAME), {
|
|
315
|
+
...metadata,
|
|
316
|
+
heartbeatAt: Date.now()
|
|
317
|
+
}).catch(() => void 0);
|
|
318
|
+
}
|
|
319
|
+
function isProcessRunning(pid) {
|
|
320
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
process.kill(pid, 0);
|
|
325
|
+
return true;
|
|
326
|
+
} catch (error) {
|
|
327
|
+
return error?.code === "EPERM";
|
|
228
328
|
}
|
|
229
329
|
}
|
|
230
330
|
|
|
@@ -814,7 +914,7 @@ function isJsonValueEqual(expected, actual) {
|
|
|
814
914
|
|
|
815
915
|
// ../protocol/src/version.ts
|
|
816
916
|
var OPENSTEER_PROTOCOL_NAME = "opensteer";
|
|
817
|
-
var OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION =
|
|
917
|
+
var OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION = 3;
|
|
818
918
|
var OPENSTEER_PROTOCOL_VERSION = `0.${OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION}.0`;
|
|
819
919
|
var OPENSTEER_PROTOCOL_REST_BASE_PATH = `/api/v${OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION}`;
|
|
820
920
|
objectSchema(
|
|
@@ -1037,9 +1137,6 @@ function isBrowserCoreError(value) {
|
|
|
1037
1137
|
return value instanceof BrowserCoreError;
|
|
1038
1138
|
}
|
|
1039
1139
|
|
|
1040
|
-
// ../browser-core/src/cdp-visual-stability.ts
|
|
1041
|
-
var DEFAULT_VISUAL_STABILITY_SETTLE_MS = 750;
|
|
1042
|
-
|
|
1043
1140
|
// ../browser-core/src/post-load-tracker.ts
|
|
1044
1141
|
var DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS = 400;
|
|
1045
1142
|
|
|
@@ -1191,7 +1288,7 @@ var visualViewportSchema = objectSchema(
|
|
|
1191
1288
|
required: ["origin", "offsetWithinLayoutViewport", "size"]
|
|
1192
1289
|
}
|
|
1193
1290
|
);
|
|
1194
|
-
|
|
1291
|
+
objectSchema(
|
|
1195
1292
|
{
|
|
1196
1293
|
layoutViewport: layoutViewportSchema,
|
|
1197
1294
|
visualViewport: visualViewportSchema,
|
|
@@ -2642,7 +2739,7 @@ var domSnapshotSchema = objectSchema(
|
|
|
2642
2739
|
]
|
|
2643
2740
|
}
|
|
2644
2741
|
);
|
|
2645
|
-
|
|
2742
|
+
objectSchema(
|
|
2646
2743
|
{
|
|
2647
2744
|
inputPoint: pointSchema,
|
|
2648
2745
|
inputCoordinateSpace: coordinateSpaceSchema,
|
|
@@ -4095,39 +4192,14 @@ var opensteerTargetInputSchema = oneOfSchema(
|
|
|
4095
4192
|
title: "OpensteerTargetInput"
|
|
4096
4193
|
}
|
|
4097
4194
|
);
|
|
4098
|
-
var opensteerResolvedTargetSchema = objectSchema(
|
|
4099
|
-
{
|
|
4100
|
-
pageRef: pageRefSchema,
|
|
4101
|
-
frameRef: frameRefSchema,
|
|
4102
|
-
documentRef: documentRefSchema,
|
|
4103
|
-
documentEpoch: documentEpochSchema,
|
|
4104
|
-
nodeRef: nodeRefSchema,
|
|
4105
|
-
tagName: stringSchema(),
|
|
4106
|
-
pathHint: stringSchema(),
|
|
4107
|
-
persist: stringSchema(),
|
|
4108
|
-
selectorUsed: stringSchema()
|
|
4109
|
-
},
|
|
4110
|
-
{
|
|
4111
|
-
title: "OpensteerResolvedTarget",
|
|
4112
|
-
required: [
|
|
4113
|
-
"pageRef",
|
|
4114
|
-
"frameRef",
|
|
4115
|
-
"documentRef",
|
|
4116
|
-
"documentEpoch",
|
|
4117
|
-
"nodeRef",
|
|
4118
|
-
"tagName",
|
|
4119
|
-
"pathHint"
|
|
4120
|
-
]
|
|
4121
|
-
}
|
|
4122
|
-
);
|
|
4123
4195
|
var opensteerActionResultSchema = objectSchema(
|
|
4124
4196
|
{
|
|
4125
|
-
|
|
4126
|
-
|
|
4197
|
+
tagName: stringSchema({ minLength: 1 }),
|
|
4198
|
+
persist: stringSchema({ minLength: 1 })
|
|
4127
4199
|
},
|
|
4128
4200
|
{
|
|
4129
4201
|
title: "OpensteerActionResult",
|
|
4130
|
-
required: ["
|
|
4202
|
+
required: ["tagName"]
|
|
4131
4203
|
}
|
|
4132
4204
|
);
|
|
4133
4205
|
var opensteerSnapshotCounterSchema = objectSchema(
|
|
@@ -4173,16 +4245,14 @@ var opensteerSnapshotCounterSchema = objectSchema(
|
|
|
4173
4245
|
]
|
|
4174
4246
|
}
|
|
4175
4247
|
);
|
|
4176
|
-
var
|
|
4248
|
+
var opensteerNavigationSummarySchema = objectSchema(
|
|
4177
4249
|
{
|
|
4178
|
-
sessionRef: sessionRefSchema,
|
|
4179
|
-
pageRef: pageRefSchema,
|
|
4180
4250
|
url: stringSchema(),
|
|
4181
4251
|
title: stringSchema()
|
|
4182
4252
|
},
|
|
4183
4253
|
{
|
|
4184
|
-
title: "
|
|
4185
|
-
required: ["
|
|
4254
|
+
title: "OpensteerNavigationSummary",
|
|
4255
|
+
required: ["url", "title"]
|
|
4186
4256
|
}
|
|
4187
4257
|
);
|
|
4188
4258
|
var opensteerOpenInputSchema = objectSchema(
|
|
@@ -4250,6 +4320,17 @@ var opensteerPageCloseOutputSchema = objectSchema(
|
|
|
4250
4320
|
required: ["closedPageRef", "pages"]
|
|
4251
4321
|
}
|
|
4252
4322
|
);
|
|
4323
|
+
var opensteerPageNewOutputSchema = objectSchema(
|
|
4324
|
+
{
|
|
4325
|
+
pageRef: pageRefSchema,
|
|
4326
|
+
url: stringSchema(),
|
|
4327
|
+
title: stringSchema()
|
|
4328
|
+
},
|
|
4329
|
+
{
|
|
4330
|
+
title: "OpensteerPageNewOutput",
|
|
4331
|
+
required: ["pageRef", "url", "title"]
|
|
4332
|
+
}
|
|
4333
|
+
);
|
|
4253
4334
|
var opensteerPageGotoInputSchema = objectSchema(
|
|
4254
4335
|
{
|
|
4255
4336
|
url: stringSchema(),
|
|
@@ -4636,72 +4717,28 @@ var opensteerComputerExecuteInputSchema = objectSchema(
|
|
|
4636
4717
|
required: ["action"]
|
|
4637
4718
|
}
|
|
4638
4719
|
);
|
|
4639
|
-
var
|
|
4640
|
-
{
|
|
4641
|
-
role: enumSchema(["point", "start", "end"]),
|
|
4642
|
-
point: pointSchema,
|
|
4643
|
-
hitTest: hitTestResultSchema,
|
|
4644
|
-
target: opensteerResolvedTargetSchema
|
|
4645
|
-
},
|
|
4646
|
-
{
|
|
4647
|
-
title: "OpensteerComputerTracePoint",
|
|
4648
|
-
required: ["role", "point"]
|
|
4649
|
-
}
|
|
4650
|
-
);
|
|
4651
|
-
var opensteerComputerTraceEnrichmentSchema = objectSchema(
|
|
4652
|
-
{
|
|
4653
|
-
points: arraySchema(opensteerComputerTracePointSchema)
|
|
4654
|
-
},
|
|
4655
|
-
{
|
|
4656
|
-
title: "OpensteerComputerTraceEnrichment",
|
|
4657
|
-
required: ["points"]
|
|
4658
|
-
}
|
|
4659
|
-
);
|
|
4660
|
-
var opensteerComputerExecuteTimingSchema = objectSchema(
|
|
4720
|
+
var opensteerScreenshotSummarySchema = objectSchema(
|
|
4661
4721
|
{
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
title: "OpensteerComputerExecuteTiming",
|
|
4668
|
-
required: ["actionMs", "waitMs", "totalMs"]
|
|
4669
|
-
}
|
|
4670
|
-
);
|
|
4671
|
-
var opensteerComputerDisplayScaleSchema = objectSchema(
|
|
4672
|
-
{
|
|
4673
|
-
x: numberSchema({ exclusiveMinimum: 0 }),
|
|
4674
|
-
y: numberSchema({ exclusiveMinimum: 0 })
|
|
4722
|
+
payload: externalBinaryLocationSchema,
|
|
4723
|
+
format: screenshotFormatSchema,
|
|
4724
|
+
size: sizeSchema,
|
|
4725
|
+
coordinateSpace: coordinateSpaceSchema,
|
|
4726
|
+
clip: rectSchema
|
|
4675
4727
|
},
|
|
4676
4728
|
{
|
|
4677
|
-
title: "
|
|
4678
|
-
required: ["
|
|
4729
|
+
title: "OpensteerScreenshotSummary",
|
|
4730
|
+
required: ["payload", "format", "size", "coordinateSpace"]
|
|
4679
4731
|
}
|
|
4680
4732
|
);
|
|
4681
4733
|
var opensteerComputerExecuteOutputSchema = objectSchema(
|
|
4682
4734
|
{
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
screenshot:
|
|
4686
|
-
displayViewport: viewportMetricsSchema,
|
|
4687
|
-
nativeViewport: viewportMetricsSchema,
|
|
4688
|
-
displayScale: opensteerComputerDisplayScaleSchema,
|
|
4689
|
-
events: arraySchema(opensteerEventSchema),
|
|
4690
|
-
timing: opensteerComputerExecuteTimingSchema,
|
|
4691
|
-
trace: opensteerComputerTraceEnrichmentSchema
|
|
4735
|
+
url: stringSchema(),
|
|
4736
|
+
title: stringSchema(),
|
|
4737
|
+
screenshot: opensteerScreenshotSummarySchema
|
|
4692
4738
|
},
|
|
4693
4739
|
{
|
|
4694
4740
|
title: "OpensteerComputerExecuteOutput",
|
|
4695
|
-
required: [
|
|
4696
|
-
"action",
|
|
4697
|
-
"pageRef",
|
|
4698
|
-
"screenshot",
|
|
4699
|
-
"displayViewport",
|
|
4700
|
-
"nativeViewport",
|
|
4701
|
-
"displayScale",
|
|
4702
|
-
"events",
|
|
4703
|
-
"timing"
|
|
4704
|
-
]
|
|
4741
|
+
required: ["url", "title", "screenshot"]
|
|
4705
4742
|
}
|
|
4706
4743
|
);
|
|
4707
4744
|
function assertValidSemanticOperationInput(name, input) {
|
|
@@ -4727,7 +4764,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4727
4764
|
name: "session.open",
|
|
4728
4765
|
description: "Open or resume the current Opensteer session and primary page.",
|
|
4729
4766
|
inputSchema: opensteerOpenInputSchema,
|
|
4730
|
-
outputSchema:
|
|
4767
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
4731
4768
|
requiredCapabilities: ["sessions.manage", "pages.manage"],
|
|
4732
4769
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["sessions.manage", "pages.manage"] : ["sessions.manage", "pages.manage", "pages.navigate"]
|
|
4733
4770
|
}),
|
|
@@ -4742,7 +4779,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4742
4779
|
name: "page.new",
|
|
4743
4780
|
description: "Create and optionally navigate a new top-level page in the current session.",
|
|
4744
4781
|
inputSchema: opensteerPageNewInputSchema,
|
|
4745
|
-
outputSchema:
|
|
4782
|
+
outputSchema: opensteerPageNewOutputSchema,
|
|
4746
4783
|
requiredCapabilities: ["pages.manage"],
|
|
4747
4784
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["pages.manage"] : ["pages.manage", "pages.navigate"]
|
|
4748
4785
|
}),
|
|
@@ -4750,7 +4787,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4750
4787
|
name: "page.activate",
|
|
4751
4788
|
description: "Activate an existing top-level page in the current session.",
|
|
4752
4789
|
inputSchema: opensteerPageActivateInputSchema,
|
|
4753
|
-
outputSchema:
|
|
4790
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
4754
4791
|
requiredCapabilities: ["pages.manage", "inspect.pages"]
|
|
4755
4792
|
}),
|
|
4756
4793
|
defineSemanticOperationSpec({
|
|
@@ -4764,7 +4801,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4764
4801
|
name: "page.goto",
|
|
4765
4802
|
description: "Navigate the current Opensteer page to a new URL.",
|
|
4766
4803
|
inputSchema: opensteerPageGotoInputSchema,
|
|
4767
|
-
outputSchema:
|
|
4804
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
4768
4805
|
requiredCapabilities: ["pages.navigate"]
|
|
4769
4806
|
}),
|
|
4770
4807
|
defineSemanticOperationSpec({
|
|
@@ -6845,30 +6882,15 @@ var DEFAULT_SETTLE_DELAYS = {
|
|
|
6845
6882
|
"dom-action": 100,
|
|
6846
6883
|
snapshot: 0
|
|
6847
6884
|
};
|
|
6848
|
-
var defaultSnapshotSettleObserver = {
|
|
6849
|
-
async settle(input) {
|
|
6850
|
-
if (input.trigger !== "snapshot") {
|
|
6851
|
-
return false;
|
|
6852
|
-
}
|
|
6853
|
-
await input.engine.waitForVisualStability({
|
|
6854
|
-
pageRef: input.pageRef,
|
|
6855
|
-
...input.remainingMs === void 0 ? {} : { timeoutMs: input.remainingMs },
|
|
6856
|
-
settleMs: DEFAULT_VISUAL_STABILITY_SETTLE_MS,
|
|
6857
|
-
scope: "visible-frames"
|
|
6858
|
-
});
|
|
6859
|
-
return true;
|
|
6860
|
-
}
|
|
6861
|
-
};
|
|
6862
|
-
Object.freeze(defaultSnapshotSettleObserver);
|
|
6863
6885
|
var DOM_ACTION_VISUAL_STABILITY_PROFILES = {
|
|
6864
|
-
"dom.click": { settleMs: 750, scope: "
|
|
6865
|
-
"dom.input": { settleMs: 750, scope: "
|
|
6866
|
-
"dom.scroll": { settleMs: 600, scope: "
|
|
6886
|
+
"dom.click": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
6887
|
+
"dom.input": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
6888
|
+
"dom.scroll": { settleMs: 600, scope: "main-frame", timeoutMs: 7e3 },
|
|
6867
6889
|
"dom.hover": { settleMs: 200, scope: "main-frame", timeoutMs: 2500 }
|
|
6868
6890
|
};
|
|
6869
6891
|
var DEFAULT_DOM_ACTION_VISUAL_STABILITY_PROFILE = {
|
|
6870
6892
|
settleMs: 750,
|
|
6871
|
-
scope: "
|
|
6893
|
+
scope: "main-frame",
|
|
6872
6894
|
timeoutMs: 7e3
|
|
6873
6895
|
};
|
|
6874
6896
|
var NAVIGATION_VISUAL_STABILITY_PROFILE = {
|
|
@@ -6892,6 +6914,7 @@ var defaultDomActionSettleObserver = {
|
|
|
6892
6914
|
pageRef: input.pageRef,
|
|
6893
6915
|
timeoutMs: effectiveTimeout,
|
|
6894
6916
|
settleMs: profile.settleMs,
|
|
6917
|
+
...input.observedMutationQuietMs === void 0 ? {} : { initialQuietMs: input.observedMutationQuietMs },
|
|
6895
6918
|
scope: profile.scope
|
|
6896
6919
|
});
|
|
6897
6920
|
return true;
|
|
@@ -6912,15 +6935,20 @@ var defaultNavigationSettleObserver = {
|
|
|
6912
6935
|
return false;
|
|
6913
6936
|
}
|
|
6914
6937
|
try {
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6938
|
+
let visualTimeout = effectiveTimeout;
|
|
6939
|
+
let initialQuietMs = input.observedMutationQuietMs ?? 0;
|
|
6940
|
+
if (!input.postLoadHandled) {
|
|
6941
|
+
const startedAt = Date.now();
|
|
6942
|
+
await input.engine.waitForPostLoadQuiet({
|
|
6943
|
+
pageRef: input.pageRef,
|
|
6944
|
+
timeoutMs: effectiveTimeout,
|
|
6945
|
+
quietMs: DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS,
|
|
6946
|
+
captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
|
|
6947
|
+
signal: input.signal
|
|
6948
|
+
});
|
|
6949
|
+
visualTimeout = Math.max(0, effectiveTimeout - (Date.now() - startedAt));
|
|
6950
|
+
initialQuietMs = Math.max(initialQuietMs, DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS);
|
|
6951
|
+
}
|
|
6924
6952
|
if (visualTimeout <= 0) {
|
|
6925
6953
|
return true;
|
|
6926
6954
|
}
|
|
@@ -6928,6 +6956,7 @@ var defaultNavigationSettleObserver = {
|
|
|
6928
6956
|
pageRef: input.pageRef,
|
|
6929
6957
|
timeoutMs: visualTimeout,
|
|
6930
6958
|
settleMs: profile.settleMs,
|
|
6959
|
+
...initialQuietMs <= 0 ? {} : { initialQuietMs },
|
|
6931
6960
|
scope: profile.scope
|
|
6932
6961
|
});
|
|
6933
6962
|
return true;
|
|
@@ -6938,7 +6967,6 @@ var defaultNavigationSettleObserver = {
|
|
|
6938
6967
|
};
|
|
6939
6968
|
Object.freeze(defaultNavigationSettleObserver);
|
|
6940
6969
|
var DEFAULT_SETTLE_OBSERVERS = Object.freeze([
|
|
6941
|
-
defaultSnapshotSettleObserver,
|
|
6942
6970
|
defaultDomActionSettleObserver,
|
|
6943
6971
|
defaultNavigationSettleObserver
|
|
6944
6972
|
]);
|
|
@@ -7391,6 +7419,9 @@ function buildClauseSelector(node, clause) {
|
|
|
7391
7419
|
if (!clause || typeof clause !== "object") {
|
|
7392
7420
|
return "";
|
|
7393
7421
|
}
|
|
7422
|
+
if (clause.kind === "text") {
|
|
7423
|
+
return "";
|
|
7424
|
+
}
|
|
7394
7425
|
if (clause.kind === "position") {
|
|
7395
7426
|
if (clause.axis === "nthOfType") {
|
|
7396
7427
|
return `:nth-of-type(${Math.max(1, Number(node.position?.nthOfType || 1))})`;
|
|
@@ -7515,7 +7546,7 @@ function resolveExtractedValueInContext(normalizedValue, options) {
|
|
|
7515
7546
|
function stripPositionClauses(nodes) {
|
|
7516
7547
|
return (nodes || []).map((node) => ({
|
|
7517
7548
|
...node,
|
|
7518
|
-
match: (node.match || []).filter((clause) => clause.kind !== "position")
|
|
7549
|
+
match: (node.match || []).filter((clause) => clause.kind !== "position" && clause.kind !== "text")
|
|
7519
7550
|
}));
|
|
7520
7551
|
}
|
|
7521
7552
|
function dedupeSelectors(selectors) {
|
|
@@ -8092,9 +8123,17 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
8092
8123
|
if (!candidates.length) {
|
|
8093
8124
|
return null;
|
|
8094
8125
|
}
|
|
8126
|
+
const lastNode = domPath[domPath.length - 1];
|
|
8127
|
+
const textClauses = lastNode?.match.filter((c) => c.kind === "text") ?? [];
|
|
8095
8128
|
let fallback = null;
|
|
8096
8129
|
for (const selector of candidates) {
|
|
8097
|
-
|
|
8130
|
+
let matches = querySelectorAllInScope(index, selector, scope);
|
|
8131
|
+
if (textClauses.length > 0 && matches.length > 1) {
|
|
8132
|
+
const filtered = matches.filter((node) => matchesTextClauses(node, textClauses));
|
|
8133
|
+
if (filtered.length > 0) {
|
|
8134
|
+
matches = filtered;
|
|
8135
|
+
}
|
|
8136
|
+
}
|
|
8098
8137
|
if (matches.length === 1) {
|
|
8099
8138
|
return {
|
|
8100
8139
|
node: matches[0],
|
|
@@ -8114,6 +8153,10 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
8114
8153
|
}
|
|
8115
8154
|
return fallback;
|
|
8116
8155
|
}
|
|
8156
|
+
function matchesTextClauses(node, clauses) {
|
|
8157
|
+
const text = (node.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
8158
|
+
return clauses.every((clause) => text.includes(clause.value));
|
|
8159
|
+
}
|
|
8117
8160
|
function queryAllDomPathInScope(index, domPath, scope) {
|
|
8118
8161
|
const selectors = buildPathCandidates(domPath);
|
|
8119
8162
|
for (const selector of selectors) {
|
|
@@ -8272,7 +8315,13 @@ function clonePathNode(node) {
|
|
|
8272
8315
|
};
|
|
8273
8316
|
}
|
|
8274
8317
|
function cloneMatchClause(clause) {
|
|
8275
|
-
|
|
8318
|
+
if (clause.kind === "position") {
|
|
8319
|
+
return { kind: "position", axis: clause.axis };
|
|
8320
|
+
}
|
|
8321
|
+
if (clause.kind === "text") {
|
|
8322
|
+
return { kind: "text", value: clause.value };
|
|
8323
|
+
}
|
|
8324
|
+
return {
|
|
8276
8325
|
kind: "attr",
|
|
8277
8326
|
key: clause.key,
|
|
8278
8327
|
...clause.op === void 0 ? {} : { op: clause.op },
|
|
@@ -8327,6 +8376,13 @@ function normalizeMatch(rawMatch, attrs, position, tag) {
|
|
|
8327
8376
|
op,
|
|
8328
8377
|
...value === void 0 ? {} : { value }
|
|
8329
8378
|
});
|
|
8379
|
+
continue;
|
|
8380
|
+
}
|
|
8381
|
+
if (record.kind === "text") {
|
|
8382
|
+
const textValue = typeof record.value === "string" ? record.value.trim() : "";
|
|
8383
|
+
if (textValue) {
|
|
8384
|
+
push({ kind: "text", value: textValue.slice(0, 80) });
|
|
8385
|
+
}
|
|
8330
8386
|
}
|
|
8331
8387
|
}
|
|
8332
8388
|
}
|
|
@@ -8694,7 +8750,7 @@ function isTimeoutError(error) {
|
|
|
8694
8750
|
}
|
|
8695
8751
|
|
|
8696
8752
|
// ../runtime-core/src/runtimes/dom/executor.ts
|
|
8697
|
-
var MAX_DOM_ACTION_ATTEMPTS =
|
|
8753
|
+
var MAX_DOM_ACTION_ATTEMPTS = 2;
|
|
8698
8754
|
var DEFAULT_SCROLL_OPTIONS = {
|
|
8699
8755
|
block: "center",
|
|
8700
8756
|
inline: "center"
|
|
@@ -8984,7 +9040,7 @@ var DomActionExecutor = class {
|
|
|
8984
9040
|
...snapshot === void 0 ? {} : { snapshot },
|
|
8985
9041
|
signal: timeout.signal,
|
|
8986
9042
|
remainingMs: () => timeout.remainingMs(),
|
|
8987
|
-
policySettle: async (targetPageRef, trigger) => {
|
|
9043
|
+
policySettle: async (targetPageRef, trigger, boundary2) => {
|
|
8988
9044
|
try {
|
|
8989
9045
|
await settleWithPolicy(this.options.policy.settle, {
|
|
8990
9046
|
operation,
|
|
@@ -8992,7 +9048,9 @@ var DomActionExecutor = class {
|
|
|
8992
9048
|
engine: this.options.engine,
|
|
8993
9049
|
pageRef: targetPageRef,
|
|
8994
9050
|
signal: timeout.signal,
|
|
8995
|
-
remainingMs: timeout.remainingMs()
|
|
9051
|
+
remainingMs: timeout.remainingMs(),
|
|
9052
|
+
...boundary2?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary2.observedMutationQuietMs },
|
|
9053
|
+
...boundary2?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
8996
9054
|
});
|
|
8997
9055
|
} catch (error) {
|
|
8998
9056
|
if (snapshot !== void 0 && isSoftSettleTimeoutError(error, timeout.signal)) {
|
|
@@ -9181,11 +9239,12 @@ var DomActionExecutor = class {
|
|
|
9181
9239
|
throw this.createActionabilityError(
|
|
9182
9240
|
operation,
|
|
9183
9241
|
"obscured",
|
|
9184
|
-
`
|
|
9242
|
+
`target is obscured by ${assessment.blockingDescription ?? "another element"} at the click point`,
|
|
9185
9243
|
{
|
|
9186
9244
|
...details,
|
|
9187
9245
|
hitRelation: assessment.relation,
|
|
9188
9246
|
...assessment.ambiguous === void 0 ? {} : { hitAmbiguous: assessment.ambiguous },
|
|
9247
|
+
...assessment.blockingDescription === void 0 ? {} : { blockingDescription: assessment.blockingDescription },
|
|
9189
9248
|
...assessment.canonicalTarget === void 0 ? {} : {
|
|
9190
9249
|
canonicalNodeRef: assessment.canonicalTarget.nodeRef,
|
|
9191
9250
|
canonicalDocumentRef: assessment.canonicalTarget.documentRef,
|
|
@@ -9199,8 +9258,7 @@ var DomActionExecutor = class {
|
|
|
9199
9258
|
hitMissingFromSnapshot: !resolved.snapshot.nodes.some(
|
|
9200
9259
|
(node) => node.nodeRef === hit.nodeRef
|
|
9201
9260
|
)
|
|
9202
|
-
}
|
|
9203
|
-
true
|
|
9261
|
+
}
|
|
9204
9262
|
);
|
|
9205
9263
|
}
|
|
9206
9264
|
async resolveActionablePointerTarget(session, operation, resolved) {
|
|
@@ -9412,7 +9470,12 @@ var DefaultDomRuntime = class {
|
|
|
9412
9470
|
});
|
|
9413
9471
|
}
|
|
9414
9472
|
async buildPath(input) {
|
|
9415
|
-
return sanitizeReplayElementPath(
|
|
9473
|
+
return sanitizeReplayElementPath(
|
|
9474
|
+
await this.requireBridge().buildReplayPath(
|
|
9475
|
+
input.locator,
|
|
9476
|
+
input.enableTextMatch ? { enableTextMatch: true } : void 0
|
|
9477
|
+
)
|
|
9478
|
+
);
|
|
9416
9479
|
}
|
|
9417
9480
|
async resolveTarget(input) {
|
|
9418
9481
|
return this.withSnapshotSession((session) => this.resolveTargetWithSession(session, input));
|
|
@@ -9632,7 +9695,7 @@ var DefaultDomRuntime = class {
|
|
|
9632
9695
|
if (resolvedByLocator) {
|
|
9633
9696
|
const { snapshot, node } = resolvedByLocator;
|
|
9634
9697
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
9635
|
-
const replayPath = await this.tryBuildPathFromNode(snapshot, node);
|
|
9698
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch: true });
|
|
9636
9699
|
return this.createResolvedTarget("live", snapshot, node, anchor, {
|
|
9637
9700
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
9638
9701
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -9650,11 +9713,12 @@ var DefaultDomRuntime = class {
|
|
|
9650
9713
|
const { snapshot, node } = resolved;
|
|
9651
9714
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
9652
9715
|
const writeDescriptor = descriptorWriter ?? ((input) => this.descriptors.write(input));
|
|
9653
|
-
const
|
|
9716
|
+
const enableTextMatch = method !== "extract";
|
|
9717
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch });
|
|
9654
9718
|
const descriptor = target.persist === void 0 ? void 0 : await writeDescriptor({
|
|
9655
9719
|
method,
|
|
9656
9720
|
persist: target.persist,
|
|
9657
|
-
path: replayPath ?? await this.buildPathForNode(snapshot, node),
|
|
9721
|
+
path: replayPath ?? await this.buildPathForNode(snapshot, node, { enableTextMatch }),
|
|
9658
9722
|
sourceUrl: snapshot.url
|
|
9659
9723
|
});
|
|
9660
9724
|
return this.createResolvedTarget("selector", snapshot, node, anchor, {
|
|
@@ -9754,7 +9818,7 @@ var DefaultDomRuntime = class {
|
|
|
9754
9818
|
`Unable to resolve structural anchor "${buildPathSelectorHint(anchor)}" in the current session`
|
|
9755
9819
|
);
|
|
9756
9820
|
}
|
|
9757
|
-
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node);
|
|
9821
|
+
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, { enableTextMatch: true });
|
|
9758
9822
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
9759
9823
|
...persist === void 0 ? {} : { persist },
|
|
9760
9824
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -9925,19 +9989,20 @@ var DefaultDomRuntime = class {
|
|
|
9925
9989
|
}
|
|
9926
9990
|
return this.bridge;
|
|
9927
9991
|
}
|
|
9928
|
-
async buildPathForNode(snapshot, node) {
|
|
9992
|
+
async buildPathForNode(snapshot, node, options) {
|
|
9929
9993
|
if (node.nodeRef === void 0) {
|
|
9930
9994
|
throw new Error(
|
|
9931
9995
|
`snapshot node ${String(node.snapshotNodeId)} does not expose a live node reference`
|
|
9932
9996
|
);
|
|
9933
9997
|
}
|
|
9934
9998
|
return this.buildPath({
|
|
9935
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef)
|
|
9999
|
+
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
10000
|
+
...options?.enableTextMatch ? { enableTextMatch: true } : {}
|
|
9936
10001
|
});
|
|
9937
10002
|
}
|
|
9938
|
-
async tryBuildPathFromNode(snapshot, node) {
|
|
10003
|
+
async tryBuildPathFromNode(snapshot, node, options) {
|
|
9939
10004
|
try {
|
|
9940
|
-
return await this.buildPathForNode(snapshot, node);
|
|
10005
|
+
return await this.buildPathForNode(snapshot, node, options);
|
|
9941
10006
|
} catch {
|
|
9942
10007
|
return void 0;
|
|
9943
10008
|
}
|
|
@@ -10373,29 +10438,29 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
10373
10438
|
const keyStats = /* @__PURE__ */ new Map();
|
|
10374
10439
|
for (const descriptor of descriptors) {
|
|
10375
10440
|
for (const field of descriptor.fields) {
|
|
10376
|
-
const
|
|
10441
|
+
const stat3 = keyStats.get(field.path) ?? {
|
|
10377
10442
|
indices: /* @__PURE__ */ new Set(),
|
|
10378
10443
|
pathNodes: [],
|
|
10379
10444
|
attributes: [],
|
|
10380
10445
|
sources: []
|
|
10381
10446
|
};
|
|
10382
|
-
|
|
10447
|
+
stat3.indices.add(descriptor.index);
|
|
10383
10448
|
if (isPersistedOpensteerExtractionValueNode(field.node)) {
|
|
10384
|
-
|
|
10385
|
-
|
|
10449
|
+
stat3.pathNodes.push(field.node.$path);
|
|
10450
|
+
stat3.attributes.push(field.node.attribute);
|
|
10386
10451
|
} else if (isPersistedOpensteerExtractionSourceNode(field.node)) {
|
|
10387
|
-
|
|
10452
|
+
stat3.sources.push("current_url");
|
|
10388
10453
|
}
|
|
10389
|
-
keyStats.set(field.path,
|
|
10454
|
+
keyStats.set(field.path, stat3);
|
|
10390
10455
|
}
|
|
10391
10456
|
}
|
|
10392
10457
|
const mergedFields = [];
|
|
10393
|
-
for (const [fieldPath,
|
|
10394
|
-
if (
|
|
10458
|
+
for (const [fieldPath, stat3] of keyStats) {
|
|
10459
|
+
if (stat3.indices.size < threshold) {
|
|
10395
10460
|
continue;
|
|
10396
10461
|
}
|
|
10397
|
-
if (
|
|
10398
|
-
let mergedFieldPath =
|
|
10462
|
+
if (stat3.pathNodes.length >= threshold) {
|
|
10463
|
+
let mergedFieldPath = stat3.pathNodes.length === 1 ? sanitizeElementPath(stat3.pathNodes[0]) : mergeElementPathsByMajority(stat3.pathNodes);
|
|
10399
10464
|
if (!mergedFieldPath) {
|
|
10400
10465
|
continue;
|
|
10401
10466
|
}
|
|
@@ -10403,8 +10468,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
10403
10468
|
mergedFieldPath = relaxPathForSingleSample(mergedFieldPath, "field");
|
|
10404
10469
|
}
|
|
10405
10470
|
mergedFieldPath = minimizePathMatchClauses(mergedFieldPath, "field");
|
|
10406
|
-
const attrThreshold =
|
|
10407
|
-
const attribute = pickModeString(
|
|
10471
|
+
const attrThreshold = stat3.pathNodes.length === 1 ? 1 : majorityThreshold(stat3.pathNodes.length);
|
|
10472
|
+
const attribute = pickModeString(stat3.attributes, attrThreshold);
|
|
10408
10473
|
mergedFields.push({
|
|
10409
10474
|
path: fieldPath,
|
|
10410
10475
|
node: createValueNode({
|
|
@@ -10414,7 +10479,7 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
10414
10479
|
});
|
|
10415
10480
|
continue;
|
|
10416
10481
|
}
|
|
10417
|
-
const dominantSource = pickModeString(
|
|
10482
|
+
const dominantSource = pickModeString(stat3.sources, threshold);
|
|
10418
10483
|
if (dominantSource === "current_url") {
|
|
10419
10484
|
mergedFields.push({
|
|
10420
10485
|
path: fieldPath,
|
|
@@ -10551,6 +10616,9 @@ function relaxPathForSingleSample(path18, mode) {
|
|
|
10551
10616
|
}
|
|
10552
10617
|
return !isLast;
|
|
10553
10618
|
}
|
|
10619
|
+
if (clause.kind === "text") {
|
|
10620
|
+
return false;
|
|
10621
|
+
}
|
|
10554
10622
|
const key = String(clause.key || "").trim().toLowerCase();
|
|
10555
10623
|
if (!key || !shouldKeepAttrForSingleSample(key)) {
|
|
10556
10624
|
return false;
|
|
@@ -10653,9 +10721,11 @@ function buildNodeStructure(node) {
|
|
|
10653
10721
|
}
|
|
10654
10722
|
structuralAttrs[key] = value;
|
|
10655
10723
|
}
|
|
10656
|
-
const matchClauses = (node.match || []).map(
|
|
10657
|
-
(clause
|
|
10658
|
-
|
|
10724
|
+
const matchClauses = (node.match || []).map((clause) => {
|
|
10725
|
+
if (clause.kind === "position") return `position:${clause.axis}`;
|
|
10726
|
+
if (clause.kind === "text") return `text:${clause.value}`;
|
|
10727
|
+
return `attr:${String(clause.key || "").trim().toLowerCase()}`;
|
|
10728
|
+
}).sort();
|
|
10659
10729
|
return {
|
|
10660
10730
|
tag,
|
|
10661
10731
|
attrs: structuralAttrs,
|
|
@@ -11061,6 +11131,9 @@ function mergeMatchByMajority(matchLists, attrs, threshold, positionFlags = {
|
|
|
11061
11131
|
});
|
|
11062
11132
|
continue;
|
|
11063
11133
|
}
|
|
11134
|
+
if (clause.kind === "text") {
|
|
11135
|
+
continue;
|
|
11136
|
+
}
|
|
11064
11137
|
if (clause.axis === "nthOfType") {
|
|
11065
11138
|
if (positionFlags.hasNthOfType) {
|
|
11066
11139
|
merged.push({ kind: "position", axis: "nthOfType" });
|
|
@@ -11989,9 +12062,9 @@ async function getProcessLiveness(owner) {
|
|
|
11989
12062
|
if (typeof startedAtMs === "number") {
|
|
11990
12063
|
return hasMatchingProcessStartTime(owner.processStartedAtMs, startedAtMs) ? "live" : "dead";
|
|
11991
12064
|
}
|
|
11992
|
-
return
|
|
12065
|
+
return isProcessRunning2(owner.pid) ? "unknown" : "dead";
|
|
11993
12066
|
}
|
|
11994
|
-
function
|
|
12067
|
+
function isProcessRunning2(pid) {
|
|
11995
12068
|
try {
|
|
11996
12069
|
process.kill(pid, 0);
|
|
11997
12070
|
return true;
|
|
@@ -13411,11 +13484,31 @@ async function writePersistedSessionRecord(rootPath, record) {
|
|
|
13411
13484
|
async function clearPersistedSessionRecord(rootPath, provider) {
|
|
13412
13485
|
await promises.rm(resolveLiveSessionRecordPath(rootPath, provider), { force: true });
|
|
13413
13486
|
}
|
|
13487
|
+
function getPersistedLocalBrowserSessionOwnership(record) {
|
|
13488
|
+
return record.ownership === "attached" ? "attached" : "owned";
|
|
13489
|
+
}
|
|
13490
|
+
async function isAttachedLocalBrowserSessionReachable(record) {
|
|
13491
|
+
if (getPersistedLocalBrowserSessionOwnership(record) !== "attached") {
|
|
13492
|
+
return false;
|
|
13493
|
+
}
|
|
13494
|
+
if (record.engine !== "playwright" || record.endpoint === void 0) {
|
|
13495
|
+
return false;
|
|
13496
|
+
}
|
|
13497
|
+
try {
|
|
13498
|
+
await inspectCdpEndpoint({
|
|
13499
|
+
endpoint: record.endpoint,
|
|
13500
|
+
timeoutMs: 1500
|
|
13501
|
+
});
|
|
13502
|
+
return true;
|
|
13503
|
+
} catch {
|
|
13504
|
+
return false;
|
|
13505
|
+
}
|
|
13506
|
+
}
|
|
13414
13507
|
function isPersistedCloudSessionRecord(value) {
|
|
13415
13508
|
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);
|
|
13416
13509
|
}
|
|
13417
13510
|
function isPersistedLocalBrowserSessionRecord(value) {
|
|
13418
|
-
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;
|
|
13511
|
+
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "local" && (value.engine === "playwright" || value.engine === "abp") && (value.ownership === void 0 || value.ownership === "owned" || value.ownership === "attached") && typeof value.pid === "number" && Number.isFinite(value.pid) && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) && typeof value.userDataDir === "string" && value.userDataDir.length > 0;
|
|
13419
13512
|
}
|
|
13420
13513
|
function resolveOpensteerStateDir() {
|
|
13421
13514
|
const explicit = process.env.OPENSTEER_HOME?.trim();
|
|
@@ -13804,19 +13897,40 @@ function delay(ms) {
|
|
|
13804
13897
|
var OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT = "opensteer-local-view-session";
|
|
13805
13898
|
var OPENSTEER_LOCAL_VIEW_SESSION_VERSION = 1;
|
|
13806
13899
|
function buildLocalViewSessionId(input) {
|
|
13900
|
+
const ownership = input.ownership ?? "owned";
|
|
13901
|
+
const identity = ownership === "attached" ? input.endpoint ?? input.remoteDebuggingUrl ?? input.baseUrl ?? "attached" : `pid:${String(input.pid ?? 0)}`;
|
|
13807
13902
|
const hash = crypto.createHash("sha256").update(`${input.rootPath}
|
|
13808
|
-
${
|
|
13903
|
+
${ownership}
|
|
13904
|
+
${identity}
|
|
13809
13905
|
${String(input.startedAt)}`).digest("hex");
|
|
13810
13906
|
return `local_${hash.slice(0, 24)}`;
|
|
13811
13907
|
}
|
|
13908
|
+
function buildLocalViewSessionIdForRecord(input) {
|
|
13909
|
+
const ownership = getPersistedLocalBrowserSessionOwnership(input.live);
|
|
13910
|
+
if (ownership === "attached") {
|
|
13911
|
+
return buildLocalViewSessionId({
|
|
13912
|
+
rootPath: input.rootPath,
|
|
13913
|
+
ownership,
|
|
13914
|
+
startedAt: input.live.startedAt,
|
|
13915
|
+
...input.live.endpoint === void 0 ? {} : { endpoint: input.live.endpoint },
|
|
13916
|
+
...input.live.baseUrl === void 0 ? {} : { baseUrl: input.live.baseUrl },
|
|
13917
|
+
...input.live.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: input.live.remoteDebuggingUrl }
|
|
13918
|
+
});
|
|
13919
|
+
}
|
|
13920
|
+
return buildLocalViewSessionId({
|
|
13921
|
+
rootPath: input.rootPath,
|
|
13922
|
+
ownership,
|
|
13923
|
+
startedAt: input.live.startedAt,
|
|
13924
|
+
pid: input.live.pid
|
|
13925
|
+
});
|
|
13926
|
+
}
|
|
13812
13927
|
function createLocalViewSessionManifest(input) {
|
|
13813
13928
|
return {
|
|
13814
13929
|
layout: OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT,
|
|
13815
13930
|
version: OPENSTEER_LOCAL_VIEW_SESSION_VERSION,
|
|
13816
|
-
sessionId:
|
|
13931
|
+
sessionId: buildLocalViewSessionIdForRecord({
|
|
13817
13932
|
rootPath: input.rootPath,
|
|
13818
|
-
|
|
13819
|
-
startedAt: input.live.startedAt
|
|
13933
|
+
live: input.live
|
|
13820
13934
|
}),
|
|
13821
13935
|
rootPath: input.rootPath,
|
|
13822
13936
|
...input.workspace === void 0 ? {} : { workspace: input.workspace },
|
|
@@ -13875,7 +13989,8 @@ function normalizeOpensteerEngineName(value, source = "engine") {
|
|
|
13875
13989
|
if (normalized === "playwright" || normalized === "abp") {
|
|
13876
13990
|
return normalized;
|
|
13877
13991
|
}
|
|
13878
|
-
throw new
|
|
13992
|
+
throw new OpensteerProtocolError(
|
|
13993
|
+
"invalid-argument",
|
|
13879
13994
|
`${source} must be one of ${OPENSTEER_ENGINE_NAMES.join(", ")}; received "${value}".`
|
|
13880
13995
|
);
|
|
13881
13996
|
}
|
|
@@ -13884,7 +13999,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
13884
13999
|
return;
|
|
13885
14000
|
}
|
|
13886
14001
|
if (typeof input.browser === "object" && input.browser !== null && input.browser.mode === "attach") {
|
|
13887
|
-
throw new
|
|
14002
|
+
throw new OpensteerProtocolError(
|
|
14003
|
+
"invalid-argument",
|
|
13888
14004
|
'ABP engine does not support browser.mode="attach". Use the Playwright engine for attach flows.'
|
|
13889
14005
|
);
|
|
13890
14006
|
}
|
|
@@ -13892,7 +14008,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
13892
14008
|
if (unsupportedContextOptionNames.length === 0) {
|
|
13893
14009
|
return;
|
|
13894
14010
|
}
|
|
13895
|
-
throw new
|
|
14011
|
+
throw new OpensteerProtocolError(
|
|
14012
|
+
"invalid-argument",
|
|
13896
14013
|
`ABP engine does not support ${unsupportedContextOptionNames.join(", ")}. Supported ABP context options: context.viewport.`
|
|
13897
14014
|
);
|
|
13898
14015
|
}
|
|
@@ -14014,7 +14131,7 @@ var OpensteerBrowserManager = class {
|
|
|
14014
14131
|
}
|
|
14015
14132
|
const liveRecord = await this.readLivePersistentBrowser(await this.ensureWorkspaceStore());
|
|
14016
14133
|
return {
|
|
14017
|
-
mode: this.mode,
|
|
14134
|
+
mode: liveRecord?.ownership === "attached" ? "attach" : this.mode,
|
|
14018
14135
|
engine: liveRecord?.engine ?? this.engineName,
|
|
14019
14136
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14020
14137
|
live: liveRecord !== void 0
|
|
@@ -14142,6 +14259,7 @@ var OpensteerBrowserManager = class {
|
|
|
14142
14259
|
});
|
|
14143
14260
|
const liveRecord = {
|
|
14144
14261
|
mode: "persistent",
|
|
14262
|
+
ownership: "owned",
|
|
14145
14263
|
engine: "abp",
|
|
14146
14264
|
baseUrl: launched.baseUrl,
|
|
14147
14265
|
remoteDebuggingUrl: launched.remoteDebuggingUrl,
|
|
@@ -14228,11 +14346,78 @@ var OpensteerBrowserManager = class {
|
|
|
14228
14346
|
}
|
|
14229
14347
|
async createAttachEngine() {
|
|
14230
14348
|
const endpoint = await resolveAttachEndpoint(this.browserOptions);
|
|
14231
|
-
|
|
14232
|
-
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
|
|
14349
|
+
if (this.workspace === void 0) {
|
|
14350
|
+
return this.createAttachedEngine({
|
|
14351
|
+
endpoint,
|
|
14352
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
14353
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
14354
|
+
onDispose: async () => void 0
|
|
14355
|
+
});
|
|
14356
|
+
}
|
|
14357
|
+
const workspace = await this.ensureWorkspaceStore();
|
|
14358
|
+
return workspace.lock(async () => {
|
|
14359
|
+
const live = await this.readLivePersistentBrowser(workspace);
|
|
14360
|
+
if (live) {
|
|
14361
|
+
if (live.engine !== "playwright") {
|
|
14362
|
+
throw new Error(
|
|
14363
|
+
`workspace "${this.workspace}" already has a live ${live.engine} browser. Close it before attaching a Playwright browser.`
|
|
14364
|
+
);
|
|
14365
|
+
}
|
|
14366
|
+
if (live.ownership !== "attached") {
|
|
14367
|
+
throw new Error(
|
|
14368
|
+
`workspace "${this.workspace}" already has a live Opensteer-owned browser. Close it before attaching another browser.`
|
|
14369
|
+
);
|
|
14370
|
+
}
|
|
14371
|
+
if (live.endpoint === void 0) {
|
|
14372
|
+
throw new Error("workspace live browser record is missing a DevTools endpoint.");
|
|
14373
|
+
}
|
|
14374
|
+
if (live.endpoint !== endpoint) {
|
|
14375
|
+
throw new Error(
|
|
14376
|
+
`workspace "${this.workspace}" is already attached to a different browser endpoint. Close it before reattaching.`
|
|
14377
|
+
);
|
|
14378
|
+
}
|
|
14379
|
+
await bestEffortRegisterLocalViewSession({
|
|
14380
|
+
rootPath: workspace.rootPath,
|
|
14381
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14382
|
+
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
14383
|
+
ownership: "attached"
|
|
14384
|
+
});
|
|
14385
|
+
return this.createAttachedEngine({
|
|
14386
|
+
endpoint: live.endpoint,
|
|
14387
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
14388
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
14389
|
+
onDispose: async () => void 0
|
|
14390
|
+
});
|
|
14391
|
+
}
|
|
14392
|
+
const liveRecord = {
|
|
14393
|
+
mode: "persistent",
|
|
14394
|
+
ownership: "attached",
|
|
14395
|
+
engine: "playwright",
|
|
14396
|
+
endpoint,
|
|
14397
|
+
pid: 0,
|
|
14398
|
+
startedAt: Date.now(),
|
|
14399
|
+
userDataDir: workspace.browserUserDataDir
|
|
14400
|
+
};
|
|
14401
|
+
await this.writeLivePersistentBrowser(workspace, liveRecord);
|
|
14402
|
+
const persistedLiveRecord = toPersistedLocalBrowserSessionRecord(this.workspace, liveRecord);
|
|
14403
|
+
await bestEffortRegisterLocalViewSession({
|
|
14404
|
+
rootPath: workspace.rootPath,
|
|
14405
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14406
|
+
live: persistedLiveRecord,
|
|
14407
|
+
ownership: "attached"
|
|
14408
|
+
});
|
|
14409
|
+
try {
|
|
14410
|
+
return await this.createAttachedEngine({
|
|
14411
|
+
endpoint,
|
|
14412
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
14413
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
14414
|
+
onDispose: async () => void 0
|
|
14415
|
+
});
|
|
14416
|
+
} catch (error) {
|
|
14417
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
|
|
14418
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14419
|
+
throw error;
|
|
14420
|
+
}
|
|
14236
14421
|
});
|
|
14237
14422
|
}
|
|
14238
14423
|
async createPersistentEngine() {
|
|
@@ -14252,7 +14437,7 @@ var OpensteerBrowserManager = class {
|
|
|
14252
14437
|
rootPath: workspace.rootPath,
|
|
14253
14438
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14254
14439
|
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
14255
|
-
ownership:
|
|
14440
|
+
ownership: live.ownership
|
|
14256
14441
|
});
|
|
14257
14442
|
return this.createAttachedEngine({
|
|
14258
14443
|
endpoint: live.endpoint,
|
|
@@ -14268,6 +14453,7 @@ var OpensteerBrowserManager = class {
|
|
|
14268
14453
|
});
|
|
14269
14454
|
const liveRecord = {
|
|
14270
14455
|
mode: "persistent",
|
|
14456
|
+
ownership: "owned",
|
|
14271
14457
|
engine: "playwright",
|
|
14272
14458
|
endpoint: launched.endpoint,
|
|
14273
14459
|
pid: launched.pid,
|
|
@@ -14397,7 +14583,20 @@ var OpensteerBrowserManager = class {
|
|
|
14397
14583
|
if (live === void 0) {
|
|
14398
14584
|
return void 0;
|
|
14399
14585
|
}
|
|
14400
|
-
if (
|
|
14586
|
+
if (live.ownership === "attached") {
|
|
14587
|
+
const attachedRecord = toPersistedLocalBrowserSessionRecord(this.workspace, live);
|
|
14588
|
+
if (!await isAttachedLocalBrowserSessionReachable(attachedRecord)) {
|
|
14589
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, attachedRecord);
|
|
14590
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14591
|
+
return void 0;
|
|
14592
|
+
}
|
|
14593
|
+
return live;
|
|
14594
|
+
}
|
|
14595
|
+
if (!isProcessRunning2(live.pid)) {
|
|
14596
|
+
await this.unregisterLocalViewSessionForRecord(
|
|
14597
|
+
workspace.rootPath,
|
|
14598
|
+
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
14599
|
+
);
|
|
14401
14600
|
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14402
14601
|
return void 0;
|
|
14403
14602
|
}
|
|
@@ -14445,6 +14644,10 @@ var OpensteerBrowserManager = class {
|
|
|
14445
14644
|
workspace.rootPath,
|
|
14446
14645
|
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
14447
14646
|
);
|
|
14647
|
+
if (live.ownership === "attached") {
|
|
14648
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14649
|
+
return;
|
|
14650
|
+
}
|
|
14448
14651
|
if (live.engine === "playwright") {
|
|
14449
14652
|
if (live.endpoint !== void 0) {
|
|
14450
14653
|
await requestBrowserClose(live.endpoint).catch(() => void 0);
|
|
@@ -14473,10 +14676,18 @@ var OpensteerBrowserManager = class {
|
|
|
14473
14676
|
}
|
|
14474
14677
|
async unregisterLocalViewSessionForRecord(rootPath, record) {
|
|
14475
14678
|
await bestEffortUnregisterLocalViewSession(
|
|
14476
|
-
buildLocalViewSessionId({
|
|
14679
|
+
getPersistedLocalBrowserSessionOwnership(record) === "attached" ? buildLocalViewSessionId({
|
|
14680
|
+
rootPath,
|
|
14681
|
+
startedAt: record.startedAt,
|
|
14682
|
+
ownership: "attached",
|
|
14683
|
+
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
14684
|
+
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
14685
|
+
...record.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: record.remoteDebuggingUrl }
|
|
14686
|
+
}) : buildLocalViewSessionId({
|
|
14477
14687
|
rootPath,
|
|
14478
|
-
|
|
14479
|
-
|
|
14688
|
+
startedAt: record.startedAt,
|
|
14689
|
+
ownership: "owned",
|
|
14690
|
+
pid: record.pid
|
|
14480
14691
|
})
|
|
14481
14692
|
);
|
|
14482
14693
|
}
|
|
@@ -14511,6 +14722,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
14511
14722
|
version: 1,
|
|
14512
14723
|
provider: "local",
|
|
14513
14724
|
...workspace === void 0 ? {} : { workspace },
|
|
14725
|
+
ownership: live.ownership,
|
|
14514
14726
|
engine: live.engine,
|
|
14515
14727
|
...live.endpoint === void 0 ? {} : { endpoint: live.endpoint },
|
|
14516
14728
|
...live.baseUrl === void 0 ? {} : { baseUrl: live.baseUrl },
|
|
@@ -14526,6 +14738,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
14526
14738
|
function toWorkspaceLiveBrowserRecord(record) {
|
|
14527
14739
|
return {
|
|
14528
14740
|
mode: "persistent",
|
|
14741
|
+
ownership: getPersistedLocalBrowserSessionOwnership(record),
|
|
14529
14742
|
engine: record.engine,
|
|
14530
14743
|
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
14531
14744
|
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
@@ -14552,7 +14765,12 @@ function isAttachBrowserOptions(browser) {
|
|
|
14552
14765
|
async function resolveAttachEndpoint(browser) {
|
|
14553
14766
|
const endpoint = browser?.endpoint?.trim();
|
|
14554
14767
|
if (endpoint && endpoint.length > 0) {
|
|
14555
|
-
|
|
14768
|
+
const inspected = await inspectCdpEndpoint({
|
|
14769
|
+
endpoint,
|
|
14770
|
+
...browser?.headers === void 0 ? {} : { headers: browser.headers },
|
|
14771
|
+
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
14772
|
+
});
|
|
14773
|
+
return inspected.endpoint;
|
|
14556
14774
|
}
|
|
14557
14775
|
const selection = await selectAttachBrowserCandidate({
|
|
14558
14776
|
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
@@ -14816,12 +15034,12 @@ async function waitForProcessExit(pid, timeoutMs) {
|
|
|
14816
15034
|
}
|
|
14817
15035
|
const deadline = Date.now() + timeoutMs;
|
|
14818
15036
|
while (Date.now() < deadline) {
|
|
14819
|
-
if (!
|
|
15037
|
+
if (!isProcessRunning2(pid)) {
|
|
14820
15038
|
return true;
|
|
14821
15039
|
}
|
|
14822
15040
|
await sleep2(50);
|
|
14823
15041
|
}
|
|
14824
|
-
return !
|
|
15042
|
+
return !isProcessRunning2(pid);
|
|
14825
15043
|
}
|
|
14826
15044
|
function resolveAbpSessionDir(workspace) {
|
|
14827
15045
|
return path10__default.default.join(workspace.livePath, "abp-session");
|
|
@@ -14994,15 +15212,58 @@ function isOpensteerEnvironmentKey(key) {
|
|
|
14994
15212
|
return key.startsWith(OPENSTEER_ENV_PREFIX);
|
|
14995
15213
|
}
|
|
14996
15214
|
|
|
14997
|
-
// src/
|
|
14998
|
-
|
|
14999
|
-
|
|
15000
|
-
|
|
15001
|
-
return;
|
|
15215
|
+
// src/internal/errors.ts
|
|
15216
|
+
function normalizeThrownOpensteerError(error, fallbackMessage) {
|
|
15217
|
+
if (isOpensteerProtocolError(error)) {
|
|
15218
|
+
return toOpensteerError(error);
|
|
15002
15219
|
}
|
|
15003
|
-
if (
|
|
15004
|
-
|
|
15005
|
-
|
|
15220
|
+
if (isBrowserCoreError(error)) {
|
|
15221
|
+
return createOpensteerError(error.code, error.message, {
|
|
15222
|
+
retriable: error.retriable,
|
|
15223
|
+
...error.details === void 0 ? {} : { details: error.details }
|
|
15224
|
+
});
|
|
15225
|
+
}
|
|
15226
|
+
if (error instanceof OpensteerAttachAmbiguousError) {
|
|
15227
|
+
return createOpensteerError("conflict", error.message, {
|
|
15228
|
+
details: {
|
|
15229
|
+
candidates: error.candidates,
|
|
15230
|
+
code: error.code,
|
|
15231
|
+
name: error.name
|
|
15232
|
+
}
|
|
15233
|
+
});
|
|
15234
|
+
}
|
|
15235
|
+
if (error instanceof Error && "opensteerError" in error && typeof error.opensteerError === "object" && error.opensteerError !== null) {
|
|
15236
|
+
const oe = error.opensteerError;
|
|
15237
|
+
return createOpensteerError(oe.code, oe.message, {
|
|
15238
|
+
retriable: oe.retriable,
|
|
15239
|
+
...oe.capability === void 0 ? {} : { capability: oe.capability },
|
|
15240
|
+
...oe.details === void 0 ? {} : { details: oe.details }
|
|
15241
|
+
});
|
|
15242
|
+
}
|
|
15243
|
+
if (error instanceof Error) {
|
|
15244
|
+
return createOpensteerError("operation-failed", error.message, {
|
|
15245
|
+
details: {
|
|
15246
|
+
name: error.name
|
|
15247
|
+
}
|
|
15248
|
+
});
|
|
15249
|
+
}
|
|
15250
|
+
return createOpensteerError("internal", fallbackMessage, {
|
|
15251
|
+
details: {
|
|
15252
|
+
value: error
|
|
15253
|
+
}
|
|
15254
|
+
});
|
|
15255
|
+
}
|
|
15256
|
+
|
|
15257
|
+
// src/provider/config.ts
|
|
15258
|
+
var OPENSTEER_PROVIDER_MODES = ["local", "cloud"];
|
|
15259
|
+
function assertProviderSupportsEngine(provider, engine) {
|
|
15260
|
+
if (engine !== "abp") {
|
|
15261
|
+
return;
|
|
15262
|
+
}
|
|
15263
|
+
if (provider === "cloud") {
|
|
15264
|
+
throw new OpensteerProtocolError(
|
|
15265
|
+
"invalid-argument",
|
|
15266
|
+
"ABP is not supported for provider=cloud. Cloud provider currently requires Playwright."
|
|
15006
15267
|
);
|
|
15007
15268
|
}
|
|
15008
15269
|
}
|
|
@@ -15011,7 +15272,8 @@ function normalizeOpensteerProviderMode(value, source = "OPENSTEER_PROVIDER") {
|
|
|
15011
15272
|
if (normalized === OPENSTEER_PROVIDER_MODES[0] || normalized === OPENSTEER_PROVIDER_MODES[1]) {
|
|
15012
15273
|
return normalized;
|
|
15013
15274
|
}
|
|
15014
|
-
throw new
|
|
15275
|
+
throw new OpensteerProtocolError(
|
|
15276
|
+
"invalid-argument",
|
|
15015
15277
|
`${source} must be one of ${OPENSTEER_PROVIDER_MODES.join(", ")}; received "${value}".`
|
|
15016
15278
|
);
|
|
15017
15279
|
}
|
|
@@ -15451,6 +15713,24 @@ async function sleep3(ms) {
|
|
|
15451
15713
|
// src/cloud/client.ts
|
|
15452
15714
|
var CLOUD_CLOSE_TIMEOUT_MS = 6e4;
|
|
15453
15715
|
var CLOUD_CLOSE_POLL_INTERVAL_MS = 250;
|
|
15716
|
+
var OpensteerCloudRequestError = class extends Error {
|
|
15717
|
+
statusCode;
|
|
15718
|
+
code;
|
|
15719
|
+
details;
|
|
15720
|
+
method;
|
|
15721
|
+
pathname;
|
|
15722
|
+
url;
|
|
15723
|
+
constructor(args) {
|
|
15724
|
+
super(args.message);
|
|
15725
|
+
this.name = "OpensteerCloudRequestError";
|
|
15726
|
+
this.statusCode = args.statusCode;
|
|
15727
|
+
this.code = args.code;
|
|
15728
|
+
this.details = args.details;
|
|
15729
|
+
this.method = args.method;
|
|
15730
|
+
this.pathname = args.pathname;
|
|
15731
|
+
this.url = args.url;
|
|
15732
|
+
}
|
|
15733
|
+
};
|
|
15454
15734
|
var OpensteerCloudClient = class {
|
|
15455
15735
|
constructor(config) {
|
|
15456
15736
|
this.config = config;
|
|
@@ -15626,7 +15906,11 @@ var OpensteerCloudClient = class {
|
|
|
15626
15906
|
});
|
|
15627
15907
|
}
|
|
15628
15908
|
if (!response.ok) {
|
|
15629
|
-
throw
|
|
15909
|
+
throw await createCloudRequestError(response, {
|
|
15910
|
+
method: init.method,
|
|
15911
|
+
pathname,
|
|
15912
|
+
url
|
|
15913
|
+
});
|
|
15630
15914
|
}
|
|
15631
15915
|
return response;
|
|
15632
15916
|
}
|
|
@@ -15674,6 +15958,36 @@ function wrapCloudFetchError(error, input) {
|
|
|
15674
15958
|
wrapped.name = error.name;
|
|
15675
15959
|
return wrapped;
|
|
15676
15960
|
}
|
|
15961
|
+
async function createCloudRequestError(response, input) {
|
|
15962
|
+
const payload = await readCloudErrorPayload(response);
|
|
15963
|
+
return new OpensteerCloudRequestError({
|
|
15964
|
+
statusCode: response.status,
|
|
15965
|
+
method: input.method,
|
|
15966
|
+
pathname: input.pathname,
|
|
15967
|
+
url: input.url,
|
|
15968
|
+
message: payload?.error ?? `${input.method} ${input.pathname} failed with ${String(response.status)}.`,
|
|
15969
|
+
...payload?.code === void 0 ? {} : { code: payload.code },
|
|
15970
|
+
...payload?.details === void 0 ? {} : { details: payload.details }
|
|
15971
|
+
});
|
|
15972
|
+
}
|
|
15973
|
+
async function readCloudErrorPayload(response) {
|
|
15974
|
+
try {
|
|
15975
|
+
return asCloudErrorPayload(await response.json());
|
|
15976
|
+
} catch {
|
|
15977
|
+
return void 0;
|
|
15978
|
+
}
|
|
15979
|
+
}
|
|
15980
|
+
function asCloudErrorPayload(value) {
|
|
15981
|
+
if (value === null || typeof value !== "object") {
|
|
15982
|
+
return void 0;
|
|
15983
|
+
}
|
|
15984
|
+
const payload = value;
|
|
15985
|
+
return {
|
|
15986
|
+
...typeof payload.error === "string" ? { error: payload.error } : {},
|
|
15987
|
+
...typeof payload.code === "string" ? { code: payload.code } : {},
|
|
15988
|
+
..."details" in payload ? { details: payload.details } : {}
|
|
15989
|
+
};
|
|
15990
|
+
}
|
|
15677
15991
|
|
|
15678
15992
|
// src/cloud/config.ts
|
|
15679
15993
|
function resolveCloudConfig(input = {}) {
|
|
@@ -15704,13 +16018,13 @@ function resolveCloudConfig(input = {}) {
|
|
|
15704
16018
|
|
|
15705
16019
|
// ../runtime-core/package.json
|
|
15706
16020
|
var package_default = {
|
|
15707
|
-
version: "0.2.
|
|
16021
|
+
version: "0.2.6"};
|
|
15708
16022
|
|
|
15709
16023
|
// ../runtime-core/src/version.ts
|
|
15710
16024
|
var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
|
|
15711
16025
|
|
|
15712
16026
|
// ../runtime-core/src/internal/errors.ts
|
|
15713
|
-
function
|
|
16027
|
+
function normalizeThrownOpensteerError2(error, fallbackMessage) {
|
|
15714
16028
|
if (isOpensteerProtocolError(error)) {
|
|
15715
16029
|
return toOpensteerError(error);
|
|
15716
16030
|
}
|
|
@@ -15975,12 +16289,16 @@ function toOpensteerResolvedTarget(target) {
|
|
|
15975
16289
|
documentRef: target.documentRef,
|
|
15976
16290
|
documentEpoch: target.documentEpoch,
|
|
15977
16291
|
nodeRef: target.nodeRef,
|
|
15978
|
-
tagName: target.node.nodeName
|
|
16292
|
+
tagName: toOpensteerTagName(target.node.nodeName),
|
|
15979
16293
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
15980
16294
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
15981
16295
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
15982
16296
|
};
|
|
15983
16297
|
}
|
|
16298
|
+
function toOpensteerTagName(nodeName) {
|
|
16299
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
16300
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
16301
|
+
}
|
|
15984
16302
|
|
|
15985
16303
|
// ../runtime-core/src/runtimes/computer-use/runtime.ts
|
|
15986
16304
|
function createComputerUseRuntime(options) {
|
|
@@ -16014,7 +16332,7 @@ var DefaultComputerUseRuntime = class {
|
|
|
16014
16332
|
screenshot,
|
|
16015
16333
|
signal: input.timeout.signal,
|
|
16016
16334
|
remainingMs: () => input.timeout.remainingMs(),
|
|
16017
|
-
policySettle: async (pageRef, trigger) => {
|
|
16335
|
+
policySettle: async (pageRef, trigger, boundary) => {
|
|
16018
16336
|
try {
|
|
16019
16337
|
await settleWithPolicy(this.options.policy.settle, {
|
|
16020
16338
|
operation: "computer.execute",
|
|
@@ -16022,7 +16340,9 @@ var DefaultComputerUseRuntime = class {
|
|
|
16022
16340
|
engine: this.options.engine,
|
|
16023
16341
|
pageRef,
|
|
16024
16342
|
signal: input.timeout.signal,
|
|
16025
|
-
remainingMs: input.timeout.remainingMs()
|
|
16343
|
+
remainingMs: input.timeout.remainingMs(),
|
|
16344
|
+
...boundary?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary.observedMutationQuietMs },
|
|
16345
|
+
...boundary?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
16026
16346
|
});
|
|
16027
16347
|
} catch (error) {
|
|
16028
16348
|
if (pageRef === input.pageRef && isSoftSettleTimeoutError(error, input.timeout.signal)) {
|
|
@@ -17200,28 +17520,24 @@ function restoreBoundedAttr(el, attr, value) {
|
|
|
17200
17520
|
}
|
|
17201
17521
|
setBoundedAttr(el, attr, value);
|
|
17202
17522
|
}
|
|
17203
|
-
function
|
|
17523
|
+
function deduplicateImagesInDom($) {
|
|
17204
17524
|
const seen = /* @__PURE__ */ new Set();
|
|
17205
|
-
|
|
17206
|
-
|
|
17207
|
-
|
|
17208
|
-
|
|
17209
|
-
const srcMatch = attrContent.match(/\bsrc\s*=\s*(["']?)(.*?)\1/);
|
|
17210
|
-
const srcsetMatch = attrContent.match(/\bsrcset\s*=\s*(["'])(.*?)\1/);
|
|
17211
|
-
let src = null;
|
|
17212
|
-
if (srcMatch && srcMatch[2]) {
|
|
17213
|
-
src = srcMatch[2].trim();
|
|
17214
|
-
} else if (srcsetMatch && srcsetMatch[2]) {
|
|
17215
|
-
src = srcsetMatch[2].split(",")[0]?.trim().split(" ")[0] ?? null;
|
|
17525
|
+
$("img").each(function deduplicateDomImage() {
|
|
17526
|
+
const el = $(this);
|
|
17527
|
+
if (el.attr("c") !== void 0) {
|
|
17528
|
+
return;
|
|
17216
17529
|
}
|
|
17530
|
+
const srcValue = el.attr("src")?.trim();
|
|
17531
|
+
const srcsetValue = el.attr("srcset");
|
|
17532
|
+
const src = srcValue && srcValue.length > 0 ? srcValue : srcsetValue?.split(",")[0]?.trim().split(/\s+/u)[0];
|
|
17217
17533
|
if (!src) {
|
|
17218
|
-
return
|
|
17534
|
+
return;
|
|
17219
17535
|
}
|
|
17220
17536
|
if (seen.has(src)) {
|
|
17221
|
-
|
|
17537
|
+
el.remove();
|
|
17538
|
+
return;
|
|
17222
17539
|
}
|
|
17223
17540
|
seen.add(src);
|
|
17224
|
-
return full;
|
|
17225
17541
|
});
|
|
17226
17542
|
}
|
|
17227
17543
|
function hasAttribute2(node, attr) {
|
|
@@ -17279,23 +17595,6 @@ function isPreservedImageElement(node) {
|
|
|
17279
17595
|
function getElementsInReverseDocumentOrder($) {
|
|
17280
17596
|
return $.root().find("*").toArray().reverse().filter((node) => node.type === "tag");
|
|
17281
17597
|
}
|
|
17282
|
-
function getNodeDepth(node) {
|
|
17283
|
-
let depth = 0;
|
|
17284
|
-
let current = node.parent;
|
|
17285
|
-
while (current) {
|
|
17286
|
-
depth++;
|
|
17287
|
-
current = current.parent;
|
|
17288
|
-
}
|
|
17289
|
-
return depth;
|
|
17290
|
-
}
|
|
17291
|
-
function getElementsByDepthDescending($) {
|
|
17292
|
-
const elements = $.root().find("*").toArray().filter((node) => node.type === "tag");
|
|
17293
|
-
const depths = /* @__PURE__ */ new Map();
|
|
17294
|
-
for (const el of elements) {
|
|
17295
|
-
depths.set(el, getNodeDepth(el));
|
|
17296
|
-
}
|
|
17297
|
-
return elements.sort((a, b) => (depths.get(b) ?? 0) - (depths.get(a) ?? 0));
|
|
17298
|
-
}
|
|
17299
17598
|
function flattenExtractionTree($) {
|
|
17300
17599
|
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
17301
17600
|
const el = $(node);
|
|
@@ -17313,19 +17612,6 @@ function flattenExtractionTree($) {
|
|
|
17313
17612
|
el.replaceWith(el.contents());
|
|
17314
17613
|
}
|
|
17315
17614
|
}
|
|
17316
|
-
function hasMarkedAncestor(el, attr) {
|
|
17317
|
-
let current = el[0]?.parent;
|
|
17318
|
-
while (current) {
|
|
17319
|
-
if (!isElementLikeNode(current)) {
|
|
17320
|
-
return false;
|
|
17321
|
-
}
|
|
17322
|
-
if (current.attribs?.[attr] !== void 0) {
|
|
17323
|
-
return true;
|
|
17324
|
-
}
|
|
17325
|
-
current = current.parent;
|
|
17326
|
-
}
|
|
17327
|
-
return false;
|
|
17328
|
-
}
|
|
17329
17615
|
function isIndicatorImage(node) {
|
|
17330
17616
|
return (node?.tagName || "").toLowerCase() === "img" && (hasAttribute2(node, "alt") || hasAttribute2(node, "src") || hasAttribute2(node, "srcset"));
|
|
17331
17617
|
}
|
|
@@ -17443,7 +17729,7 @@ function serializeForExtraction($, root) {
|
|
|
17443
17729
|
traverse(root, 0);
|
|
17444
17730
|
return lines.map((l) => l.trim()).filter((l) => l.length > 0).join("");
|
|
17445
17731
|
}
|
|
17446
|
-
function isClickable(
|
|
17732
|
+
function isClickable(el, context) {
|
|
17447
17733
|
if (context.hasPreMarked) {
|
|
17448
17734
|
return el.attr(OPENSTEER_INTERACTIVE_ATTR) !== void 0;
|
|
17449
17735
|
}
|
|
@@ -17477,21 +17763,17 @@ function isClickable($, el, context) {
|
|
|
17477
17763
|
}
|
|
17478
17764
|
return false;
|
|
17479
17765
|
}
|
|
17480
|
-
function
|
|
17766
|
+
function prepareExtractionSnapshotDom(html) {
|
|
17481
17767
|
if (!html.trim()) {
|
|
17482
|
-
return
|
|
17768
|
+
return void 0;
|
|
17483
17769
|
}
|
|
17484
17770
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
17485
17771
|
removeNoise($);
|
|
17486
17772
|
removeComments($);
|
|
17487
17773
|
markInlineSelfHiddenFallback($);
|
|
17488
17774
|
pruneSelfHiddenNodes($);
|
|
17489
|
-
|
|
17490
|
-
|
|
17491
|
-
{ xmlMode: false }
|
|
17492
|
-
);
|
|
17493
|
-
$clean("*").each(function stripAndRestoreExtractionAttrs() {
|
|
17494
|
-
const el = $clean(this);
|
|
17775
|
+
$("*").each(function stripAndRestoreExtractionAttrs() {
|
|
17776
|
+
const el = $(this);
|
|
17495
17777
|
const node = el[0];
|
|
17496
17778
|
if (!node) {
|
|
17497
17779
|
return;
|
|
@@ -17532,16 +17814,20 @@ function cleanForExtraction(html) {
|
|
|
17532
17814
|
restoreBoundedAttr(el, "href", hrefValue);
|
|
17533
17815
|
}
|
|
17534
17816
|
});
|
|
17535
|
-
flattenExtractionTree($
|
|
17536
|
-
|
|
17817
|
+
flattenExtractionTree($);
|
|
17818
|
+
deduplicateImagesInDom($);
|
|
17819
|
+
return $;
|
|
17820
|
+
}
|
|
17821
|
+
function serializePreparedExtractionSnapshot($) {
|
|
17822
|
+
const root = $.root()[0];
|
|
17537
17823
|
if (root === void 0) {
|
|
17538
17824
|
return "";
|
|
17539
17825
|
}
|
|
17540
|
-
return
|
|
17826
|
+
return serializeForExtraction($, root);
|
|
17541
17827
|
}
|
|
17542
|
-
function
|
|
17828
|
+
function prepareActionSnapshotDom(html) {
|
|
17543
17829
|
if (!html.trim()) {
|
|
17544
|
-
return
|
|
17830
|
+
return void 0;
|
|
17545
17831
|
}
|
|
17546
17832
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
17547
17833
|
removeNoise($);
|
|
@@ -17550,13 +17836,12 @@ function cleanForAction(html) {
|
|
|
17550
17836
|
pruneSelfHiddenNodes($);
|
|
17551
17837
|
const clickableMark = "data-clickable-marker";
|
|
17552
17838
|
const indicatorMark = "data-keep-indicator";
|
|
17553
|
-
const branchMark = "data-keep-branch";
|
|
17554
17839
|
const context = {
|
|
17555
17840
|
hasPreMarked: $(`[${OPENSTEER_INTERACTIVE_ATTR}]`).length > 0
|
|
17556
17841
|
};
|
|
17557
17842
|
$("*").each(function markClickables() {
|
|
17558
17843
|
const el = $(this);
|
|
17559
|
-
if (isClickable(
|
|
17844
|
+
if (isClickable(el, context)) {
|
|
17560
17845
|
el.attr(clickableMark, "1");
|
|
17561
17846
|
}
|
|
17562
17847
|
});
|
|
@@ -17586,25 +17871,7 @@ function cleanForAction(html) {
|
|
|
17586
17871
|
el.remove();
|
|
17587
17872
|
}
|
|
17588
17873
|
});
|
|
17589
|
-
|
|
17590
|
-
let current = $(this).parent();
|
|
17591
|
-
while (current.length > 0) {
|
|
17592
|
-
const node = current[0];
|
|
17593
|
-
if (!node || node.type !== "tag") {
|
|
17594
|
-
break;
|
|
17595
|
-
}
|
|
17596
|
-
const ancestor = current;
|
|
17597
|
-
const tag = (node.tagName || "").toLowerCase();
|
|
17598
|
-
if (ROOT_TAGS.has(tag) || ancestor.attr(clickableMark) !== void 0) {
|
|
17599
|
-
break;
|
|
17600
|
-
}
|
|
17601
|
-
if (!isBoundaryTag(tag)) {
|
|
17602
|
-
ancestor.attr(branchMark, "1");
|
|
17603
|
-
}
|
|
17604
|
-
current = ancestor.parent();
|
|
17605
|
-
}
|
|
17606
|
-
});
|
|
17607
|
-
for (const node of getElementsByDepthDescending($)) {
|
|
17874
|
+
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
17608
17875
|
const el = $(node);
|
|
17609
17876
|
const tag = (node.tagName || "").toLowerCase();
|
|
17610
17877
|
if (ROOT_TAGS.has(tag) || isBoundaryTag(tag)) {
|
|
@@ -17613,17 +17880,7 @@ function cleanForAction(html) {
|
|
|
17613
17880
|
if (el.attr(clickableMark) !== void 0 || el.attr(indicatorMark) !== void 0) {
|
|
17614
17881
|
continue;
|
|
17615
17882
|
}
|
|
17616
|
-
const insideClickable = hasMarkedAncestor(el, clickableMark);
|
|
17617
|
-
const preserveBranch = el.attr(branchMark) !== void 0;
|
|
17618
17883
|
const hasContent = hasElementChildren(node) || hasDirectText(node);
|
|
17619
|
-
if (insideClickable || preserveBranch) {
|
|
17620
|
-
if (!hasContent) {
|
|
17621
|
-
el.remove();
|
|
17622
|
-
} else {
|
|
17623
|
-
unwrapActionNode($, el);
|
|
17624
|
-
}
|
|
17625
|
-
continue;
|
|
17626
|
-
}
|
|
17627
17884
|
if (!hasContent) {
|
|
17628
17885
|
el.remove();
|
|
17629
17886
|
continue;
|
|
@@ -17724,13 +17981,20 @@ function cleanForAction(html) {
|
|
|
17724
17981
|
}
|
|
17725
17982
|
el.removeAttr(clickableMark);
|
|
17726
17983
|
el.removeAttr(indicatorMark);
|
|
17727
|
-
el.removeAttr(branchMark);
|
|
17728
17984
|
el.removeAttr(OPENSTEER_INTERACTIVE_ATTR);
|
|
17729
17985
|
el.removeAttr(OPENSTEER_HIDDEN_ATTR);
|
|
17730
17986
|
el.removeAttr(OPENSTEER_SCROLLABLE_ATTR);
|
|
17731
17987
|
el.removeAttr(OPENSTEER_SELF_HIDDEN_ATTR);
|
|
17732
17988
|
});
|
|
17733
|
-
|
|
17989
|
+
deduplicateImagesInDom($);
|
|
17990
|
+
return $;
|
|
17991
|
+
}
|
|
17992
|
+
function serializePreparedActionSnapshot($) {
|
|
17993
|
+
const normalized = compactHtml($.html());
|
|
17994
|
+
if (normalized.length === 0) {
|
|
17995
|
+
return "";
|
|
17996
|
+
}
|
|
17997
|
+
return cheerio__namespace.load(normalized, { xmlMode: false }).html();
|
|
17734
17998
|
}
|
|
17735
17999
|
var VOID_TAGS2 = /* @__PURE__ */ new Set([
|
|
17736
18000
|
"area",
|
|
@@ -17953,27 +18217,32 @@ async function markLiveSnapshotSemantics(options) {
|
|
|
17953
18217
|
const frames = await options.engine.listFrames({
|
|
17954
18218
|
pageRef: options.pageRef
|
|
17955
18219
|
});
|
|
17956
|
-
|
|
17957
|
-
|
|
17958
|
-
|
|
17959
|
-
frame.frameRef,
|
|
17960
|
-
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
17961
|
-
SNAPSHOT_SEMANTIC_ARGS
|
|
17962
|
-
);
|
|
17963
|
-
}
|
|
17964
|
-
return async () => {
|
|
17965
|
-
for (const frame of frames) {
|
|
17966
|
-
await evaluateFrameBestEffort(
|
|
18220
|
+
await Promise.all(
|
|
18221
|
+
frames.map(
|
|
18222
|
+
(frame) => evaluateFrameBestEffort(
|
|
17967
18223
|
options.engine,
|
|
17968
18224
|
frame.frameRef,
|
|
17969
|
-
|
|
17970
|
-
|
|
17971
|
-
)
|
|
17972
|
-
|
|
18225
|
+
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
18226
|
+
SNAPSHOT_SEMANTIC_ARGS
|
|
18227
|
+
)
|
|
18228
|
+
)
|
|
18229
|
+
);
|
|
18230
|
+
return async () => {
|
|
18231
|
+
await Promise.all(
|
|
18232
|
+
frames.map(
|
|
18233
|
+
(frame) => evaluateFrameBestEffort(
|
|
18234
|
+
options.engine,
|
|
18235
|
+
frame.frameRef,
|
|
18236
|
+
CLEAR_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
18237
|
+
CLEAR_SNAPSHOT_SEMANTIC_ARGS
|
|
18238
|
+
)
|
|
18239
|
+
)
|
|
18240
|
+
);
|
|
17973
18241
|
};
|
|
17974
18242
|
}
|
|
17975
18243
|
|
|
17976
18244
|
// ../runtime-core/src/sdk/snapshot/compiler.ts
|
|
18245
|
+
var EXTRACTION_SKIPPED_COUNTER_TAGS = /* @__PURE__ */ new Set(["html", "head", "body"]);
|
|
17977
18246
|
var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
|
|
17978
18247
|
"c",
|
|
17979
18248
|
OPENSTEER_BOUNDARY_ATTR,
|
|
@@ -17988,7 +18257,7 @@ var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
|
|
|
17988
18257
|
var MAX_LIVE_COUNTER_SYNC_ATTEMPTS = 4;
|
|
17989
18258
|
var CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
|
|
17990
18259
|
const walk = (root) => {
|
|
17991
|
-
for (const child of root
|
|
18260
|
+
for (const child of Array.from(root?.children || [])) {
|
|
17992
18261
|
child.removeAttribute("c");
|
|
17993
18262
|
child.removeAttribute(sparseCounterAttr);
|
|
17994
18263
|
walk(child);
|
|
@@ -18004,7 +18273,7 @@ var CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
|
|
|
18004
18273
|
var ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
|
|
18005
18274
|
let counter = startCounter;
|
|
18006
18275
|
const walk = (root) => {
|
|
18007
|
-
for (const child of root
|
|
18276
|
+
for (const child of Array.from(root?.children || [])) {
|
|
18008
18277
|
child.setAttribute(sparseCounterAttr, String(counter++));
|
|
18009
18278
|
walk(child);
|
|
18010
18279
|
if (child.shadowRoot) {
|
|
@@ -18018,7 +18287,7 @@ var ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
|
|
|
18018
18287
|
})`;
|
|
18019
18288
|
var APPLY_DENSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, mapping }) => {
|
|
18020
18289
|
const walk = (root) => {
|
|
18021
|
-
for (const child of root
|
|
18290
|
+
for (const child of Array.from(root?.children || [])) {
|
|
18022
18291
|
child.removeAttribute("c");
|
|
18023
18292
|
const sparse = child.getAttribute(sparseCounterAttr);
|
|
18024
18293
|
if (sparse !== null) {
|
|
@@ -18081,20 +18350,22 @@ function ensureSparseCountersForAllRecords(counterRecords) {
|
|
|
18081
18350
|
async function clearOpensteerLiveCounters(engine, pageRef) {
|
|
18082
18351
|
const frames = await engine.listFrames({ pageRef });
|
|
18083
18352
|
const failures = [];
|
|
18084
|
-
|
|
18085
|
-
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
|
|
18089
|
-
|
|
18090
|
-
|
|
18091
|
-
|
|
18092
|
-
|
|
18093
|
-
|
|
18353
|
+
await Promise.all(
|
|
18354
|
+
frames.map(async (frame) => {
|
|
18355
|
+
try {
|
|
18356
|
+
await engine.evaluateFrame({
|
|
18357
|
+
frameRef: frame.frameRef,
|
|
18358
|
+
script: CLEAR_LIVE_COUNTERS_SCRIPT,
|
|
18359
|
+
args: [{ sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR }]
|
|
18360
|
+
});
|
|
18361
|
+
} catch (error) {
|
|
18362
|
+
if (isDetachedFrameSyncError(error)) {
|
|
18363
|
+
return;
|
|
18364
|
+
}
|
|
18365
|
+
failures.push(`frame ${frame.frameRef} could not be cleared (${describeError(error)}).`);
|
|
18094
18366
|
}
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
}
|
|
18367
|
+
})
|
|
18368
|
+
);
|
|
18098
18369
|
if (failures.length > 0) {
|
|
18099
18370
|
throw buildLiveCounterSyncError("clear live counters", failures);
|
|
18100
18371
|
}
|
|
@@ -18143,25 +18414,29 @@ async function syncDenseCountersToLiveDom(engine, pageRef, sparseToDirectMapping
|
|
|
18143
18414
|
denseCounter
|
|
18144
18415
|
])
|
|
18145
18416
|
);
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18417
|
+
await Promise.all(
|
|
18418
|
+
frames.map(async (frame) => {
|
|
18419
|
+
try {
|
|
18420
|
+
await engine.evaluateFrame({
|
|
18421
|
+
frameRef: frame.frameRef,
|
|
18422
|
+
script: APPLY_DENSE_COUNTERS_SCRIPT,
|
|
18423
|
+
args: [
|
|
18424
|
+
{
|
|
18425
|
+
sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR,
|
|
18426
|
+
mapping: mappingObj
|
|
18427
|
+
}
|
|
18428
|
+
]
|
|
18429
|
+
});
|
|
18430
|
+
} catch (error) {
|
|
18431
|
+
if (isDetachedFrameSyncError(error)) {
|
|
18432
|
+
return;
|
|
18433
|
+
}
|
|
18434
|
+
failures.push(
|
|
18435
|
+
`frame ${frame.frameRef} could not be synchronized (${describeError(error)}).`
|
|
18436
|
+
);
|
|
18161
18437
|
}
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
}
|
|
18438
|
+
})
|
|
18439
|
+
);
|
|
18165
18440
|
if (failures.length > 0) {
|
|
18166
18441
|
throw buildLiveCounterSyncError("synchronize dense counters", failures);
|
|
18167
18442
|
}
|
|
@@ -18179,26 +18454,26 @@ async function compileOpensteerSnapshot(options) {
|
|
|
18179
18454
|
await clearOpensteerLiveCounters(options.engine, options.pageRef);
|
|
18180
18455
|
await assignSparseCountersToLiveDom(options.engine, options.pageRef);
|
|
18181
18456
|
const pageInfo = await options.engine.getPageInfo({ pageRef: options.pageRef });
|
|
18182
|
-
const mainSnapshot = await
|
|
18183
|
-
|
|
18457
|
+
const { mainSnapshot, snapshotsByDocumentRef } = await getPageDocumentSnapshots(
|
|
18458
|
+
options.engine,
|
|
18459
|
+
options.pageRef
|
|
18460
|
+
);
|
|
18184
18461
|
await cleanupLiveSemantics();
|
|
18185
18462
|
cleanupLiveSemantics = async () => {
|
|
18186
18463
|
};
|
|
18187
|
-
const snapshotIndices = /* @__PURE__ */ new Map();
|
|
18188
18464
|
const renderedNodes = /* @__PURE__ */ new Map();
|
|
18189
18465
|
const rawHtml = renderDocumentSnapshot(
|
|
18190
18466
|
mainSnapshot.documentRef,
|
|
18191
18467
|
snapshotsByDocumentRef,
|
|
18192
|
-
snapshotIndices,
|
|
18193
18468
|
renderedNodes,
|
|
18194
18469
|
{
|
|
18195
18470
|
iframeDepth: 0,
|
|
18196
18471
|
shadowDepth: 0
|
|
18197
18472
|
}
|
|
18198
18473
|
);
|
|
18199
|
-
const
|
|
18200
|
-
const compiledHtml =
|
|
18201
|
-
const finalHtml = options.mode === "extraction" ?
|
|
18474
|
+
const preparedSnapshotDom = options.mode === "extraction" ? prepareExtractionSnapshotDom(rawHtml) : prepareActionSnapshotDom(rawHtml);
|
|
18475
|
+
const compiledHtml = assignCountersInDom(preparedSnapshotDom, renderedNodes, options.mode);
|
|
18476
|
+
const finalHtml = preparedSnapshotDom === void 0 ? "" : options.mode === "extraction" ? serializePreparedExtractionSnapshot(preparedSnapshotDom) : serializePreparedActionSnapshot(preparedSnapshotDom);
|
|
18202
18477
|
ensureSparseCountersForAllRecords(compiledHtml.counterRecords);
|
|
18203
18478
|
await syncDenseCountersToLiveDom(
|
|
18204
18479
|
options.engine,
|
|
@@ -18233,6 +18508,25 @@ async function getMainDocumentSnapshot(engine, pageRef) {
|
|
|
18233
18508
|
}
|
|
18234
18509
|
return engine.getDomSnapshot({ frameRef: mainFrame.frameRef });
|
|
18235
18510
|
}
|
|
18511
|
+
async function getPageDocumentSnapshots(engine, pageRef) {
|
|
18512
|
+
const bundleEngine = engine;
|
|
18513
|
+
const bundledSnapshots = await bundleEngine.getPageDomSnapshots?.({ pageRef });
|
|
18514
|
+
if (bundledSnapshots && bundledSnapshots.length > 0) {
|
|
18515
|
+
const mainSnapshot2 = bundledSnapshots.find((snapshot) => snapshot.parentDocumentRef === void 0) ?? bundledSnapshots[0];
|
|
18516
|
+
return {
|
|
18517
|
+
mainSnapshot: mainSnapshot2,
|
|
18518
|
+
snapshotsByDocumentRef: new Map(
|
|
18519
|
+
bundledSnapshots.map((snapshot) => [snapshot.documentRef, snapshot])
|
|
18520
|
+
)
|
|
18521
|
+
};
|
|
18522
|
+
}
|
|
18523
|
+
const mainSnapshot = await getMainDocumentSnapshot(engine, pageRef);
|
|
18524
|
+
const snapshotsByDocumentRef = await collectDocumentSnapshots(engine, mainSnapshot);
|
|
18525
|
+
return {
|
|
18526
|
+
mainSnapshot,
|
|
18527
|
+
snapshotsByDocumentRef
|
|
18528
|
+
};
|
|
18529
|
+
}
|
|
18236
18530
|
async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
18237
18531
|
const snapshotsByDocumentRef = /* @__PURE__ */ new Map([
|
|
18238
18532
|
[mainSnapshot.documentRef, mainSnapshot]
|
|
@@ -18251,7 +18545,7 @@ async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
|
18251
18545
|
}
|
|
18252
18546
|
return snapshotsByDocumentRef;
|
|
18253
18547
|
}
|
|
18254
|
-
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef,
|
|
18548
|
+
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
18255
18549
|
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
18256
18550
|
if (!snapshot) {
|
|
18257
18551
|
return "";
|
|
@@ -18263,17 +18557,9 @@ function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, snapshotInd
|
|
|
18263
18557
|
`snapshot ${snapshot.documentRef} is missing root node ${String(snapshot.rootSnapshotNodeId)}`
|
|
18264
18558
|
);
|
|
18265
18559
|
}
|
|
18266
|
-
return renderNode(
|
|
18267
|
-
snapshot,
|
|
18268
|
-
rootNode,
|
|
18269
|
-
nodesById,
|
|
18270
|
-
snapshotsByDocumentRef,
|
|
18271
|
-
snapshotIndices,
|
|
18272
|
-
renderedNodes,
|
|
18273
|
-
depth
|
|
18274
|
-
);
|
|
18560
|
+
return renderNode(snapshot, rootNode, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18275
18561
|
}
|
|
18276
|
-
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
18562
|
+
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
18277
18563
|
if (node.nodeType === 3) {
|
|
18278
18564
|
return escapeHtml(node.nodeValue || node.textContent || "");
|
|
18279
18565
|
}
|
|
@@ -18281,56 +18567,26 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18281
18567
|
return "";
|
|
18282
18568
|
}
|
|
18283
18569
|
if (node.nodeType === 9 || node.nodeType === 11) {
|
|
18284
|
-
return renderChildren(
|
|
18285
|
-
snapshot,
|
|
18286
|
-
node,
|
|
18287
|
-
nodesById,
|
|
18288
|
-
snapshotsByDocumentRef,
|
|
18289
|
-
snapshotIndices,
|
|
18290
|
-
renderedNodes,
|
|
18291
|
-
depth
|
|
18292
|
-
);
|
|
18570
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18293
18571
|
}
|
|
18294
18572
|
if (node.nodeType !== 1) {
|
|
18295
|
-
return renderChildren(
|
|
18296
|
-
snapshot,
|
|
18297
|
-
node,
|
|
18298
|
-
nodesById,
|
|
18299
|
-
snapshotsByDocumentRef,
|
|
18300
|
-
snapshotIndices,
|
|
18301
|
-
renderedNodes,
|
|
18302
|
-
depth
|
|
18303
|
-
);
|
|
18573
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18304
18574
|
}
|
|
18305
18575
|
const tagName = normalizeTagName(node.nodeName);
|
|
18306
18576
|
if (isPseudoElementTagName(tagName)) {
|
|
18307
|
-
return renderChildren(
|
|
18308
|
-
snapshot,
|
|
18309
|
-
node,
|
|
18310
|
-
nodesById,
|
|
18311
|
-
snapshotsByDocumentRef,
|
|
18312
|
-
snapshotIndices,
|
|
18313
|
-
renderedNodes,
|
|
18314
|
-
depth
|
|
18315
|
-
);
|
|
18577
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18316
18578
|
}
|
|
18317
18579
|
if ((depth.iframeDepth > 0 || depth.shadowDepth > 0) && (tagName === "html" || tagName === "head" || tagName === "body")) {
|
|
18318
|
-
return renderChildren(
|
|
18319
|
-
snapshot,
|
|
18320
|
-
node,
|
|
18321
|
-
nodesById,
|
|
18322
|
-
snapshotsByDocumentRef,
|
|
18323
|
-
snapshotIndices,
|
|
18324
|
-
renderedNodes,
|
|
18325
|
-
depth
|
|
18326
|
-
);
|
|
18580
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18327
18581
|
}
|
|
18328
18582
|
const snapshotAttributes = normalizeNodeAttributes(node.attributes);
|
|
18583
|
+
const snapshotAttributeIndex = indexNodeAttributes(snapshotAttributes);
|
|
18329
18584
|
const authoredAttributes = stripInternalSnapshotAttributes(snapshotAttributes);
|
|
18585
|
+
const authoredAttributeIndex = indexNodeAttributes(authoredAttributes);
|
|
18330
18586
|
const attributes = [...authoredAttributes];
|
|
18331
|
-
const subtreeHidden =
|
|
18332
|
-
const selfHidden = !subtreeHidden && (
|
|
18333
|
-
const interactive = !subtreeHidden && !selfHidden && (
|
|
18587
|
+
const subtreeHidden = snapshotAttributeIndex.has(OPENSTEER_HIDDEN_ATTR) || isLikelySubtreeHidden(node);
|
|
18588
|
+
const selfHidden = !subtreeHidden && (snapshotAttributeIndex.has(OPENSTEER_SELF_HIDDEN_ATTR) || isLikelySelfHidden(node, nodesById));
|
|
18589
|
+
const interactive = !subtreeHidden && !selfHidden && (snapshotAttributeIndex.has(OPENSTEER_INTERACTIVE_ATTR) || isLikelyInteractive(tagName, node, authoredAttributes, authoredAttributeIndex));
|
|
18334
18590
|
if (interactive) {
|
|
18335
18591
|
attributes.push({ name: OPENSTEER_INTERACTIVE_ATTR, value: "1" });
|
|
18336
18592
|
}
|
|
@@ -18339,7 +18595,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18339
18595
|
} else if (selfHidden) {
|
|
18340
18596
|
attributes.push({ name: OPENSTEER_SELF_HIDDEN_ATTR, value: "1" });
|
|
18341
18597
|
}
|
|
18342
|
-
const sparseCounter =
|
|
18598
|
+
const sparseCounter = snapshotAttributeIndex.get(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18343
18599
|
if (sparseCounter !== void 0) {
|
|
18344
18600
|
attributes.push({ name: OPENSTEER_SPARSE_COUNTER_ATTR, value: sparseCounter });
|
|
18345
18601
|
}
|
|
@@ -18350,21 +18606,18 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18350
18606
|
const syntheticNodeId = buildSyntheticNodeId(snapshot, node);
|
|
18351
18607
|
attributes.push({ name: OPENSTEER_NODE_ID_ATTR, value: syntheticNodeId });
|
|
18352
18608
|
renderedNodes.set(syntheticNodeId, {
|
|
18353
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
18354
|
-
anchor: buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices),
|
|
18355
18609
|
pageRef: snapshot.pageRef,
|
|
18356
18610
|
frameRef: snapshot.frameRef,
|
|
18357
18611
|
documentRef: snapshot.documentRef,
|
|
18358
18612
|
documentEpoch: snapshot.documentEpoch,
|
|
18359
18613
|
nodeRef: node.nodeRef,
|
|
18360
18614
|
tagName: tagName.toUpperCase(),
|
|
18361
|
-
pathHint: buildPathHint(tagName, authoredAttributes),
|
|
18362
|
-
...buildTextSnippet(node.textContent) === void 0 ? {} : { text: buildTextSnippet(node.textContent) },
|
|
18363
18615
|
...authoredAttributes.length === 0 ? {} : { attributes: authoredAttributes },
|
|
18364
18616
|
iframeDepth: depth.iframeDepth,
|
|
18365
18617
|
shadowDepth: depth.shadowDepth,
|
|
18366
18618
|
interactive,
|
|
18367
|
-
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById)
|
|
18619
|
+
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById),
|
|
18620
|
+
...node.textContent === void 0 ? {} : { textContent: node.textContent }
|
|
18368
18621
|
});
|
|
18369
18622
|
}
|
|
18370
18623
|
const attributeText = attributesToHtml(attributes);
|
|
@@ -18373,7 +18626,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18373
18626
|
node,
|
|
18374
18627
|
nodesById,
|
|
18375
18628
|
snapshotsByDocumentRef,
|
|
18376
|
-
snapshotIndices,
|
|
18377
18629
|
renderedNodes,
|
|
18378
18630
|
depth
|
|
18379
18631
|
);
|
|
@@ -18384,7 +18636,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18384
18636
|
const iframeHtml = renderDocumentSnapshot(
|
|
18385
18637
|
node.contentDocumentRef,
|
|
18386
18638
|
snapshotsByDocumentRef,
|
|
18387
|
-
snapshotIndices,
|
|
18388
18639
|
renderedNodes,
|
|
18389
18640
|
{
|
|
18390
18641
|
iframeDepth: depth.iframeDepth + 1,
|
|
@@ -18396,7 +18647,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18396
18647
|
}
|
|
18397
18648
|
return `${elementHtml}<${OPENSTEER_IFRAME_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="iframe">${iframeHtml}</${OPENSTEER_IFRAME_BOUNDARY_TAG}>`;
|
|
18398
18649
|
}
|
|
18399
|
-
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
18650
|
+
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
18400
18651
|
const regularChildren = [];
|
|
18401
18652
|
const shadowChildren = [];
|
|
18402
18653
|
for (const childSnapshotNodeId of node.childSnapshotNodeIds) {
|
|
@@ -18413,18 +18664,10 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
18413
18664
|
const chunks = [];
|
|
18414
18665
|
if (shadowChildren.length > 0) {
|
|
18415
18666
|
const shadowHtml = shadowChildren.map(
|
|
18416
|
-
(child) => renderNode(
|
|
18417
|
-
|
|
18418
|
-
|
|
18419
|
-
|
|
18420
|
-
snapshotsByDocumentRef,
|
|
18421
|
-
snapshotIndices,
|
|
18422
|
-
renderedNodes,
|
|
18423
|
-
{
|
|
18424
|
-
iframeDepth: depth.iframeDepth,
|
|
18425
|
-
shadowDepth: depth.shadowDepth + 1
|
|
18426
|
-
}
|
|
18427
|
-
)
|
|
18667
|
+
(child) => renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, {
|
|
18668
|
+
iframeDepth: depth.iframeDepth,
|
|
18669
|
+
shadowDepth: depth.shadowDepth + 1
|
|
18670
|
+
})
|
|
18428
18671
|
).join("");
|
|
18429
18672
|
chunks.push(
|
|
18430
18673
|
`<${OPENSTEER_SHADOW_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="shadow">${shadowHtml}</${OPENSTEER_SHADOW_BOUNDARY_TAG}>`
|
|
@@ -18432,24 +18675,21 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
18432
18675
|
}
|
|
18433
18676
|
for (const child of regularChildren) {
|
|
18434
18677
|
chunks.push(
|
|
18435
|
-
renderNode(
|
|
18436
|
-
snapshot,
|
|
18437
|
-
child,
|
|
18438
|
-
nodesById,
|
|
18439
|
-
snapshotsByDocumentRef,
|
|
18440
|
-
snapshotIndices,
|
|
18441
|
-
renderedNodes,
|
|
18442
|
-
depth
|
|
18443
|
-
)
|
|
18678
|
+
renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, depth)
|
|
18444
18679
|
);
|
|
18445
18680
|
}
|
|
18446
18681
|
return chunks.join("");
|
|
18447
18682
|
}
|
|
18448
|
-
function
|
|
18449
|
-
const $ = cheerio__namespace.load(cleanedHtml, { xmlMode: false });
|
|
18683
|
+
function assignCountersInDom($, renderedNodes, mode) {
|
|
18450
18684
|
const counterRecords = /* @__PURE__ */ new Map();
|
|
18451
18685
|
const sparseToDirectMapping = /* @__PURE__ */ new Map();
|
|
18452
18686
|
let nextCounter = 1;
|
|
18687
|
+
if (!$) {
|
|
18688
|
+
return {
|
|
18689
|
+
counterRecords,
|
|
18690
|
+
sparseToDirectMapping
|
|
18691
|
+
};
|
|
18692
|
+
}
|
|
18453
18693
|
$("*").each(function assignElementCounter() {
|
|
18454
18694
|
const el = $(this);
|
|
18455
18695
|
const syntheticNodeId = el.attr(OPENSTEER_NODE_ID_ATTR);
|
|
@@ -18461,14 +18701,24 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
18461
18701
|
if (!rendered) {
|
|
18462
18702
|
return;
|
|
18463
18703
|
}
|
|
18704
|
+
if (mode === "extraction" && EXTRACTION_SKIPPED_COUNTER_TAGS.has(rendered.tagName.toLowerCase())) {
|
|
18705
|
+
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18706
|
+
return;
|
|
18707
|
+
}
|
|
18464
18708
|
const rawSparseCounter = el.attr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18465
18709
|
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18466
18710
|
const sparseCounter = rawSparseCounter ? Number.parseInt(rawSparseCounter, 10) : void 0;
|
|
18711
|
+
const replayableSparseCounter = typeof sparseCounter === "number" && Number.isFinite(sparseCounter) ? sparseCounter : void 0;
|
|
18712
|
+
if (rendered.liveCounterSyncEligible && replayableSparseCounter === void 0) {
|
|
18713
|
+
return;
|
|
18714
|
+
}
|
|
18467
18715
|
const counter = nextCounter++;
|
|
18468
18716
|
el.attr("c", String(counter));
|
|
18469
|
-
if (
|
|
18470
|
-
sparseToDirectMapping.set(
|
|
18717
|
+
if (replayableSparseCounter !== void 0) {
|
|
18718
|
+
sparseToDirectMapping.set(replayableSparseCounter, counter);
|
|
18471
18719
|
}
|
|
18720
|
+
const pathHint = buildPathHint(rendered.tagName.toLowerCase(), rendered.attributes ?? []);
|
|
18721
|
+
const text = buildTextSnippet(rendered.textContent);
|
|
18472
18722
|
counterRecords.set(counter, {
|
|
18473
18723
|
element: counter,
|
|
18474
18724
|
pageRef: rendered.pageRef,
|
|
@@ -18477,20 +18727,17 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
18477
18727
|
documentEpoch: rendered.documentEpoch,
|
|
18478
18728
|
nodeRef: rendered.nodeRef,
|
|
18479
18729
|
tagName: rendered.tagName,
|
|
18480
|
-
pathHint
|
|
18481
|
-
...
|
|
18730
|
+
pathHint,
|
|
18731
|
+
...text === void 0 ? {} : { text },
|
|
18482
18732
|
...rendered.attributes === void 0 ? {} : { attributes: rendered.attributes },
|
|
18483
18733
|
iframeDepth: rendered.iframeDepth,
|
|
18484
18734
|
shadowDepth: rendered.shadowDepth,
|
|
18485
18735
|
interactive: rendered.interactive,
|
|
18486
18736
|
liveCounterSyncEligible: rendered.liveCounterSyncEligible,
|
|
18487
|
-
|
|
18488
|
-
anchor: rendered.anchor,
|
|
18489
|
-
...sparseCounter !== void 0 && Number.isFinite(sparseCounter) ? { sparseCounter } : {}
|
|
18737
|
+
...replayableSparseCounter === void 0 ? {} : { sparseCounter: replayableSparseCounter }
|
|
18490
18738
|
});
|
|
18491
18739
|
});
|
|
18492
18740
|
return {
|
|
18493
|
-
html: $.html(),
|
|
18494
18741
|
counterRecords,
|
|
18495
18742
|
sparseToDirectMapping
|
|
18496
18743
|
};
|
|
@@ -18564,28 +18811,28 @@ function isLikelySelfHidden(node, nodesById) {
|
|
|
18564
18811
|
}
|
|
18565
18812
|
return !hasVisibleOutOfFlowChild(node, nodesById);
|
|
18566
18813
|
}
|
|
18567
|
-
function isLikelyInteractive(tagName, node, attributes) {
|
|
18814
|
+
function isLikelyInteractive(tagName, node, attributes, attributeIndex) {
|
|
18568
18815
|
if (NATIVE_INTERACTIVE_TAGS.has(tagName)) {
|
|
18569
|
-
if (tagName === "input" &&
|
|
18816
|
+
if (tagName === "input" && attributeIndex.get("type")?.toLowerCase() === "hidden") {
|
|
18570
18817
|
return false;
|
|
18571
18818
|
}
|
|
18572
18819
|
if (tagName !== "a") {
|
|
18573
18820
|
return true;
|
|
18574
18821
|
}
|
|
18575
18822
|
}
|
|
18576
|
-
if (tagName === "a" &&
|
|
18823
|
+
if (tagName === "a" && attributeIndex.has("href")) {
|
|
18577
18824
|
return true;
|
|
18578
18825
|
}
|
|
18579
|
-
if (
|
|
18826
|
+
if (attributeIndex.has("onclick") || attributeIndex.has("onmousedown") || attributeIndex.has("onmouseup") || attributeIndex.has("data-action") || attributeIndex.has("data-click") || attributeIndex.has("data-toggle")) {
|
|
18580
18827
|
return true;
|
|
18581
18828
|
}
|
|
18582
|
-
if (hasNonNegativeTabIndex(
|
|
18829
|
+
if (hasNonNegativeTabIndex(attributeIndex.get("tabindex"))) {
|
|
18583
18830
|
return true;
|
|
18584
18831
|
}
|
|
18585
|
-
if (
|
|
18832
|
+
if (attributeIndex.get("contenteditable")?.toLowerCase() === "true") {
|
|
18586
18833
|
return true;
|
|
18587
18834
|
}
|
|
18588
|
-
const role =
|
|
18835
|
+
const role = attributeIndex.get("role")?.toLowerCase();
|
|
18589
18836
|
return role !== void 0 && INTERACTIVE_ROLE_SET.has(role);
|
|
18590
18837
|
}
|
|
18591
18838
|
function hasVisibleOutOfFlowChild(node, nodesById) {
|
|
@@ -18648,14 +18895,6 @@ function parseOpacity(value) {
|
|
|
18648
18895
|
const parsed = Number.parseFloat(value);
|
|
18649
18896
|
return Number.isFinite(parsed) ? parsed : Number.NaN;
|
|
18650
18897
|
}
|
|
18651
|
-
function hasAttribute3(attributes, name) {
|
|
18652
|
-
const normalizedName = name.toLowerCase();
|
|
18653
|
-
return attributes.some((attribute) => attribute.name.toLowerCase() === normalizedName);
|
|
18654
|
-
}
|
|
18655
|
-
function unwrapExtractionHtml(html) {
|
|
18656
|
-
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
18657
|
-
return $("body").html()?.trim() || html;
|
|
18658
|
-
}
|
|
18659
18898
|
function buildSyntheticNodeId(snapshot, node) {
|
|
18660
18899
|
return `${snapshot.documentRef}:${String(snapshot.documentEpoch)}:${String(node.snapshotNodeId)}`;
|
|
18661
18900
|
}
|
|
@@ -18702,6 +18941,13 @@ function findAttributeValue(attributes, name) {
|
|
|
18702
18941
|
const normalizedName = name.toLowerCase();
|
|
18703
18942
|
return attributes.find((attribute) => attribute.name.toLowerCase() === normalizedName)?.value;
|
|
18704
18943
|
}
|
|
18944
|
+
function indexNodeAttributes(attributes) {
|
|
18945
|
+
const indexed = /* @__PURE__ */ new Map();
|
|
18946
|
+
for (const attribute of attributes) {
|
|
18947
|
+
indexed.set(attribute.name.toLowerCase(), attribute.value);
|
|
18948
|
+
}
|
|
18949
|
+
return indexed;
|
|
18950
|
+
}
|
|
18705
18951
|
function attributesToHtml(attributes) {
|
|
18706
18952
|
if (attributes.length === 0) {
|
|
18707
18953
|
return "";
|
|
@@ -18711,56 +18957,6 @@ function attributesToHtml(attributes) {
|
|
|
18711
18957
|
function escapeAttribute(value) {
|
|
18712
18958
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
18713
18959
|
}
|
|
18714
|
-
function buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices) {
|
|
18715
|
-
const index = getSnapshotIndex(snapshot.documentRef, snapshotsByDocumentRef, snapshotIndices);
|
|
18716
|
-
const localAnchor = buildLocalStructuralElementAnchor(index, node);
|
|
18717
|
-
return prefixIframeContext(snapshot, localAnchor, snapshotsByDocumentRef, snapshotIndices);
|
|
18718
|
-
}
|
|
18719
|
-
function prefixIframeContext(snapshot, localPath, snapshotsByDocumentRef, snapshotIndices) {
|
|
18720
|
-
if (snapshot.parentDocumentRef === void 0) {
|
|
18721
|
-
return sanitizeStructuralElementAnchor(localPath);
|
|
18722
|
-
}
|
|
18723
|
-
const parentSnapshot = snapshotsByDocumentRef.get(snapshot.parentDocumentRef);
|
|
18724
|
-
if (!parentSnapshot) {
|
|
18725
|
-
throw new Error(
|
|
18726
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no parent snapshot`
|
|
18727
|
-
);
|
|
18728
|
-
}
|
|
18729
|
-
const parentIndex = getSnapshotIndex(
|
|
18730
|
-
parentSnapshot.documentRef,
|
|
18731
|
-
snapshotsByDocumentRef,
|
|
18732
|
-
snapshotIndices
|
|
18733
|
-
);
|
|
18734
|
-
const iframeHost = findIframeHostNode(parentIndex, snapshot.documentRef);
|
|
18735
|
-
if (!iframeHost) {
|
|
18736
|
-
throw new Error(
|
|
18737
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no iframe host`
|
|
18738
|
-
);
|
|
18739
|
-
}
|
|
18740
|
-
const hostPath = buildSnapshotElementAnchor(
|
|
18741
|
-
parentSnapshot,
|
|
18742
|
-
iframeHost,
|
|
18743
|
-
snapshotsByDocumentRef,
|
|
18744
|
-
snapshotIndices
|
|
18745
|
-
);
|
|
18746
|
-
return sanitizeStructuralElementAnchor({
|
|
18747
|
-
context: [...hostPath.context, { kind: "iframe", host: hostPath.nodes }, ...localPath.context],
|
|
18748
|
-
nodes: localPath.nodes
|
|
18749
|
-
});
|
|
18750
|
-
}
|
|
18751
|
-
function getSnapshotIndex(documentRef, snapshotsByDocumentRef, snapshotIndices) {
|
|
18752
|
-
const existing = snapshotIndices.get(documentRef);
|
|
18753
|
-
if (existing) {
|
|
18754
|
-
return existing;
|
|
18755
|
-
}
|
|
18756
|
-
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
18757
|
-
if (!snapshot) {
|
|
18758
|
-
throw new Error(`missing DOM snapshot for ${documentRef}`);
|
|
18759
|
-
}
|
|
18760
|
-
const index = createSnapshotIndex(snapshot);
|
|
18761
|
-
snapshotIndices.set(documentRef, index);
|
|
18762
|
-
return index;
|
|
18763
|
-
}
|
|
18764
18960
|
function escapeHtml(value) {
|
|
18765
18961
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
18766
18962
|
}
|
|
@@ -19973,7 +20169,7 @@ var OpensteerSessionRuntime = class {
|
|
|
19973
20169
|
options
|
|
19974
20170
|
);
|
|
19975
20171
|
}
|
|
19976
|
-
return this.
|
|
20172
|
+
return this.readNavigationSummary();
|
|
19977
20173
|
}
|
|
19978
20174
|
const startedAt = Date.now();
|
|
19979
20175
|
const root = await this.ensureRoot();
|
|
@@ -19994,7 +20190,8 @@ var OpensteerSessionRuntime = class {
|
|
|
19994
20190
|
openedSessionRef = sessionRef;
|
|
19995
20191
|
const createdPage = await timeout.runStep(
|
|
19996
20192
|
() => engine.createPage({
|
|
19997
|
-
sessionRef
|
|
20193
|
+
sessionRef,
|
|
20194
|
+
...input.url === void 0 ? {} : { url: input.url }
|
|
19998
20195
|
})
|
|
19999
20196
|
);
|
|
20000
20197
|
openedPageRef = createdPage.data.pageRef;
|
|
@@ -20004,18 +20201,19 @@ var OpensteerSessionRuntime = class {
|
|
|
20004
20201
|
await timeout.runStep(() => this.ensureSemantics());
|
|
20005
20202
|
let frameRef2 = createdPage.frameRef;
|
|
20006
20203
|
if (input.url !== void 0) {
|
|
20007
|
-
|
|
20008
|
-
{
|
|
20204
|
+
await timeout.runStep(
|
|
20205
|
+
() => settleWithPolicy(this.policy.settle, {
|
|
20009
20206
|
operation: "session.open",
|
|
20207
|
+
trigger: "navigation",
|
|
20208
|
+
engine: this.requireEngine(),
|
|
20010
20209
|
pageRef: createdPage.data.pageRef,
|
|
20011
|
-
|
|
20012
|
-
|
|
20013
|
-
|
|
20210
|
+
signal: timeout.signal,
|
|
20211
|
+
remainingMs: timeout.remainingMs()
|
|
20212
|
+
})
|
|
20014
20213
|
);
|
|
20015
|
-
frameRef2 = navigation.data.mainFrame.frameRef;
|
|
20016
20214
|
}
|
|
20017
20215
|
return {
|
|
20018
|
-
state: await timeout.runStep(() => this.
|
|
20216
|
+
state: await timeout.runStep(() => this.readNavigationSummary()),
|
|
20019
20217
|
frameRef: frameRef2
|
|
20020
20218
|
};
|
|
20021
20219
|
},
|
|
@@ -20108,7 +20306,11 @@ var OpensteerSessionRuntime = class {
|
|
|
20108
20306
|
"page.new cannot use openerPageRef before a session exists"
|
|
20109
20307
|
);
|
|
20110
20308
|
}
|
|
20111
|
-
|
|
20309
|
+
const summary = await this.open(input.url === void 0 ? {} : { url: input.url }, options);
|
|
20310
|
+
return {
|
|
20311
|
+
pageRef: await this.ensurePageRef(),
|
|
20312
|
+
...summary
|
|
20313
|
+
};
|
|
20112
20314
|
}
|
|
20113
20315
|
const startedAt = Date.now();
|
|
20114
20316
|
try {
|
|
@@ -20123,7 +20325,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20123
20325
|
})
|
|
20124
20326
|
);
|
|
20125
20327
|
this.pageRef = created.data.pageRef;
|
|
20126
|
-
return this.
|
|
20328
|
+
return this.readCreatedPageOutput(created.data.pageRef);
|
|
20127
20329
|
},
|
|
20128
20330
|
options
|
|
20129
20331
|
);
|
|
@@ -20165,7 +20367,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20165
20367
|
() => this.requireEngine().activatePage({ pageRef: input.pageRef })
|
|
20166
20368
|
);
|
|
20167
20369
|
this.pageRef = input.pageRef;
|
|
20168
|
-
return this.
|
|
20370
|
+
return this.readNavigationSummary(input.pageRef);
|
|
20169
20371
|
},
|
|
20170
20372
|
options
|
|
20171
20373
|
);
|
|
@@ -20291,7 +20493,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20291
20493
|
timeout.throwIfAborted();
|
|
20292
20494
|
return {
|
|
20293
20495
|
navigation: navigation2,
|
|
20294
|
-
state: await timeout.runStep(() => this.
|
|
20496
|
+
state: await timeout.runStep(() => this.readNavigationSummary(pageRef))
|
|
20295
20497
|
};
|
|
20296
20498
|
},
|
|
20297
20499
|
(diagnostics) => {
|
|
@@ -21525,7 +21727,7 @@ var OpensteerSessionRuntime = class {
|
|
|
21525
21727
|
let mutationCaptureDiagnostics;
|
|
21526
21728
|
let boundaryDiagnostics;
|
|
21527
21729
|
try {
|
|
21528
|
-
const { artifacts, output } = await this.runMutationCapturedOperation(
|
|
21730
|
+
const { artifacts, output, result } = await this.runMutationCapturedOperation(
|
|
21529
21731
|
"computer.execute",
|
|
21530
21732
|
{
|
|
21531
21733
|
...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
|
|
@@ -21543,9 +21745,14 @@ var OpensteerSessionRuntime = class {
|
|
|
21543
21745
|
await this.invalidateLiveSnapshotCounters([pageRef, output2.pageRef], timeout);
|
|
21544
21746
|
this.pageRef = output2.pageRef;
|
|
21545
21747
|
const artifacts2 = await this.persistComputerArtifacts(output2, timeout);
|
|
21748
|
+
const result2 = {
|
|
21749
|
+
...await timeout.runStep(() => this.readNavigationSummary(output2.pageRef)),
|
|
21750
|
+
screenshot: artifacts2.screenshot
|
|
21751
|
+
};
|
|
21546
21752
|
return {
|
|
21547
21753
|
artifacts: { manifests: artifacts2.manifests },
|
|
21548
|
-
output:
|
|
21754
|
+
output: output2,
|
|
21755
|
+
result: result2
|
|
21549
21756
|
};
|
|
21550
21757
|
} catch (error) {
|
|
21551
21758
|
boundaryDiagnostics ??= takeActionBoundaryDiagnostics(timeout.signal);
|
|
@@ -21582,7 +21789,7 @@ var OpensteerSessionRuntime = class {
|
|
|
21582
21789
|
documentEpoch: output.screenshot.documentEpoch
|
|
21583
21790
|
})
|
|
21584
21791
|
});
|
|
21585
|
-
return
|
|
21792
|
+
return result;
|
|
21586
21793
|
} catch (error) {
|
|
21587
21794
|
await this.appendTrace({
|
|
21588
21795
|
operation: "computer.execute",
|
|
@@ -21730,8 +21937,9 @@ var OpensteerSessionRuntime = class {
|
|
|
21730
21937
|
mutationCaptureDiagnostics = diagnostics;
|
|
21731
21938
|
}
|
|
21732
21939
|
);
|
|
21733
|
-
const output = toOpensteerActionResult(executed.result);
|
|
21940
|
+
const output = toOpensteerActionResult(executed.result.resolved);
|
|
21734
21941
|
const actionEvents = "events" in executed.result ? executed.result.events : void 0;
|
|
21942
|
+
const resolvedTarget = toOpensteerResolvedTarget2(executed.result.resolved);
|
|
21735
21943
|
await this.appendTrace({
|
|
21736
21944
|
operation,
|
|
21737
21945
|
startedAt,
|
|
@@ -21739,8 +21947,13 @@ var OpensteerSessionRuntime = class {
|
|
|
21739
21947
|
outcome: "ok",
|
|
21740
21948
|
...actionEvents === void 0 ? {} : { events: actionEvents },
|
|
21741
21949
|
data: {
|
|
21742
|
-
target:
|
|
21743
|
-
...
|
|
21950
|
+
target: resolvedTarget,
|
|
21951
|
+
..."point" in executed.result && executed.result.point !== void 0 ? {
|
|
21952
|
+
point: {
|
|
21953
|
+
x: executed.result.point.x,
|
|
21954
|
+
y: executed.result.point.y
|
|
21955
|
+
}
|
|
21956
|
+
} : {},
|
|
21744
21957
|
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
21745
21958
|
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
21746
21959
|
},
|
|
@@ -23205,20 +23418,20 @@ var OpensteerSessionRuntime = class {
|
|
|
23205
23418
|
throw error;
|
|
23206
23419
|
}
|
|
23207
23420
|
}
|
|
23208
|
-
async
|
|
23209
|
-
const pageRef = await this.ensurePageRef();
|
|
23421
|
+
async readNavigationSummary(targetPageRef) {
|
|
23422
|
+
const pageRef = targetPageRef ?? await this.ensurePageRef();
|
|
23210
23423
|
const pageInfo = await this.requireEngine().getPageInfo({ pageRef });
|
|
23211
|
-
const sessionRef = this.sessionRef;
|
|
23212
|
-
if (!sessionRef) {
|
|
23213
|
-
throw new Error("Opensteer session is not initialized");
|
|
23214
|
-
}
|
|
23215
23424
|
return {
|
|
23216
|
-
sessionRef,
|
|
23217
|
-
pageRef,
|
|
23218
23425
|
url: pageInfo.url,
|
|
23219
23426
|
title: pageInfo.title
|
|
23220
23427
|
};
|
|
23221
23428
|
}
|
|
23429
|
+
async readCreatedPageOutput(pageRef) {
|
|
23430
|
+
return {
|
|
23431
|
+
pageRef,
|
|
23432
|
+
...await this.readNavigationSummary(pageRef)
|
|
23433
|
+
};
|
|
23434
|
+
}
|
|
23222
23435
|
async captureSnapshotArtifacts(pageRef, options, timeout) {
|
|
23223
23436
|
const root = this.requireRoot();
|
|
23224
23437
|
const mainFrame = await timeout.runStep(() => getMainFrame(this.requireEngine(), pageRef));
|
|
@@ -23290,12 +23503,12 @@ var OpensteerSessionRuntime = class {
|
|
|
23290
23503
|
const screenshotPayload = manifestToExternalBinaryLocation(root.rootPath, screenshotManifest);
|
|
23291
23504
|
return {
|
|
23292
23505
|
manifests,
|
|
23293
|
-
|
|
23294
|
-
|
|
23295
|
-
|
|
23296
|
-
|
|
23297
|
-
|
|
23298
|
-
}
|
|
23506
|
+
screenshot: {
|
|
23507
|
+
payload: screenshotPayload,
|
|
23508
|
+
format: output.screenshot.format,
|
|
23509
|
+
size: output.screenshot.size,
|
|
23510
|
+
coordinateSpace: output.screenshot.coordinateSpace,
|
|
23511
|
+
...output.screenshot.clip === void 0 ? {} : { clip: output.screenshot.clip }
|
|
23299
23512
|
}
|
|
23300
23513
|
};
|
|
23301
23514
|
}
|
|
@@ -24818,15 +25031,10 @@ function normalizeNamespace2(value) {
|
|
|
24818
25031
|
const normalized = String(value ?? "default").trim();
|
|
24819
25032
|
return normalized.length === 0 ? "default" : normalized;
|
|
24820
25033
|
}
|
|
24821
|
-
function toOpensteerActionResult(
|
|
25034
|
+
function toOpensteerActionResult(target) {
|
|
24822
25035
|
return {
|
|
24823
|
-
|
|
24824
|
-
...
|
|
24825
|
-
point: {
|
|
24826
|
-
x: result.point.x,
|
|
24827
|
-
y: result.point.y
|
|
24828
|
-
}
|
|
24829
|
-
}
|
|
25036
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
25037
|
+
...target.persist === void 0 ? {} : { persist: target.persist }
|
|
24830
25038
|
};
|
|
24831
25039
|
}
|
|
24832
25040
|
function toOpensteerResolvedTarget2(target) {
|
|
@@ -24836,14 +25044,18 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
24836
25044
|
documentRef: target.documentRef,
|
|
24837
25045
|
documentEpoch: target.documentEpoch,
|
|
24838
25046
|
nodeRef: target.nodeRef,
|
|
24839
|
-
tagName: target.node.nodeName
|
|
25047
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
24840
25048
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
24841
25049
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
24842
25050
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
24843
25051
|
};
|
|
24844
25052
|
}
|
|
25053
|
+
function toOpensteerTagName2(nodeName) {
|
|
25054
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
25055
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
25056
|
+
}
|
|
24845
25057
|
function normalizeOpensteerError(error) {
|
|
24846
|
-
return
|
|
25058
|
+
return normalizeThrownOpensteerError2(error, "Unknown Opensteer runtime failure");
|
|
24847
25059
|
}
|
|
24848
25060
|
function observationArtifactKindFromManifest(kind) {
|
|
24849
25061
|
switch (kind) {
|
|
@@ -25543,6 +25755,7 @@ function payloadByteLength(value) {
|
|
|
25543
25755
|
|
|
25544
25756
|
// src/cloud/session-proxy.ts
|
|
25545
25757
|
var TEMPORARY_CLOUD_WORKSPACE_PREFIX = "opensteer-cloud-workspace-";
|
|
25758
|
+
var CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS = 1e4;
|
|
25546
25759
|
var CloudSessionProxy = class {
|
|
25547
25760
|
rootPath;
|
|
25548
25761
|
workspace;
|
|
@@ -25556,6 +25769,8 @@ var CloudSessionProxy = class {
|
|
|
25556
25769
|
automation;
|
|
25557
25770
|
workspaceStore;
|
|
25558
25771
|
syncWorkspaceOnClose = false;
|
|
25772
|
+
liveSessionStateEstablished = false;
|
|
25773
|
+
storedInstrumentation = [];
|
|
25559
25774
|
constructor(cloud, options = {}) {
|
|
25560
25775
|
this.cloud = cloud;
|
|
25561
25776
|
this.workspace = options.workspace;
|
|
@@ -25585,15 +25800,12 @@ var CloudSessionProxy = class {
|
|
|
25585
25800
|
if (this.client === void 0 && this.sessionId === void 0 && persisted !== void 0 && await this.isReusableCloudSession(persisted.sessionId)) {
|
|
25586
25801
|
this.bindClient(persisted);
|
|
25587
25802
|
}
|
|
25588
|
-
|
|
25589
|
-
|
|
25590
|
-
|
|
25591
|
-
|
|
25592
|
-
|
|
25593
|
-
|
|
25594
|
-
};
|
|
25595
|
-
} catch {
|
|
25596
|
-
}
|
|
25803
|
+
const sessionInfo = this.automation ? await this.automation.getSessionInfo().catch(() => void 0) : void 0;
|
|
25804
|
+
if (sessionInfo !== void 0) {
|
|
25805
|
+
return {
|
|
25806
|
+
...sessionInfo,
|
|
25807
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace }
|
|
25808
|
+
};
|
|
25597
25809
|
}
|
|
25598
25810
|
return {
|
|
25599
25811
|
provider: {
|
|
@@ -25705,12 +25917,26 @@ var CloudSessionProxy = class {
|
|
|
25705
25917
|
return this.invokeSemanticOperation("session.cookies", input);
|
|
25706
25918
|
}
|
|
25707
25919
|
async route(input) {
|
|
25708
|
-
await this.
|
|
25709
|
-
|
|
25920
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
25921
|
+
"instrumentation.route",
|
|
25922
|
+
(automation) => automation.route(input)
|
|
25923
|
+
);
|
|
25924
|
+
this.storedInstrumentation.push({
|
|
25925
|
+
kind: "route",
|
|
25926
|
+
input
|
|
25927
|
+
});
|
|
25928
|
+
return registration;
|
|
25710
25929
|
}
|
|
25711
25930
|
async interceptScript(input) {
|
|
25712
|
-
await this.
|
|
25713
|
-
|
|
25931
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
25932
|
+
"instrumentation.intercept-script",
|
|
25933
|
+
(automation) => automation.interceptScript(input)
|
|
25934
|
+
);
|
|
25935
|
+
this.storedInstrumentation.push({
|
|
25936
|
+
kind: "intercept-script",
|
|
25937
|
+
input
|
|
25938
|
+
});
|
|
25939
|
+
return registration;
|
|
25714
25940
|
}
|
|
25715
25941
|
async getStorageSnapshot(input = {}) {
|
|
25716
25942
|
return this.invokeSemanticOperation("session.storage", input);
|
|
@@ -25758,6 +25984,8 @@ var CloudSessionProxy = class {
|
|
|
25758
25984
|
this.client = void 0;
|
|
25759
25985
|
this.sessionId = void 0;
|
|
25760
25986
|
this.semanticGrant = void 0;
|
|
25987
|
+
this.liveSessionStateEstablished = false;
|
|
25988
|
+
this.storedInstrumentation.length = 0;
|
|
25761
25989
|
if (this.cleanupRootOnClose) {
|
|
25762
25990
|
await promises.rm(this.rootPath, { recursive: true, force: true }).catch(() => void 0);
|
|
25763
25991
|
}
|
|
@@ -25785,6 +26013,8 @@ var CloudSessionProxy = class {
|
|
|
25785
26013
|
this.automation = void 0;
|
|
25786
26014
|
this.sessionId = void 0;
|
|
25787
26015
|
this.semanticGrant = void 0;
|
|
26016
|
+
this.liveSessionStateEstablished = false;
|
|
26017
|
+
this.storedInstrumentation.length = 0;
|
|
25788
26018
|
if (syncError !== void 0) {
|
|
25789
26019
|
throw syncError;
|
|
25790
26020
|
}
|
|
@@ -25832,6 +26062,7 @@ var CloudSessionProxy = class {
|
|
|
25832
26062
|
};
|
|
25833
26063
|
await this.writePersistedSession(record);
|
|
25834
26064
|
this.bindClient(record, session.initialGrants?.semantic);
|
|
26065
|
+
await this.restoreStoredInstrumentation();
|
|
25835
26066
|
}
|
|
25836
26067
|
async syncWorkspaceToCloud() {
|
|
25837
26068
|
if (this.workspace === void 0) {
|
|
@@ -25843,6 +26074,7 @@ var CloudSessionProxy = class {
|
|
|
25843
26074
|
bindClient(record, initialSemanticGrant) {
|
|
25844
26075
|
this.sessionId = record.sessionId;
|
|
25845
26076
|
this.semanticGrant = initialSemanticGrant?.kind === "semantic" ? initialSemanticGrant : void 0;
|
|
26077
|
+
this.liveSessionStateEstablished = false;
|
|
25846
26078
|
this.client = new OpensteerSemanticRestClient({
|
|
25847
26079
|
getBaseUrl: async () => (await this.ensureSemanticGrant()).url,
|
|
25848
26080
|
getAuthorizationHeader: async () => `Bearer ${(await this.ensureSemanticGrant()).token}`,
|
|
@@ -25850,6 +26082,19 @@ var CloudSessionProxy = class {
|
|
|
25850
26082
|
});
|
|
25851
26083
|
this.automation = new OpensteerCloudAutomationClient(this.cloud, record.sessionId);
|
|
25852
26084
|
}
|
|
26085
|
+
async restoreStoredInstrumentation() {
|
|
26086
|
+
if (this.storedInstrumentation.length === 0) {
|
|
26087
|
+
return;
|
|
26088
|
+
}
|
|
26089
|
+
const automation = this.requireAutomation();
|
|
26090
|
+
for (const registration of this.storedInstrumentation) {
|
|
26091
|
+
if (registration.kind === "route") {
|
|
26092
|
+
await automation.route(registration.input);
|
|
26093
|
+
} else {
|
|
26094
|
+
await automation.interceptScript(registration.input);
|
|
26095
|
+
}
|
|
26096
|
+
}
|
|
26097
|
+
}
|
|
25853
26098
|
async ensureWorkspaceStore() {
|
|
25854
26099
|
if (this.workspaceStore !== void 0) {
|
|
25855
26100
|
return this.workspaceStore;
|
|
@@ -25872,13 +26117,22 @@ var CloudSessionProxy = class {
|
|
|
25872
26117
|
async clearPersistedSession() {
|
|
25873
26118
|
await clearPersistedSessionRecord(this.rootPath, "cloud").catch(() => void 0);
|
|
25874
26119
|
}
|
|
26120
|
+
async invalidateSession() {
|
|
26121
|
+
await this.automation?.close().catch(() => void 0);
|
|
26122
|
+
this.automation = void 0;
|
|
26123
|
+
this.client = void 0;
|
|
26124
|
+
this.sessionId = void 0;
|
|
26125
|
+
this.semanticGrant = void 0;
|
|
26126
|
+
this.liveSessionStateEstablished = false;
|
|
26127
|
+
await this.clearPersistedSession();
|
|
26128
|
+
}
|
|
25875
26129
|
async isReusableCloudSession(sessionId, timeout) {
|
|
25876
26130
|
try {
|
|
25877
26131
|
const session = await this.cloud.getSession(sessionId, {
|
|
25878
26132
|
signal: timeout?.signal,
|
|
25879
26133
|
timeoutMs: timeout?.remainingMs()
|
|
25880
26134
|
});
|
|
25881
|
-
return session
|
|
26135
|
+
return isReusableCloudSessionState(session);
|
|
25882
26136
|
} catch (error) {
|
|
25883
26137
|
if (isMissingCloudSessionError(error)) {
|
|
25884
26138
|
return false;
|
|
@@ -25927,26 +26181,79 @@ var CloudSessionProxy = class {
|
|
|
25927
26181
|
try {
|
|
25928
26182
|
await this.ensureSemanticGrant(true);
|
|
25929
26183
|
return true;
|
|
25930
|
-
} catch {
|
|
26184
|
+
} catch (refreshError) {
|
|
26185
|
+
if (await this.resetStaleSession(refreshError)) {
|
|
26186
|
+
throw refreshError;
|
|
26187
|
+
}
|
|
25931
26188
|
return false;
|
|
25932
26189
|
}
|
|
25933
26190
|
}
|
|
25934
26191
|
async invokeSemanticOperation(operation, input, sessionInit = {}) {
|
|
25935
|
-
return this.
|
|
26192
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
25936
26193
|
await this.ensureSession(sessionInit, timeout);
|
|
25937
26194
|
await this.ensureSemanticGrant(false, timeout);
|
|
25938
|
-
|
|
26195
|
+
const output = await this.requireClient().invoke(operation, input, {
|
|
25939
26196
|
signal: timeout.signal,
|
|
25940
26197
|
timeoutMs: timeout.remainingMs()
|
|
25941
26198
|
});
|
|
26199
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
26200
|
+
return output;
|
|
25942
26201
|
});
|
|
25943
26202
|
}
|
|
25944
26203
|
async invokeAutomationOperation(operation, invoke, sessionInit = {}) {
|
|
25945
|
-
return this.
|
|
26204
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
25946
26205
|
await this.ensureSession(sessionInit, timeout);
|
|
25947
|
-
|
|
26206
|
+
const output = await invoke(this.requireAutomation());
|
|
26207
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
26208
|
+
return output;
|
|
26209
|
+
});
|
|
26210
|
+
}
|
|
26211
|
+
async invokeBootstrapInstrumentationOperation(operation, invoke) {
|
|
26212
|
+
let recovered = false;
|
|
26213
|
+
while (true) {
|
|
26214
|
+
try {
|
|
26215
|
+
await this.ensureSession();
|
|
26216
|
+
return await invoke(this.requireAutomation());
|
|
26217
|
+
} catch (error) {
|
|
26218
|
+
const stale = await this.resetStaleSession(error);
|
|
26219
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
26220
|
+
throw error;
|
|
26221
|
+
}
|
|
26222
|
+
recovered = true;
|
|
26223
|
+
}
|
|
26224
|
+
}
|
|
26225
|
+
}
|
|
26226
|
+
async runOperationWithSessionRecovery(operation, invoke) {
|
|
26227
|
+
return this.runOperationWithPolicy(operation, async (timeout) => {
|
|
26228
|
+
let recovered = false;
|
|
26229
|
+
while (true) {
|
|
26230
|
+
try {
|
|
26231
|
+
return await invoke(timeout);
|
|
26232
|
+
} catch (error) {
|
|
26233
|
+
const stale = await this.resetStaleSession(error);
|
|
26234
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
26235
|
+
throw error;
|
|
26236
|
+
}
|
|
26237
|
+
recovered = true;
|
|
26238
|
+
}
|
|
26239
|
+
}
|
|
25948
26240
|
});
|
|
25949
26241
|
}
|
|
26242
|
+
async resetStaleSession(error) {
|
|
26243
|
+
if (!isRecoverableCloudSessionError(error)) {
|
|
26244
|
+
return false;
|
|
26245
|
+
}
|
|
26246
|
+
await this.invalidateSession();
|
|
26247
|
+
return true;
|
|
26248
|
+
}
|
|
26249
|
+
canRecoverWithFreshSession(operation) {
|
|
26250
|
+
return !this.liveSessionStateEstablished && isBootstrapRecoveryOperation(operation);
|
|
26251
|
+
}
|
|
26252
|
+
noteSuccessfulLiveOperation(operation) {
|
|
26253
|
+
if (operation === "session.open" || operation === "page.list" || operation === "page.new" || operation === "page.activate" || operation === "page.close" || operation === "page.goto" || operation === "page.evaluate" || operation === "page.add-init-script" || operation === "page.snapshot" || operation === "dom.click" || operation === "dom.hover" || operation === "dom.input" || operation === "dom.scroll" || operation === "dom.extract" || operation === "network.query" || operation === "network.detail" || operation === "interaction.capture" || operation === "interaction.get" || operation === "interaction.diff" || operation === "interaction.replay" || operation === "scripts.capture" || operation === "artifact.read" || operation === "scripts.beautify" || operation === "scripts.deobfuscate" || operation === "scripts.sandbox" || operation === "captcha.solve" || operation === "session.cookies" || operation === "session.storage" || operation === "session.state" || operation === "session.fetch" || operation === "computer.execute") {
|
|
26254
|
+
this.liveSessionStateEstablished = true;
|
|
26255
|
+
}
|
|
26256
|
+
}
|
|
25950
26257
|
async runOperationWithPolicy(operation, invoke) {
|
|
25951
26258
|
return runWithPolicyTimeout(this.policy.timeout, { operation }, invoke);
|
|
25952
26259
|
}
|
|
@@ -25970,8 +26277,29 @@ function assertSupportedCloudBrowserMode(browser) {
|
|
|
25970
26277
|
}
|
|
25971
26278
|
}
|
|
25972
26279
|
function isMissingCloudSessionError(error) {
|
|
26280
|
+
if (error instanceof OpensteerCloudRequestError) {
|
|
26281
|
+
return error.statusCode === 404 && (error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND");
|
|
26282
|
+
}
|
|
25973
26283
|
return error instanceof Error && /\b404\b/.test(error.message);
|
|
25974
26284
|
}
|
|
26285
|
+
function isRecoverableCloudSessionError(error) {
|
|
26286
|
+
if (!(error instanceof OpensteerCloudRequestError)) {
|
|
26287
|
+
return false;
|
|
26288
|
+
}
|
|
26289
|
+
if (error.statusCode === 404) {
|
|
26290
|
+
return error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND";
|
|
26291
|
+
}
|
|
26292
|
+
return error.statusCode === 409 && error.code === "CLOUD_SESSION_STALE";
|
|
26293
|
+
}
|
|
26294
|
+
function isBootstrapRecoveryOperation(operation) {
|
|
26295
|
+
return operation === "session.open" || operation === "instrumentation.route" || operation === "instrumentation.intercept-script";
|
|
26296
|
+
}
|
|
26297
|
+
function isReusableCloudSessionState(session) {
|
|
26298
|
+
if (session.status === "closing" || session.status === "closed" || session.status === "failed") {
|
|
26299
|
+
return false;
|
|
26300
|
+
}
|
|
26301
|
+
return !(typeof session.expiresAt === "number" && session.expiresAt <= Date.now() + CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS);
|
|
26302
|
+
}
|
|
25975
26303
|
function isLoopbackBaseUrl(baseUrl) {
|
|
25976
26304
|
let url;
|
|
25977
26305
|
try {
|
|
@@ -26133,6 +26461,25 @@ var SessionCookieJar = class {
|
|
|
26133
26461
|
return this.cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
|
|
26134
26462
|
}
|
|
26135
26463
|
};
|
|
26464
|
+
function createSdkProtocolError(error, fallbackMessage) {
|
|
26465
|
+
const normalized = normalizeThrownOpensteerError(error, fallbackMessage);
|
|
26466
|
+
return new OpensteerProtocolError(normalized.code, normalized.message, {
|
|
26467
|
+
cause: error,
|
|
26468
|
+
retriable: normalized.retriable,
|
|
26469
|
+
...normalized.capability === void 0 ? {} : { capability: normalized.capability },
|
|
26470
|
+
...normalized.details === void 0 ? {} : { details: normalized.details }
|
|
26471
|
+
});
|
|
26472
|
+
}
|
|
26473
|
+
async function wrapSdkError(operation, fn) {
|
|
26474
|
+
try {
|
|
26475
|
+
return await fn();
|
|
26476
|
+
} catch (error) {
|
|
26477
|
+
if (isOpensteerProtocolError(error)) {
|
|
26478
|
+
throw error;
|
|
26479
|
+
}
|
|
26480
|
+
throw createSdkProtocolError(error, `${operation} failed`);
|
|
26481
|
+
}
|
|
26482
|
+
}
|
|
26136
26483
|
var Opensteer = class {
|
|
26137
26484
|
runtime;
|
|
26138
26485
|
browserManager;
|
|
@@ -26140,207 +26487,265 @@ var Opensteer = class {
|
|
|
26140
26487
|
dom;
|
|
26141
26488
|
network;
|
|
26142
26489
|
constructor(options = {}) {
|
|
26143
|
-
|
|
26144
|
-
|
|
26145
|
-
|
|
26146
|
-
|
|
26147
|
-
environment
|
|
26148
|
-
});
|
|
26149
|
-
if (runtimeConfig.provider.mode === "cloud") {
|
|
26150
|
-
this.browserManager = void 0;
|
|
26151
|
-
this.runtime = createOpensteerSemanticRuntime({
|
|
26152
|
-
...provider === void 0 ? {} : { provider },
|
|
26153
|
-
...engineName === void 0 ? {} : { engine: engineName },
|
|
26154
|
-
environment,
|
|
26155
|
-
runtimeOptions
|
|
26156
|
-
});
|
|
26157
|
-
this.browser = createUnsupportedBrowserController();
|
|
26158
|
-
} else {
|
|
26159
|
-
this.browserManager = new OpensteerBrowserManager({
|
|
26160
|
-
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
26161
|
-
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
26162
|
-
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
26163
|
-
...engineName === void 0 ? {} : { engineName },
|
|
26164
|
-
environment,
|
|
26165
|
-
...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
|
|
26166
|
-
...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
|
|
26167
|
-
...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
|
|
26168
|
-
});
|
|
26169
|
-
this.runtime = createOpensteerSemanticRuntime({
|
|
26490
|
+
try {
|
|
26491
|
+
const environment = resolveOpensteerEnvironment(options.rootDir);
|
|
26492
|
+
const { provider, engineName, ...runtimeOptions } = options;
|
|
26493
|
+
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
26170
26494
|
...provider === void 0 ? {} : { provider },
|
|
26171
|
-
|
|
26172
|
-
environment,
|
|
26173
|
-
runtimeOptions: {
|
|
26174
|
-
...runtimeOptions,
|
|
26175
|
-
rootPath: this.browserManager.rootPath,
|
|
26176
|
-
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
26177
|
-
}
|
|
26495
|
+
environment
|
|
26178
26496
|
});
|
|
26179
|
-
|
|
26180
|
-
|
|
26181
|
-
|
|
26182
|
-
|
|
26183
|
-
|
|
26497
|
+
if (runtimeConfig.provider.mode === "cloud") {
|
|
26498
|
+
this.browserManager = void 0;
|
|
26499
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
26500
|
+
...provider === void 0 ? {} : { provider },
|
|
26501
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
26502
|
+
environment,
|
|
26503
|
+
runtimeOptions
|
|
26504
|
+
});
|
|
26505
|
+
this.browser = createUnsupportedBrowserController();
|
|
26506
|
+
} else {
|
|
26507
|
+
this.browserManager = new OpensteerBrowserManager({
|
|
26508
|
+
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
26509
|
+
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
26510
|
+
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
26511
|
+
...engineName === void 0 ? {} : { engineName },
|
|
26512
|
+
environment,
|
|
26513
|
+
...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
|
|
26514
|
+
...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
|
|
26515
|
+
...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
|
|
26516
|
+
});
|
|
26517
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
26518
|
+
...provider === void 0 ? {} : { provider },
|
|
26519
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
26520
|
+
environment,
|
|
26521
|
+
runtimeOptions: {
|
|
26522
|
+
...runtimeOptions,
|
|
26523
|
+
rootPath: this.browserManager.rootPath,
|
|
26524
|
+
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
26525
|
+
}
|
|
26526
|
+
});
|
|
26527
|
+
this.browser = {
|
|
26528
|
+
status: () => wrapSdkError("browser.status", () => this.browserManager.status()),
|
|
26529
|
+
clone: (input) => wrapSdkError("browser.clone", () => this.browserManager.clonePersistentBrowser(input)),
|
|
26530
|
+
reset: () => wrapSdkError("browser.reset", () => this.browserManager.reset()),
|
|
26531
|
+
delete: () => wrapSdkError("browser.delete", () => this.browserManager.delete())
|
|
26532
|
+
};
|
|
26533
|
+
}
|
|
26534
|
+
this.dom = {
|
|
26535
|
+
click: (input) => this.click(input),
|
|
26536
|
+
hover: (input) => this.hover(input),
|
|
26537
|
+
input: (input) => this.input(input),
|
|
26538
|
+
scroll: (input) => this.scroll(input)
|
|
26184
26539
|
};
|
|
26540
|
+
this.network = {
|
|
26541
|
+
query: (input = {}) => wrapSdkError("network.query", () => this.runtime.queryNetwork(input)),
|
|
26542
|
+
detail: (recordId, options2) => wrapSdkError(
|
|
26543
|
+
"network.detail",
|
|
26544
|
+
() => this.runtime.getNetworkDetail({ recordId, ...options2 })
|
|
26545
|
+
)
|
|
26546
|
+
};
|
|
26547
|
+
} catch (error) {
|
|
26548
|
+
if (isOpensteerProtocolError(error)) {
|
|
26549
|
+
throw error;
|
|
26550
|
+
}
|
|
26551
|
+
throw createSdkProtocolError(error, "Failed to initialize Opensteer");
|
|
26185
26552
|
}
|
|
26186
|
-
this.dom = {
|
|
26187
|
-
click: (input) => this.click(input),
|
|
26188
|
-
hover: (input) => this.hover(input),
|
|
26189
|
-
input: (input) => this.input(input),
|
|
26190
|
-
scroll: (input) => this.scroll(input)
|
|
26191
|
-
};
|
|
26192
|
-
this.network = {
|
|
26193
|
-
query: (input = {}) => this.runtime.queryNetwork(input),
|
|
26194
|
-
detail: (recordId, options2) => this.runtime.getNetworkDetail({ recordId, ...options2 })
|
|
26195
|
-
};
|
|
26196
26553
|
}
|
|
26197
26554
|
async open(input = {}) {
|
|
26198
|
-
return
|
|
26555
|
+
return wrapSdkError(
|
|
26556
|
+
"session.open",
|
|
26557
|
+
() => this.runtime.open(typeof input === "string" ? { url: input } : input)
|
|
26558
|
+
);
|
|
26199
26559
|
}
|
|
26200
26560
|
async info() {
|
|
26201
|
-
return this.runtime.info();
|
|
26561
|
+
return wrapSdkError("session.info", () => this.runtime.info());
|
|
26202
26562
|
}
|
|
26203
26563
|
async listPages(input = {}) {
|
|
26204
|
-
return this.runtime.listPages(input);
|
|
26564
|
+
return wrapSdkError("page.list", () => this.runtime.listPages(input));
|
|
26205
26565
|
}
|
|
26206
26566
|
async newPage(input = {}) {
|
|
26207
|
-
return this.runtime.newPage(input);
|
|
26567
|
+
return wrapSdkError("page.new", () => this.runtime.newPage(input));
|
|
26208
26568
|
}
|
|
26209
26569
|
async activatePage(input) {
|
|
26210
|
-
return this.runtime.activatePage(input);
|
|
26570
|
+
return wrapSdkError("page.activate", () => this.runtime.activatePage(input));
|
|
26211
26571
|
}
|
|
26212
26572
|
async closePage(input = {}) {
|
|
26213
|
-
return this.runtime.closePage(input);
|
|
26573
|
+
return wrapSdkError("page.close", () => this.runtime.closePage(input));
|
|
26214
26574
|
}
|
|
26215
26575
|
async goto(url, options = {}) {
|
|
26216
|
-
return
|
|
26217
|
-
|
|
26218
|
-
|
|
26219
|
-
|
|
26576
|
+
return wrapSdkError(
|
|
26577
|
+
"page.goto",
|
|
26578
|
+
() => this.runtime.goto({
|
|
26579
|
+
url,
|
|
26580
|
+
...options
|
|
26581
|
+
})
|
|
26582
|
+
);
|
|
26220
26583
|
}
|
|
26221
26584
|
async evaluate(input) {
|
|
26222
|
-
|
|
26223
|
-
|
|
26224
|
-
|
|
26225
|
-
|
|
26585
|
+
return wrapSdkError("page.evaluate", async () => {
|
|
26586
|
+
const normalized = typeof input === "string" ? {
|
|
26587
|
+
script: input
|
|
26588
|
+
} : input;
|
|
26589
|
+
return (await this.runtime.evaluate(normalized)).value;
|
|
26590
|
+
});
|
|
26226
26591
|
}
|
|
26227
26592
|
async addInitScript(input) {
|
|
26228
|
-
return
|
|
26229
|
-
|
|
26230
|
-
|
|
26231
|
-
|
|
26593
|
+
return wrapSdkError(
|
|
26594
|
+
"page.addInitScript",
|
|
26595
|
+
() => this.runtime.addInitScript(
|
|
26596
|
+
typeof input === "string" ? {
|
|
26597
|
+
script: input
|
|
26598
|
+
} : input
|
|
26599
|
+
)
|
|
26232
26600
|
);
|
|
26233
26601
|
}
|
|
26234
26602
|
async click(input) {
|
|
26235
|
-
|
|
26236
|
-
|
|
26237
|
-
|
|
26238
|
-
|
|
26239
|
-
|
|
26240
|
-
|
|
26603
|
+
return wrapSdkError("dom.click", () => {
|
|
26604
|
+
const { button, clickCount, modifiers, ...target } = input;
|
|
26605
|
+
return this.runtime.click({
|
|
26606
|
+
...normalizeTargetOptions(target),
|
|
26607
|
+
...button === void 0 ? {} : { button },
|
|
26608
|
+
...clickCount === void 0 ? {} : { clickCount },
|
|
26609
|
+
...modifiers === void 0 ? {} : { modifiers }
|
|
26610
|
+
});
|
|
26241
26611
|
});
|
|
26242
26612
|
}
|
|
26243
26613
|
async hover(input) {
|
|
26244
|
-
return this.runtime.hover(normalizeTargetOptions(input));
|
|
26614
|
+
return wrapSdkError("dom.hover", () => this.runtime.hover(normalizeTargetOptions(input)));
|
|
26245
26615
|
}
|
|
26246
26616
|
async input(input) {
|
|
26247
|
-
return
|
|
26248
|
-
|
|
26249
|
-
|
|
26250
|
-
|
|
26251
|
-
|
|
26617
|
+
return wrapSdkError(
|
|
26618
|
+
"dom.input",
|
|
26619
|
+
() => this.runtime.input({
|
|
26620
|
+
...normalizeTargetOptions(input),
|
|
26621
|
+
text: input.text,
|
|
26622
|
+
...input.pressEnter === void 0 ? {} : { pressEnter: input.pressEnter }
|
|
26623
|
+
})
|
|
26624
|
+
);
|
|
26252
26625
|
}
|
|
26253
26626
|
async scroll(input) {
|
|
26254
|
-
return
|
|
26255
|
-
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
|
|
26627
|
+
return wrapSdkError(
|
|
26628
|
+
"dom.scroll",
|
|
26629
|
+
() => this.runtime.scroll({
|
|
26630
|
+
...normalizeTargetOptions(input),
|
|
26631
|
+
direction: input.direction,
|
|
26632
|
+
amount: input.amount
|
|
26633
|
+
})
|
|
26634
|
+
);
|
|
26259
26635
|
}
|
|
26260
26636
|
async extract(input) {
|
|
26261
|
-
return (await this.runtime.extract(input)).data;
|
|
26637
|
+
return wrapSdkError("extract", async () => (await this.runtime.extract(input)).data);
|
|
26262
26638
|
}
|
|
26263
26639
|
async waitForPage(input = {}) {
|
|
26264
|
-
|
|
26265
|
-
|
|
26266
|
-
|
|
26267
|
-
|
|
26268
|
-
|
|
26269
|
-
|
|
26270
|
-
|
|
26271
|
-
|
|
26272
|
-
|
|
26273
|
-
|
|
26640
|
+
return wrapSdkError("page.waitForPage", async () => {
|
|
26641
|
+
const baseline = new Set((await this.runtime.listPages()).pages.map((page) => page.pageRef));
|
|
26642
|
+
const timeoutAt = Date.now() + (input.timeoutMs ?? 3e4);
|
|
26643
|
+
const pollIntervalMs = input.pollIntervalMs ?? 100;
|
|
26644
|
+
while (true) {
|
|
26645
|
+
const match = (await this.runtime.listPages()).pages.find((page) => {
|
|
26646
|
+
if (baseline.has(page.pageRef)) {
|
|
26647
|
+
return false;
|
|
26648
|
+
}
|
|
26649
|
+
if (input.openerPageRef !== void 0 && page.openerPageRef !== input.openerPageRef) {
|
|
26650
|
+
return false;
|
|
26651
|
+
}
|
|
26652
|
+
if (input.urlIncludes !== void 0 && !page.url.includes(input.urlIncludes)) {
|
|
26653
|
+
return false;
|
|
26654
|
+
}
|
|
26655
|
+
return true;
|
|
26656
|
+
});
|
|
26657
|
+
if (match !== void 0) {
|
|
26658
|
+
return match;
|
|
26274
26659
|
}
|
|
26275
|
-
if (
|
|
26276
|
-
|
|
26660
|
+
if (Date.now() >= timeoutAt) {
|
|
26661
|
+
throw new OpensteerProtocolError("timeout", "waitForPage timed out");
|
|
26277
26662
|
}
|
|
26278
|
-
|
|
26279
|
-
});
|
|
26280
|
-
if (match !== void 0) {
|
|
26281
|
-
return match;
|
|
26282
|
-
}
|
|
26283
|
-
if (Date.now() >= timeoutAt) {
|
|
26284
|
-
throw new Error("waitForPage timed out");
|
|
26663
|
+
await delay3(pollIntervalMs);
|
|
26285
26664
|
}
|
|
26286
|
-
|
|
26287
|
-
}
|
|
26665
|
+
});
|
|
26288
26666
|
}
|
|
26289
26667
|
async cookies(domain) {
|
|
26290
|
-
return
|
|
26291
|
-
|
|
26668
|
+
return wrapSdkError(
|
|
26669
|
+
"session.cookies",
|
|
26670
|
+
async () => new SessionCookieJar(await this.runtime.getCookies(domain === void 0 ? {} : { domain }))
|
|
26292
26671
|
);
|
|
26293
26672
|
}
|
|
26294
26673
|
async storage(domain, type = "local") {
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
|
|
26299
|
-
|
|
26300
|
-
|
|
26301
|
-
|
|
26674
|
+
return wrapSdkError("session.storage", async () => {
|
|
26675
|
+
const snapshot = await this.runtime.getStorageSnapshot(
|
|
26676
|
+
domain === void 0 ? {} : { domain }
|
|
26677
|
+
);
|
|
26678
|
+
const domainSnapshot = pickStorageDomainSnapshot(snapshot, domain);
|
|
26679
|
+
if (domainSnapshot === void 0) {
|
|
26680
|
+
return {};
|
|
26681
|
+
}
|
|
26682
|
+
const entries = type === "local" ? domainSnapshot.localStorage : domainSnapshot.sessionStorage;
|
|
26683
|
+
return Object.fromEntries(entries.map((entry) => [entry.key, entry.value]));
|
|
26684
|
+
});
|
|
26302
26685
|
}
|
|
26303
26686
|
async state(domain) {
|
|
26304
|
-
return
|
|
26687
|
+
return wrapSdkError(
|
|
26688
|
+
"session.state",
|
|
26689
|
+
() => this.runtime.getBrowserState(domain === void 0 ? {} : { domain })
|
|
26690
|
+
);
|
|
26305
26691
|
}
|
|
26306
26692
|
async fetch(url, options = {}) {
|
|
26307
|
-
|
|
26308
|
-
|
|
26309
|
-
|
|
26310
|
-
|
|
26311
|
-
|
|
26312
|
-
|
|
26693
|
+
return wrapSdkError("session.fetch", async () => {
|
|
26694
|
+
const input = buildFetchInput(url, options);
|
|
26695
|
+
const result = await this.runtime.fetch(input);
|
|
26696
|
+
if (result.response === void 0) {
|
|
26697
|
+
throw new OpensteerProtocolError(
|
|
26698
|
+
"operation-failed",
|
|
26699
|
+
result.note ?? `session.fetch did not produce a response for ${url}`
|
|
26700
|
+
);
|
|
26701
|
+
}
|
|
26702
|
+
return toResponse(result.response);
|
|
26703
|
+
});
|
|
26313
26704
|
}
|
|
26314
26705
|
async computerExecute(input) {
|
|
26315
|
-
return this.runtime.computerExecute(input);
|
|
26706
|
+
return wrapSdkError("session.computerExecute", () => this.runtime.computerExecute(input));
|
|
26316
26707
|
}
|
|
26317
26708
|
async route(input) {
|
|
26318
|
-
return
|
|
26709
|
+
return wrapSdkError(
|
|
26710
|
+
"session.route",
|
|
26711
|
+
() => this.requireOwnedInstrumentationRuntime("route").route(input)
|
|
26712
|
+
);
|
|
26319
26713
|
}
|
|
26320
26714
|
async interceptScript(input) {
|
|
26321
|
-
return
|
|
26715
|
+
return wrapSdkError(
|
|
26716
|
+
"session.interceptScript",
|
|
26717
|
+
() => this.requireOwnedInstrumentationRuntime("interceptScript").interceptScript(input)
|
|
26718
|
+
);
|
|
26322
26719
|
}
|
|
26323
26720
|
async close() {
|
|
26324
|
-
|
|
26325
|
-
|
|
26326
|
-
|
|
26327
|
-
|
|
26328
|
-
|
|
26329
|
-
|
|
26721
|
+
return wrapSdkError("session.close", async () => {
|
|
26722
|
+
if (this.browserManager === void 0 || this.browserManager.mode === "temporary") {
|
|
26723
|
+
return this.runtime.close();
|
|
26724
|
+
}
|
|
26725
|
+
const output = await this.runtime.close();
|
|
26726
|
+
await this.browserManager.close();
|
|
26727
|
+
return output;
|
|
26728
|
+
});
|
|
26330
26729
|
}
|
|
26331
26730
|
async disconnect() {
|
|
26332
|
-
|
|
26731
|
+
return wrapSdkError("session.disconnect", () => this.runtime.disconnect());
|
|
26333
26732
|
}
|
|
26334
26733
|
requireOwnedInstrumentationRuntime(method) {
|
|
26335
26734
|
if (typeof this.runtime.route === "function" && typeof this.runtime.interceptScript === "function") {
|
|
26336
26735
|
return this.runtime;
|
|
26337
26736
|
}
|
|
26338
|
-
throw new
|
|
26737
|
+
throw new OpensteerProtocolError(
|
|
26738
|
+
"unsupported-operation",
|
|
26739
|
+
`${method}() is not available for this session runtime.`
|
|
26740
|
+
);
|
|
26339
26741
|
}
|
|
26340
26742
|
};
|
|
26341
26743
|
function createUnsupportedBrowserController() {
|
|
26342
26744
|
const fail = async () => {
|
|
26343
|
-
throw new
|
|
26745
|
+
throw new OpensteerProtocolError(
|
|
26746
|
+
"unsupported-operation",
|
|
26747
|
+
"browser.* helpers are only available in local mode."
|
|
26748
|
+
);
|
|
26344
26749
|
};
|
|
26345
26750
|
return {
|
|
26346
26751
|
status: fail,
|
|
@@ -26353,7 +26758,10 @@ function normalizeTargetOptions(input) {
|
|
|
26353
26758
|
const hasElement = input.element !== void 0;
|
|
26354
26759
|
const hasSelector = input.selector !== void 0;
|
|
26355
26760
|
if (hasElement && hasSelector) {
|
|
26356
|
-
throw new
|
|
26761
|
+
throw new OpensteerProtocolError(
|
|
26762
|
+
"invalid-argument",
|
|
26763
|
+
"Specify exactly one of element, selector, or persist."
|
|
26764
|
+
);
|
|
26357
26765
|
}
|
|
26358
26766
|
if (hasElement) {
|
|
26359
26767
|
return {
|
|
@@ -26376,7 +26784,10 @@ function normalizeTargetOptions(input) {
|
|
|
26376
26784
|
};
|
|
26377
26785
|
}
|
|
26378
26786
|
if (input.persist === void 0) {
|
|
26379
|
-
throw new
|
|
26787
|
+
throw new OpensteerProtocolError(
|
|
26788
|
+
"invalid-argument",
|
|
26789
|
+
"Specify exactly one of element, selector, or persist."
|
|
26790
|
+
);
|
|
26380
26791
|
}
|
|
26381
26792
|
return {
|
|
26382
26793
|
target: {
|
|
@@ -26448,6 +26859,7 @@ exports.Opensteer = Opensteer;
|
|
|
26448
26859
|
exports.OpensteerAttachAmbiguousError = OpensteerAttachAmbiguousError;
|
|
26449
26860
|
exports.OpensteerBrowserManager = OpensteerBrowserManager;
|
|
26450
26861
|
exports.OpensteerCloudClient = OpensteerCloudClient;
|
|
26862
|
+
exports.OpensteerProtocolError = OpensteerProtocolError;
|
|
26451
26863
|
exports.STABLE_PRIMARY_ATTR_KEYS = STABLE_PRIMARY_ATTR_KEYS;
|
|
26452
26864
|
exports.assertProviderSupportsEngine = assertProviderSupportsEngine;
|
|
26453
26865
|
exports.buildArrayFieldPathCandidates = buildArrayFieldPathCandidates;
|
|
@@ -26477,6 +26889,7 @@ exports.discoverLocalCdpBrowsers = discoverLocalCdpBrowsers;
|
|
|
26477
26889
|
exports.hashDomDescriptorPersist = hashDomDescriptorPersist;
|
|
26478
26890
|
exports.inspectCdpEndpoint = inspectCdpEndpoint;
|
|
26479
26891
|
exports.isCurrentUrlField = isCurrentUrlField;
|
|
26892
|
+
exports.isOpensteerProtocolError = isOpensteerProtocolError;
|
|
26480
26893
|
exports.isValidCssAttributeKey = isValidCssAttributeKey;
|
|
26481
26894
|
exports.listLocalChromeProfiles = listLocalChromeProfiles;
|
|
26482
26895
|
exports.manifestToExternalBinaryLocation = manifestToExternalBinaryLocation;
|
|
@@ -26485,6 +26898,7 @@ exports.normalizeObservabilityConfig = normalizeObservabilityConfig;
|
|
|
26485
26898
|
exports.normalizeOpensteerEngineName = normalizeOpensteerEngineName;
|
|
26486
26899
|
exports.normalizeOpensteerProviderMode = normalizeOpensteerProviderMode;
|
|
26487
26900
|
exports.normalizeWorkspaceId = normalizeWorkspaceId;
|
|
26901
|
+
exports.opensteerErrorCodes = opensteerErrorCodes;
|
|
26488
26902
|
exports.parseDomDescriptorRecord = parseDomDescriptorRecord;
|
|
26489
26903
|
exports.parseExtractionDescriptorRecord = parseExtractionDescriptorRecord;
|
|
26490
26904
|
exports.readPersistedCloudSessionRecord = readPersistedCloudSessionRecord;
|