opensteer 0.9.6 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{chunk-3I3A5OLB.js → chunk-BPGXP3RF.js} +257 -24
- package/dist/chunk-BPGXP3RF.js.map +1 -0
- package/dist/{chunk-3XBQRZZC.js → chunk-EXXRLPLI.js} +158 -46
- package/dist/chunk-EXXRLPLI.js.map +1 -0
- package/dist/{chunk-T5P2QGZ3.js → chunk-GKYBP3KD.js} +154 -13
- package/dist/chunk-GKYBP3KD.js.map +1 -0
- package/dist/{chunk-BVRIPCWA.js → chunk-LFWP5RXF.js} +500 -513
- package/dist/chunk-LFWP5RXF.js.map +1 -0
- package/dist/{chunk-L4NF74KI.js → chunk-SOJEWKSW.js} +5 -5
- package/dist/{chunk-L4NF74KI.js.map → chunk-SOJEWKSW.js.map} +1 -1
- package/dist/cli/bin.cjs +1230 -660
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +166 -72
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +793 -565
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -51
- package/dist/index.d.ts +36 -51
- package/dist/index.js +4 -4
- package/dist/local-view/public/assets/app.js +10 -1
- package/dist/local-view/serve-entry.cjs +1022 -591
- package/dist/local-view/serve-entry.cjs.map +1 -1
- package/dist/local-view/serve-entry.js +2 -2
- package/dist/opensteer-XLPY343Y.js +6 -0
- package/dist/{opensteer-UGA6YBRN.js.map → opensteer-XLPY343Y.js.map} +1 -1
- package/dist/{session-control-U3L5H2ZI.js → session-control-FVKKD45R.js} +4 -4
- package/dist/{session-control-U3L5H2ZI.js.map → session-control-FVKKD45R.js.map} +1 -1
- package/package.json +5 -5
- package/skills/recorder/SKILL.md +2 -2
- package/dist/chunk-3I3A5OLB.js.map +0 -1
- package/dist/chunk-3XBQRZZC.js.map +0 -1
- package/dist/chunk-BVRIPCWA.js.map +0 -1
- package/dist/chunk-T5P2QGZ3.js.map +0 -1
- package/dist/opensteer-UGA6YBRN.js +0 -6
package/dist/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(
|
|
@@ -1188,7 +1288,7 @@ var visualViewportSchema = objectSchema(
|
|
|
1188
1288
|
required: ["origin", "offsetWithinLayoutViewport", "size"]
|
|
1189
1289
|
}
|
|
1190
1290
|
);
|
|
1191
|
-
|
|
1291
|
+
objectSchema(
|
|
1192
1292
|
{
|
|
1193
1293
|
layoutViewport: layoutViewportSchema,
|
|
1194
1294
|
visualViewport: visualViewportSchema,
|
|
@@ -1223,6 +1323,9 @@ var pageInfoSchema = objectSchema(
|
|
|
1223
1323
|
{
|
|
1224
1324
|
pageRef: pageRefSchema,
|
|
1225
1325
|
sessionRef: sessionRefSchema,
|
|
1326
|
+
targetId: stringSchema({
|
|
1327
|
+
description: "Underlying browser target identifier when available."
|
|
1328
|
+
}),
|
|
1226
1329
|
openerPageRef: pageRefSchema,
|
|
1227
1330
|
url: stringSchema({
|
|
1228
1331
|
description: "Current main-frame URL."
|
|
@@ -2639,7 +2742,7 @@ var domSnapshotSchema = objectSchema(
|
|
|
2639
2742
|
]
|
|
2640
2743
|
}
|
|
2641
2744
|
);
|
|
2642
|
-
|
|
2745
|
+
objectSchema(
|
|
2643
2746
|
{
|
|
2644
2747
|
inputPoint: pointSchema,
|
|
2645
2748
|
inputCoordinateSpace: coordinateSpaceSchema,
|
|
@@ -4092,39 +4195,14 @@ var opensteerTargetInputSchema = oneOfSchema(
|
|
|
4092
4195
|
title: "OpensteerTargetInput"
|
|
4093
4196
|
}
|
|
4094
4197
|
);
|
|
4095
|
-
var opensteerResolvedTargetSchema = objectSchema(
|
|
4096
|
-
{
|
|
4097
|
-
pageRef: pageRefSchema,
|
|
4098
|
-
frameRef: frameRefSchema,
|
|
4099
|
-
documentRef: documentRefSchema,
|
|
4100
|
-
documentEpoch: documentEpochSchema,
|
|
4101
|
-
nodeRef: nodeRefSchema,
|
|
4102
|
-
tagName: stringSchema(),
|
|
4103
|
-
pathHint: stringSchema(),
|
|
4104
|
-
persist: stringSchema(),
|
|
4105
|
-
selectorUsed: stringSchema()
|
|
4106
|
-
},
|
|
4107
|
-
{
|
|
4108
|
-
title: "OpensteerResolvedTarget",
|
|
4109
|
-
required: [
|
|
4110
|
-
"pageRef",
|
|
4111
|
-
"frameRef",
|
|
4112
|
-
"documentRef",
|
|
4113
|
-
"documentEpoch",
|
|
4114
|
-
"nodeRef",
|
|
4115
|
-
"tagName",
|
|
4116
|
-
"pathHint"
|
|
4117
|
-
]
|
|
4118
|
-
}
|
|
4119
|
-
);
|
|
4120
4198
|
var opensteerActionResultSchema = objectSchema(
|
|
4121
4199
|
{
|
|
4122
|
-
|
|
4123
|
-
|
|
4200
|
+
tagName: stringSchema({ minLength: 1 }),
|
|
4201
|
+
persist: stringSchema({ minLength: 1 })
|
|
4124
4202
|
},
|
|
4125
4203
|
{
|
|
4126
4204
|
title: "OpensteerActionResult",
|
|
4127
|
-
required: ["
|
|
4205
|
+
required: ["tagName"]
|
|
4128
4206
|
}
|
|
4129
4207
|
);
|
|
4130
4208
|
var opensteerSnapshotCounterSchema = objectSchema(
|
|
@@ -4170,16 +4248,14 @@ var opensteerSnapshotCounterSchema = objectSchema(
|
|
|
4170
4248
|
]
|
|
4171
4249
|
}
|
|
4172
4250
|
);
|
|
4173
|
-
var
|
|
4251
|
+
var opensteerNavigationSummarySchema = objectSchema(
|
|
4174
4252
|
{
|
|
4175
|
-
sessionRef: sessionRefSchema,
|
|
4176
|
-
pageRef: pageRefSchema,
|
|
4177
4253
|
url: stringSchema(),
|
|
4178
4254
|
title: stringSchema()
|
|
4179
4255
|
},
|
|
4180
4256
|
{
|
|
4181
|
-
title: "
|
|
4182
|
-
required: ["
|
|
4257
|
+
title: "OpensteerNavigationSummary",
|
|
4258
|
+
required: ["url", "title"]
|
|
4183
4259
|
}
|
|
4184
4260
|
);
|
|
4185
4261
|
var opensteerOpenInputSchema = objectSchema(
|
|
@@ -4247,6 +4323,17 @@ var opensteerPageCloseOutputSchema = objectSchema(
|
|
|
4247
4323
|
required: ["closedPageRef", "pages"]
|
|
4248
4324
|
}
|
|
4249
4325
|
);
|
|
4326
|
+
var opensteerPageNewOutputSchema = objectSchema(
|
|
4327
|
+
{
|
|
4328
|
+
pageRef: pageRefSchema,
|
|
4329
|
+
url: stringSchema(),
|
|
4330
|
+
title: stringSchema()
|
|
4331
|
+
},
|
|
4332
|
+
{
|
|
4333
|
+
title: "OpensteerPageNewOutput",
|
|
4334
|
+
required: ["pageRef", "url", "title"]
|
|
4335
|
+
}
|
|
4336
|
+
);
|
|
4250
4337
|
var opensteerPageGotoInputSchema = objectSchema(
|
|
4251
4338
|
{
|
|
4252
4339
|
url: stringSchema(),
|
|
@@ -4633,72 +4720,28 @@ var opensteerComputerExecuteInputSchema = objectSchema(
|
|
|
4633
4720
|
required: ["action"]
|
|
4634
4721
|
}
|
|
4635
4722
|
);
|
|
4636
|
-
var
|
|
4637
|
-
{
|
|
4638
|
-
role: enumSchema(["point", "start", "end"]),
|
|
4639
|
-
point: pointSchema,
|
|
4640
|
-
hitTest: hitTestResultSchema,
|
|
4641
|
-
target: opensteerResolvedTargetSchema
|
|
4642
|
-
},
|
|
4643
|
-
{
|
|
4644
|
-
title: "OpensteerComputerTracePoint",
|
|
4645
|
-
required: ["role", "point"]
|
|
4646
|
-
}
|
|
4647
|
-
);
|
|
4648
|
-
var opensteerComputerTraceEnrichmentSchema = objectSchema(
|
|
4649
|
-
{
|
|
4650
|
-
points: arraySchema(opensteerComputerTracePointSchema)
|
|
4651
|
-
},
|
|
4652
|
-
{
|
|
4653
|
-
title: "OpensteerComputerTraceEnrichment",
|
|
4654
|
-
required: ["points"]
|
|
4655
|
-
}
|
|
4656
|
-
);
|
|
4657
|
-
var opensteerComputerExecuteTimingSchema = objectSchema(
|
|
4723
|
+
var opensteerScreenshotSummarySchema = objectSchema(
|
|
4658
4724
|
{
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
title: "OpensteerComputerExecuteTiming",
|
|
4665
|
-
required: ["actionMs", "waitMs", "totalMs"]
|
|
4666
|
-
}
|
|
4667
|
-
);
|
|
4668
|
-
var opensteerComputerDisplayScaleSchema = objectSchema(
|
|
4669
|
-
{
|
|
4670
|
-
x: numberSchema({ exclusiveMinimum: 0 }),
|
|
4671
|
-
y: numberSchema({ exclusiveMinimum: 0 })
|
|
4725
|
+
payload: externalBinaryLocationSchema,
|
|
4726
|
+
format: screenshotFormatSchema,
|
|
4727
|
+
size: sizeSchema,
|
|
4728
|
+
coordinateSpace: coordinateSpaceSchema,
|
|
4729
|
+
clip: rectSchema
|
|
4672
4730
|
},
|
|
4673
4731
|
{
|
|
4674
|
-
title: "
|
|
4675
|
-
required: ["
|
|
4732
|
+
title: "OpensteerScreenshotSummary",
|
|
4733
|
+
required: ["payload", "format", "size", "coordinateSpace"]
|
|
4676
4734
|
}
|
|
4677
4735
|
);
|
|
4678
4736
|
var opensteerComputerExecuteOutputSchema = objectSchema(
|
|
4679
4737
|
{
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
screenshot:
|
|
4683
|
-
displayViewport: viewportMetricsSchema,
|
|
4684
|
-
nativeViewport: viewportMetricsSchema,
|
|
4685
|
-
displayScale: opensteerComputerDisplayScaleSchema,
|
|
4686
|
-
events: arraySchema(opensteerEventSchema),
|
|
4687
|
-
timing: opensteerComputerExecuteTimingSchema,
|
|
4688
|
-
trace: opensteerComputerTraceEnrichmentSchema
|
|
4738
|
+
url: stringSchema(),
|
|
4739
|
+
title: stringSchema(),
|
|
4740
|
+
screenshot: opensteerScreenshotSummarySchema
|
|
4689
4741
|
},
|
|
4690
4742
|
{
|
|
4691
4743
|
title: "OpensteerComputerExecuteOutput",
|
|
4692
|
-
required: [
|
|
4693
|
-
"action",
|
|
4694
|
-
"pageRef",
|
|
4695
|
-
"screenshot",
|
|
4696
|
-
"displayViewport",
|
|
4697
|
-
"nativeViewport",
|
|
4698
|
-
"displayScale",
|
|
4699
|
-
"events",
|
|
4700
|
-
"timing"
|
|
4701
|
-
]
|
|
4744
|
+
required: ["url", "title", "screenshot"]
|
|
4702
4745
|
}
|
|
4703
4746
|
);
|
|
4704
4747
|
function assertValidSemanticOperationInput(name, input) {
|
|
@@ -4724,7 +4767,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4724
4767
|
name: "session.open",
|
|
4725
4768
|
description: "Open or resume the current Opensteer session and primary page.",
|
|
4726
4769
|
inputSchema: opensteerOpenInputSchema,
|
|
4727
|
-
outputSchema:
|
|
4770
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
4728
4771
|
requiredCapabilities: ["sessions.manage", "pages.manage"],
|
|
4729
4772
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["sessions.manage", "pages.manage"] : ["sessions.manage", "pages.manage", "pages.navigate"]
|
|
4730
4773
|
}),
|
|
@@ -4739,7 +4782,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4739
4782
|
name: "page.new",
|
|
4740
4783
|
description: "Create and optionally navigate a new top-level page in the current session.",
|
|
4741
4784
|
inputSchema: opensteerPageNewInputSchema,
|
|
4742
|
-
outputSchema:
|
|
4785
|
+
outputSchema: opensteerPageNewOutputSchema,
|
|
4743
4786
|
requiredCapabilities: ["pages.manage"],
|
|
4744
4787
|
resolveRequiredCapabilities: (input) => input.url === void 0 ? ["pages.manage"] : ["pages.manage", "pages.navigate"]
|
|
4745
4788
|
}),
|
|
@@ -4747,7 +4790,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4747
4790
|
name: "page.activate",
|
|
4748
4791
|
description: "Activate an existing top-level page in the current session.",
|
|
4749
4792
|
inputSchema: opensteerPageActivateInputSchema,
|
|
4750
|
-
outputSchema:
|
|
4793
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
4751
4794
|
requiredCapabilities: ["pages.manage", "inspect.pages"]
|
|
4752
4795
|
}),
|
|
4753
4796
|
defineSemanticOperationSpec({
|
|
@@ -4761,7 +4804,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
4761
4804
|
name: "page.goto",
|
|
4762
4805
|
description: "Navigate the current Opensteer page to a new URL.",
|
|
4763
4806
|
inputSchema: opensteerPageGotoInputSchema,
|
|
4764
|
-
outputSchema:
|
|
4807
|
+
outputSchema: opensteerNavigationSummarySchema,
|
|
4765
4808
|
requiredCapabilities: ["pages.navigate"]
|
|
4766
4809
|
}),
|
|
4767
4810
|
defineSemanticOperationSpec({
|
|
@@ -6163,6 +6206,9 @@ var FilesystemSessionSink = class {
|
|
|
6163
6206
|
this.store = store;
|
|
6164
6207
|
this.sessionId = sessionId;
|
|
6165
6208
|
}
|
|
6209
|
+
configure(input) {
|
|
6210
|
+
return this.store.configureSession(this.sessionId, input);
|
|
6211
|
+
}
|
|
6166
6212
|
append(input) {
|
|
6167
6213
|
return this.store.appendEvent(this.sessionId, input);
|
|
6168
6214
|
}
|
|
@@ -6193,40 +6239,14 @@ var FilesystemObservationStoreImpl = class {
|
|
|
6193
6239
|
const sessionId = normalizeNonEmptyString("sessionId", input.sessionId);
|
|
6194
6240
|
const openedAt = normalizeTimestamp("openedAt", input.openedAt ?? Date.now());
|
|
6195
6241
|
const config = normalizeObservabilityConfig(input.config);
|
|
6196
|
-
|
|
6197
|
-
this.redactors.set(sessionId, redactor);
|
|
6198
|
-
const redactedLabels = redactor.redactLabels(config.labels);
|
|
6199
|
-
const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
|
|
6200
|
-
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
6201
|
-
const existing = await this.reconcileSessionManifest(sessionId);
|
|
6202
|
-
if (existing === void 0) {
|
|
6203
|
-
await ensureDirectory(this.sessionEventsDirectory(sessionId));
|
|
6204
|
-
await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
|
|
6205
|
-
const session = {
|
|
6206
|
-
sessionId,
|
|
6207
|
-
profile: config.profile,
|
|
6208
|
-
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
6209
|
-
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
6210
|
-
openedAt,
|
|
6211
|
-
updatedAt: openedAt,
|
|
6212
|
-
currentSequence: 0,
|
|
6213
|
-
eventCount: 0,
|
|
6214
|
-
artifactCount: 0
|
|
6215
|
-
};
|
|
6216
|
-
await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
|
|
6217
|
-
return;
|
|
6218
|
-
}
|
|
6219
|
-
const patched = {
|
|
6220
|
-
...existing,
|
|
6221
|
-
profile: config.profile,
|
|
6222
|
-
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
6223
|
-
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
6224
|
-
updatedAt: Math.max(existing.updatedAt, openedAt)
|
|
6225
|
-
};
|
|
6226
|
-
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
|
|
6227
|
-
});
|
|
6242
|
+
await this.applySessionConfiguration(sessionId, config, openedAt);
|
|
6228
6243
|
return new FilesystemSessionSink(this, sessionId);
|
|
6229
6244
|
}
|
|
6245
|
+
async configureSession(sessionId, input) {
|
|
6246
|
+
const updatedAt = normalizeTimestamp("updatedAt", input.updatedAt ?? Date.now());
|
|
6247
|
+
const config = normalizeObservabilityConfig(input.config);
|
|
6248
|
+
await this.applySessionConfiguration(sessionId, config, updatedAt);
|
|
6249
|
+
}
|
|
6230
6250
|
async getSession(sessionId) {
|
|
6231
6251
|
const manifestPath = this.sessionManifestPath(sessionId);
|
|
6232
6252
|
if (!await pathExists(manifestPath)) {
|
|
@@ -6447,6 +6467,40 @@ var FilesystemObservationStoreImpl = class {
|
|
|
6447
6467
|
sessionLockPath(sessionId) {
|
|
6448
6468
|
return path10__default.default.join(this.sessionDirectory(sessionId), ".lock");
|
|
6449
6469
|
}
|
|
6470
|
+
async applySessionConfiguration(sessionId, config, timestamp) {
|
|
6471
|
+
const redactor = createObservationRedactor(config);
|
|
6472
|
+
this.redactors.set(sessionId, redactor);
|
|
6473
|
+
const redactedLabels = redactor.redactLabels(config.labels);
|
|
6474
|
+
const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
|
|
6475
|
+
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
6476
|
+
const existing = await this.reconcileSessionManifest(sessionId);
|
|
6477
|
+
if (existing === void 0) {
|
|
6478
|
+
await ensureDirectory(this.sessionEventsDirectory(sessionId));
|
|
6479
|
+
await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
|
|
6480
|
+
const session = {
|
|
6481
|
+
sessionId,
|
|
6482
|
+
profile: config.profile,
|
|
6483
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
6484
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
6485
|
+
openedAt: timestamp,
|
|
6486
|
+
updatedAt: timestamp,
|
|
6487
|
+
currentSequence: 0,
|
|
6488
|
+
eventCount: 0,
|
|
6489
|
+
artifactCount: 0
|
|
6490
|
+
};
|
|
6491
|
+
await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
|
|
6492
|
+
return;
|
|
6493
|
+
}
|
|
6494
|
+
const patched = {
|
|
6495
|
+
...existing,
|
|
6496
|
+
profile: config.profile,
|
|
6497
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
6498
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
6499
|
+
updatedAt: Math.max(existing.updatedAt, timestamp)
|
|
6500
|
+
};
|
|
6501
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
|
|
6502
|
+
});
|
|
6503
|
+
}
|
|
6450
6504
|
async reconcileSessionManifest(sessionId) {
|
|
6451
6505
|
const session = await this.getSession(sessionId);
|
|
6452
6506
|
if (session === void 0) {
|
|
@@ -6843,14 +6897,14 @@ var DEFAULT_SETTLE_DELAYS = {
|
|
|
6843
6897
|
snapshot: 0
|
|
6844
6898
|
};
|
|
6845
6899
|
var DOM_ACTION_VISUAL_STABILITY_PROFILES = {
|
|
6846
|
-
"dom.click": { settleMs: 750, scope: "
|
|
6847
|
-
"dom.input": { settleMs: 750, scope: "
|
|
6848
|
-
"dom.scroll": { settleMs: 600, scope: "
|
|
6900
|
+
"dom.click": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
6901
|
+
"dom.input": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
|
|
6902
|
+
"dom.scroll": { settleMs: 600, scope: "main-frame", timeoutMs: 7e3 },
|
|
6849
6903
|
"dom.hover": { settleMs: 200, scope: "main-frame", timeoutMs: 2500 }
|
|
6850
6904
|
};
|
|
6851
6905
|
var DEFAULT_DOM_ACTION_VISUAL_STABILITY_PROFILE = {
|
|
6852
6906
|
settleMs: 750,
|
|
6853
|
-
scope: "
|
|
6907
|
+
scope: "main-frame",
|
|
6854
6908
|
timeoutMs: 7e3
|
|
6855
6909
|
};
|
|
6856
6910
|
var NAVIGATION_VISUAL_STABILITY_PROFILE = {
|
|
@@ -6874,6 +6928,7 @@ var defaultDomActionSettleObserver = {
|
|
|
6874
6928
|
pageRef: input.pageRef,
|
|
6875
6929
|
timeoutMs: effectiveTimeout,
|
|
6876
6930
|
settleMs: profile.settleMs,
|
|
6931
|
+
...input.observedMutationQuietMs === void 0 ? {} : { initialQuietMs: input.observedMutationQuietMs },
|
|
6877
6932
|
scope: profile.scope
|
|
6878
6933
|
});
|
|
6879
6934
|
return true;
|
|
@@ -6894,15 +6949,20 @@ var defaultNavigationSettleObserver = {
|
|
|
6894
6949
|
return false;
|
|
6895
6950
|
}
|
|
6896
6951
|
try {
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6952
|
+
let visualTimeout = effectiveTimeout;
|
|
6953
|
+
let initialQuietMs = input.observedMutationQuietMs ?? 0;
|
|
6954
|
+
if (!input.postLoadHandled) {
|
|
6955
|
+
const startedAt = Date.now();
|
|
6956
|
+
await input.engine.waitForPostLoadQuiet({
|
|
6957
|
+
pageRef: input.pageRef,
|
|
6958
|
+
timeoutMs: effectiveTimeout,
|
|
6959
|
+
quietMs: DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS,
|
|
6960
|
+
captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
|
|
6961
|
+
signal: input.signal
|
|
6962
|
+
});
|
|
6963
|
+
visualTimeout = Math.max(0, effectiveTimeout - (Date.now() - startedAt));
|
|
6964
|
+
initialQuietMs = Math.max(initialQuietMs, DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS);
|
|
6965
|
+
}
|
|
6906
6966
|
if (visualTimeout <= 0) {
|
|
6907
6967
|
return true;
|
|
6908
6968
|
}
|
|
@@ -6910,6 +6970,7 @@ var defaultNavigationSettleObserver = {
|
|
|
6910
6970
|
pageRef: input.pageRef,
|
|
6911
6971
|
timeoutMs: visualTimeout,
|
|
6912
6972
|
settleMs: profile.settleMs,
|
|
6973
|
+
...initialQuietMs <= 0 ? {} : { initialQuietMs },
|
|
6913
6974
|
scope: profile.scope
|
|
6914
6975
|
});
|
|
6915
6976
|
return true;
|
|
@@ -7499,7 +7560,9 @@ function resolveExtractedValueInContext(normalizedValue, options) {
|
|
|
7499
7560
|
function stripPositionClauses(nodes) {
|
|
7500
7561
|
return (nodes || []).map((node) => ({
|
|
7501
7562
|
...node,
|
|
7502
|
-
match: (node.match || []).filter(
|
|
7563
|
+
match: (node.match || []).filter(
|
|
7564
|
+
(clause) => clause.kind !== "position" && clause.kind !== "text"
|
|
7565
|
+
)
|
|
7503
7566
|
}));
|
|
7504
7567
|
}
|
|
7505
7568
|
function dedupeSelectors(selectors) {
|
|
@@ -8993,7 +9056,7 @@ var DomActionExecutor = class {
|
|
|
8993
9056
|
...snapshot === void 0 ? {} : { snapshot },
|
|
8994
9057
|
signal: timeout.signal,
|
|
8995
9058
|
remainingMs: () => timeout.remainingMs(),
|
|
8996
|
-
policySettle: async (targetPageRef, trigger) => {
|
|
9059
|
+
policySettle: async (targetPageRef, trigger, boundary2) => {
|
|
8997
9060
|
try {
|
|
8998
9061
|
await settleWithPolicy(this.options.policy.settle, {
|
|
8999
9062
|
operation,
|
|
@@ -9001,7 +9064,9 @@ var DomActionExecutor = class {
|
|
|
9001
9064
|
engine: this.options.engine,
|
|
9002
9065
|
pageRef: targetPageRef,
|
|
9003
9066
|
signal: timeout.signal,
|
|
9004
|
-
remainingMs: timeout.remainingMs()
|
|
9067
|
+
remainingMs: timeout.remainingMs(),
|
|
9068
|
+
...boundary2?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary2.observedMutationQuietMs },
|
|
9069
|
+
...boundary2?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
9005
9070
|
});
|
|
9006
9071
|
} catch (error) {
|
|
9007
9072
|
if (snapshot !== void 0 && isSoftSettleTimeoutError(error, timeout.signal)) {
|
|
@@ -9769,7 +9834,9 @@ var DefaultDomRuntime = class {
|
|
|
9769
9834
|
`Unable to resolve structural anchor "${buildPathSelectorHint(anchor)}" in the current session`
|
|
9770
9835
|
);
|
|
9771
9836
|
}
|
|
9772
|
-
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, {
|
|
9837
|
+
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, {
|
|
9838
|
+
enableTextMatch: true
|
|
9839
|
+
});
|
|
9773
9840
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
9774
9841
|
...persist === void 0 ? {} : { persist },
|
|
9775
9842
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -10389,29 +10456,29 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
10389
10456
|
const keyStats = /* @__PURE__ */ new Map();
|
|
10390
10457
|
for (const descriptor of descriptors) {
|
|
10391
10458
|
for (const field of descriptor.fields) {
|
|
10392
|
-
const
|
|
10459
|
+
const stat3 = keyStats.get(field.path) ?? {
|
|
10393
10460
|
indices: /* @__PURE__ */ new Set(),
|
|
10394
10461
|
pathNodes: [],
|
|
10395
10462
|
attributes: [],
|
|
10396
10463
|
sources: []
|
|
10397
10464
|
};
|
|
10398
|
-
|
|
10465
|
+
stat3.indices.add(descriptor.index);
|
|
10399
10466
|
if (isPersistedOpensteerExtractionValueNode(field.node)) {
|
|
10400
|
-
|
|
10401
|
-
|
|
10467
|
+
stat3.pathNodes.push(field.node.$path);
|
|
10468
|
+
stat3.attributes.push(field.node.attribute);
|
|
10402
10469
|
} else if (isPersistedOpensteerExtractionSourceNode(field.node)) {
|
|
10403
|
-
|
|
10470
|
+
stat3.sources.push("current_url");
|
|
10404
10471
|
}
|
|
10405
|
-
keyStats.set(field.path,
|
|
10472
|
+
keyStats.set(field.path, stat3);
|
|
10406
10473
|
}
|
|
10407
10474
|
}
|
|
10408
10475
|
const mergedFields = [];
|
|
10409
|
-
for (const [fieldPath,
|
|
10410
|
-
if (
|
|
10476
|
+
for (const [fieldPath, stat3] of keyStats) {
|
|
10477
|
+
if (stat3.indices.size < threshold) {
|
|
10411
10478
|
continue;
|
|
10412
10479
|
}
|
|
10413
|
-
if (
|
|
10414
|
-
let mergedFieldPath =
|
|
10480
|
+
if (stat3.pathNodes.length >= threshold) {
|
|
10481
|
+
let mergedFieldPath = stat3.pathNodes.length === 1 ? sanitizeElementPath(stat3.pathNodes[0]) : mergeElementPathsByMajority(stat3.pathNodes);
|
|
10415
10482
|
if (!mergedFieldPath) {
|
|
10416
10483
|
continue;
|
|
10417
10484
|
}
|
|
@@ -10419,8 +10486,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
10419
10486
|
mergedFieldPath = relaxPathForSingleSample(mergedFieldPath, "field");
|
|
10420
10487
|
}
|
|
10421
10488
|
mergedFieldPath = minimizePathMatchClauses(mergedFieldPath, "field");
|
|
10422
|
-
const attrThreshold =
|
|
10423
|
-
const attribute = pickModeString(
|
|
10489
|
+
const attrThreshold = stat3.pathNodes.length === 1 ? 1 : majorityThreshold(stat3.pathNodes.length);
|
|
10490
|
+
const attribute = pickModeString(stat3.attributes, attrThreshold);
|
|
10424
10491
|
mergedFields.push({
|
|
10425
10492
|
path: fieldPath,
|
|
10426
10493
|
node: createValueNode({
|
|
@@ -10430,7 +10497,7 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
10430
10497
|
});
|
|
10431
10498
|
continue;
|
|
10432
10499
|
}
|
|
10433
|
-
const dominantSource = pickModeString(
|
|
10500
|
+
const dominantSource = pickModeString(stat3.sources, threshold);
|
|
10434
10501
|
if (dominantSource === "current_url") {
|
|
10435
10502
|
mergedFields.push({
|
|
10436
10503
|
path: fieldPath,
|
|
@@ -12013,9 +12080,9 @@ async function getProcessLiveness(owner) {
|
|
|
12013
12080
|
if (typeof startedAtMs === "number") {
|
|
12014
12081
|
return hasMatchingProcessStartTime(owner.processStartedAtMs, startedAtMs) ? "live" : "dead";
|
|
12015
12082
|
}
|
|
12016
|
-
return
|
|
12083
|
+
return isProcessRunning2(owner.pid) ? "unknown" : "dead";
|
|
12017
12084
|
}
|
|
12018
|
-
function
|
|
12085
|
+
function isProcessRunning2(pid) {
|
|
12019
12086
|
try {
|
|
12020
12087
|
process.kill(pid, 0);
|
|
12021
12088
|
return true;
|
|
@@ -13435,11 +13502,31 @@ async function writePersistedSessionRecord(rootPath, record) {
|
|
|
13435
13502
|
async function clearPersistedSessionRecord(rootPath, provider) {
|
|
13436
13503
|
await promises.rm(resolveLiveSessionRecordPath(rootPath, provider), { force: true });
|
|
13437
13504
|
}
|
|
13505
|
+
function getPersistedLocalBrowserSessionOwnership(record) {
|
|
13506
|
+
return record.ownership === "attached" ? "attached" : "owned";
|
|
13507
|
+
}
|
|
13508
|
+
async function isAttachedLocalBrowserSessionReachable(record) {
|
|
13509
|
+
if (getPersistedLocalBrowserSessionOwnership(record) !== "attached") {
|
|
13510
|
+
return false;
|
|
13511
|
+
}
|
|
13512
|
+
if (record.engine !== "playwright" || record.endpoint === void 0) {
|
|
13513
|
+
return false;
|
|
13514
|
+
}
|
|
13515
|
+
try {
|
|
13516
|
+
await inspectCdpEndpoint({
|
|
13517
|
+
endpoint: record.endpoint,
|
|
13518
|
+
timeoutMs: 1500
|
|
13519
|
+
});
|
|
13520
|
+
return true;
|
|
13521
|
+
} catch {
|
|
13522
|
+
return false;
|
|
13523
|
+
}
|
|
13524
|
+
}
|
|
13438
13525
|
function isPersistedCloudSessionRecord(value) {
|
|
13439
|
-
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);
|
|
13526
|
+
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "cloud" && typeof value.sessionId === "string" && value.sessionId.length > 0 && (value.activePageUrl === void 0 || typeof value.activePageUrl === "string") && (value.activePageTitle === void 0 || typeof value.activePageTitle === "string") && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
|
|
13440
13527
|
}
|
|
13441
13528
|
function isPersistedLocalBrowserSessionRecord(value) {
|
|
13442
|
-
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;
|
|
13529
|
+
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "local" && (value.engine === "playwright" || value.engine === "abp") && (value.ownership === void 0 || value.ownership === "owned" || value.ownership === "attached") && (value.activePageUrl === void 0 || typeof value.activePageUrl === "string") && (value.activePageTitle === void 0 || typeof value.activePageTitle === "string") && typeof value.pid === "number" && Number.isFinite(value.pid) && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) && typeof value.userDataDir === "string" && value.userDataDir.length > 0;
|
|
13443
13530
|
}
|
|
13444
13531
|
function resolveOpensteerStateDir() {
|
|
13445
13532
|
const explicit = process.env.OPENSTEER_HOME?.trim();
|
|
@@ -13828,19 +13915,40 @@ function delay(ms) {
|
|
|
13828
13915
|
var OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT = "opensteer-local-view-session";
|
|
13829
13916
|
var OPENSTEER_LOCAL_VIEW_SESSION_VERSION = 1;
|
|
13830
13917
|
function buildLocalViewSessionId(input) {
|
|
13918
|
+
const ownership = input.ownership ?? "owned";
|
|
13919
|
+
const identity = ownership === "attached" ? input.endpoint ?? input.remoteDebuggingUrl ?? input.baseUrl ?? "attached" : `pid:${String(input.pid ?? 0)}`;
|
|
13831
13920
|
const hash = crypto.createHash("sha256").update(`${input.rootPath}
|
|
13832
|
-
${
|
|
13921
|
+
${ownership}
|
|
13922
|
+
${identity}
|
|
13833
13923
|
${String(input.startedAt)}`).digest("hex");
|
|
13834
13924
|
return `local_${hash.slice(0, 24)}`;
|
|
13835
13925
|
}
|
|
13926
|
+
function buildLocalViewSessionIdForRecord(input) {
|
|
13927
|
+
const ownership = getPersistedLocalBrowserSessionOwnership(input.live);
|
|
13928
|
+
if (ownership === "attached") {
|
|
13929
|
+
return buildLocalViewSessionId({
|
|
13930
|
+
rootPath: input.rootPath,
|
|
13931
|
+
ownership,
|
|
13932
|
+
startedAt: input.live.startedAt,
|
|
13933
|
+
...input.live.endpoint === void 0 ? {} : { endpoint: input.live.endpoint },
|
|
13934
|
+
...input.live.baseUrl === void 0 ? {} : { baseUrl: input.live.baseUrl },
|
|
13935
|
+
...input.live.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: input.live.remoteDebuggingUrl }
|
|
13936
|
+
});
|
|
13937
|
+
}
|
|
13938
|
+
return buildLocalViewSessionId({
|
|
13939
|
+
rootPath: input.rootPath,
|
|
13940
|
+
ownership,
|
|
13941
|
+
startedAt: input.live.startedAt,
|
|
13942
|
+
pid: input.live.pid
|
|
13943
|
+
});
|
|
13944
|
+
}
|
|
13836
13945
|
function createLocalViewSessionManifest(input) {
|
|
13837
13946
|
return {
|
|
13838
13947
|
layout: OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT,
|
|
13839
13948
|
version: OPENSTEER_LOCAL_VIEW_SESSION_VERSION,
|
|
13840
|
-
sessionId:
|
|
13949
|
+
sessionId: buildLocalViewSessionIdForRecord({
|
|
13841
13950
|
rootPath: input.rootPath,
|
|
13842
|
-
|
|
13843
|
-
startedAt: input.live.startedAt
|
|
13951
|
+
live: input.live
|
|
13844
13952
|
}),
|
|
13845
13953
|
rootPath: input.rootPath,
|
|
13846
13954
|
...input.workspace === void 0 ? {} : { workspace: input.workspace },
|
|
@@ -14041,7 +14149,7 @@ var OpensteerBrowserManager = class {
|
|
|
14041
14149
|
}
|
|
14042
14150
|
const liveRecord = await this.readLivePersistentBrowser(await this.ensureWorkspaceStore());
|
|
14043
14151
|
return {
|
|
14044
|
-
mode: this.mode,
|
|
14152
|
+
mode: liveRecord?.ownership === "attached" ? "attach" : this.mode,
|
|
14045
14153
|
engine: liveRecord?.engine ?? this.engineName,
|
|
14046
14154
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14047
14155
|
live: liveRecord !== void 0
|
|
@@ -14169,6 +14277,7 @@ var OpensteerBrowserManager = class {
|
|
|
14169
14277
|
});
|
|
14170
14278
|
const liveRecord = {
|
|
14171
14279
|
mode: "persistent",
|
|
14280
|
+
ownership: "owned",
|
|
14172
14281
|
engine: "abp",
|
|
14173
14282
|
baseUrl: launched.baseUrl,
|
|
14174
14283
|
remoteDebuggingUrl: launched.remoteDebuggingUrl,
|
|
@@ -14255,11 +14364,78 @@ var OpensteerBrowserManager = class {
|
|
|
14255
14364
|
}
|
|
14256
14365
|
async createAttachEngine() {
|
|
14257
14366
|
const endpoint = await resolveAttachEndpoint(this.browserOptions);
|
|
14258
|
-
|
|
14259
|
-
|
|
14260
|
-
|
|
14261
|
-
|
|
14262
|
-
|
|
14367
|
+
if (this.workspace === void 0) {
|
|
14368
|
+
return this.createAttachedEngine({
|
|
14369
|
+
endpoint,
|
|
14370
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
14371
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
14372
|
+
onDispose: async () => void 0
|
|
14373
|
+
});
|
|
14374
|
+
}
|
|
14375
|
+
const workspace = await this.ensureWorkspaceStore();
|
|
14376
|
+
return workspace.lock(async () => {
|
|
14377
|
+
const live = await this.readLivePersistentBrowser(workspace);
|
|
14378
|
+
if (live) {
|
|
14379
|
+
if (live.engine !== "playwright") {
|
|
14380
|
+
throw new Error(
|
|
14381
|
+
`workspace "${this.workspace}" already has a live ${live.engine} browser. Close it before attaching a Playwright browser.`
|
|
14382
|
+
);
|
|
14383
|
+
}
|
|
14384
|
+
if (live.ownership !== "attached") {
|
|
14385
|
+
throw new Error(
|
|
14386
|
+
`workspace "${this.workspace}" already has a live Opensteer-owned browser. Close it before attaching another browser.`
|
|
14387
|
+
);
|
|
14388
|
+
}
|
|
14389
|
+
if (live.endpoint === void 0) {
|
|
14390
|
+
throw new Error("workspace live browser record is missing a DevTools endpoint.");
|
|
14391
|
+
}
|
|
14392
|
+
if (live.endpoint !== endpoint) {
|
|
14393
|
+
throw new Error(
|
|
14394
|
+
`workspace "${this.workspace}" is already attached to a different browser endpoint. Close it before reattaching.`
|
|
14395
|
+
);
|
|
14396
|
+
}
|
|
14397
|
+
await bestEffortRegisterLocalViewSession({
|
|
14398
|
+
rootPath: workspace.rootPath,
|
|
14399
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14400
|
+
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
14401
|
+
ownership: "attached"
|
|
14402
|
+
});
|
|
14403
|
+
return this.createAttachedEngine({
|
|
14404
|
+
endpoint: live.endpoint,
|
|
14405
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
14406
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
14407
|
+
onDispose: async () => void 0
|
|
14408
|
+
});
|
|
14409
|
+
}
|
|
14410
|
+
const liveRecord = {
|
|
14411
|
+
mode: "persistent",
|
|
14412
|
+
ownership: "attached",
|
|
14413
|
+
engine: "playwright",
|
|
14414
|
+
endpoint,
|
|
14415
|
+
pid: 0,
|
|
14416
|
+
startedAt: Date.now(),
|
|
14417
|
+
userDataDir: workspace.browserUserDataDir
|
|
14418
|
+
};
|
|
14419
|
+
await this.writeLivePersistentBrowser(workspace, liveRecord);
|
|
14420
|
+
const persistedLiveRecord = toPersistedLocalBrowserSessionRecord(this.workspace, liveRecord);
|
|
14421
|
+
await bestEffortRegisterLocalViewSession({
|
|
14422
|
+
rootPath: workspace.rootPath,
|
|
14423
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14424
|
+
live: persistedLiveRecord,
|
|
14425
|
+
ownership: "attached"
|
|
14426
|
+
});
|
|
14427
|
+
try {
|
|
14428
|
+
return await this.createAttachedEngine({
|
|
14429
|
+
endpoint,
|
|
14430
|
+
...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
|
|
14431
|
+
freshTab: this.browserOptions?.freshTab ?? true,
|
|
14432
|
+
onDispose: async () => void 0
|
|
14433
|
+
});
|
|
14434
|
+
} catch (error) {
|
|
14435
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
|
|
14436
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14437
|
+
throw error;
|
|
14438
|
+
}
|
|
14263
14439
|
});
|
|
14264
14440
|
}
|
|
14265
14441
|
async createPersistentEngine() {
|
|
@@ -14279,7 +14455,7 @@ var OpensteerBrowserManager = class {
|
|
|
14279
14455
|
rootPath: workspace.rootPath,
|
|
14280
14456
|
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
14281
14457
|
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
14282
|
-
ownership:
|
|
14458
|
+
ownership: live.ownership
|
|
14283
14459
|
});
|
|
14284
14460
|
return this.createAttachedEngine({
|
|
14285
14461
|
endpoint: live.endpoint,
|
|
@@ -14295,6 +14471,7 @@ var OpensteerBrowserManager = class {
|
|
|
14295
14471
|
});
|
|
14296
14472
|
const liveRecord = {
|
|
14297
14473
|
mode: "persistent",
|
|
14474
|
+
ownership: "owned",
|
|
14298
14475
|
engine: "playwright",
|
|
14299
14476
|
endpoint: launched.endpoint,
|
|
14300
14477
|
pid: launched.pid,
|
|
@@ -14424,7 +14601,20 @@ var OpensteerBrowserManager = class {
|
|
|
14424
14601
|
if (live === void 0) {
|
|
14425
14602
|
return void 0;
|
|
14426
14603
|
}
|
|
14427
|
-
if (
|
|
14604
|
+
if (live.ownership === "attached") {
|
|
14605
|
+
const attachedRecord = toPersistedLocalBrowserSessionRecord(this.workspace, live);
|
|
14606
|
+
if (!await isAttachedLocalBrowserSessionReachable(attachedRecord)) {
|
|
14607
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, attachedRecord);
|
|
14608
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14609
|
+
return void 0;
|
|
14610
|
+
}
|
|
14611
|
+
return live;
|
|
14612
|
+
}
|
|
14613
|
+
if (!isProcessRunning2(live.pid)) {
|
|
14614
|
+
await this.unregisterLocalViewSessionForRecord(
|
|
14615
|
+
workspace.rootPath,
|
|
14616
|
+
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
14617
|
+
);
|
|
14428
14618
|
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14429
14619
|
return void 0;
|
|
14430
14620
|
}
|
|
@@ -14472,6 +14662,10 @@ var OpensteerBrowserManager = class {
|
|
|
14472
14662
|
workspace.rootPath,
|
|
14473
14663
|
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
14474
14664
|
);
|
|
14665
|
+
if (live.ownership === "attached") {
|
|
14666
|
+
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
14667
|
+
return;
|
|
14668
|
+
}
|
|
14475
14669
|
if (live.engine === "playwright") {
|
|
14476
14670
|
if (live.endpoint !== void 0) {
|
|
14477
14671
|
await requestBrowserClose(live.endpoint).catch(() => void 0);
|
|
@@ -14500,10 +14694,18 @@ var OpensteerBrowserManager = class {
|
|
|
14500
14694
|
}
|
|
14501
14695
|
async unregisterLocalViewSessionForRecord(rootPath, record) {
|
|
14502
14696
|
await bestEffortUnregisterLocalViewSession(
|
|
14503
|
-
buildLocalViewSessionId({
|
|
14697
|
+
getPersistedLocalBrowserSessionOwnership(record) === "attached" ? buildLocalViewSessionId({
|
|
14504
14698
|
rootPath,
|
|
14505
|
-
|
|
14506
|
-
|
|
14699
|
+
startedAt: record.startedAt,
|
|
14700
|
+
ownership: "attached",
|
|
14701
|
+
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
14702
|
+
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
14703
|
+
...record.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: record.remoteDebuggingUrl }
|
|
14704
|
+
}) : buildLocalViewSessionId({
|
|
14705
|
+
rootPath,
|
|
14706
|
+
startedAt: record.startedAt,
|
|
14707
|
+
ownership: "owned",
|
|
14708
|
+
pid: record.pid
|
|
14507
14709
|
})
|
|
14508
14710
|
);
|
|
14509
14711
|
}
|
|
@@ -14538,6 +14740,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
14538
14740
|
version: 1,
|
|
14539
14741
|
provider: "local",
|
|
14540
14742
|
...workspace === void 0 ? {} : { workspace },
|
|
14743
|
+
ownership: live.ownership,
|
|
14541
14744
|
engine: live.engine,
|
|
14542
14745
|
...live.endpoint === void 0 ? {} : { endpoint: live.endpoint },
|
|
14543
14746
|
...live.baseUrl === void 0 ? {} : { baseUrl: live.baseUrl },
|
|
@@ -14553,6 +14756,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
|
|
|
14553
14756
|
function toWorkspaceLiveBrowserRecord(record) {
|
|
14554
14757
|
return {
|
|
14555
14758
|
mode: "persistent",
|
|
14759
|
+
ownership: getPersistedLocalBrowserSessionOwnership(record),
|
|
14556
14760
|
engine: record.engine,
|
|
14557
14761
|
...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
|
|
14558
14762
|
...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
|
|
@@ -14579,7 +14783,12 @@ function isAttachBrowserOptions(browser) {
|
|
|
14579
14783
|
async function resolveAttachEndpoint(browser) {
|
|
14580
14784
|
const endpoint = browser?.endpoint?.trim();
|
|
14581
14785
|
if (endpoint && endpoint.length > 0) {
|
|
14582
|
-
|
|
14786
|
+
const inspected = await inspectCdpEndpoint({
|
|
14787
|
+
endpoint,
|
|
14788
|
+
...browser?.headers === void 0 ? {} : { headers: browser.headers },
|
|
14789
|
+
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
14790
|
+
});
|
|
14791
|
+
return inspected.endpoint;
|
|
14583
14792
|
}
|
|
14584
14793
|
const selection = await selectAttachBrowserCandidate({
|
|
14585
14794
|
timeoutMs: DEFAULT_TIMEOUT_MS
|
|
@@ -14843,12 +15052,12 @@ async function waitForProcessExit(pid, timeoutMs) {
|
|
|
14843
15052
|
}
|
|
14844
15053
|
const deadline = Date.now() + timeoutMs;
|
|
14845
15054
|
while (Date.now() < deadline) {
|
|
14846
|
-
if (!
|
|
15055
|
+
if (!isProcessRunning2(pid)) {
|
|
14847
15056
|
return true;
|
|
14848
15057
|
}
|
|
14849
15058
|
await sleep2(50);
|
|
14850
15059
|
}
|
|
14851
|
-
return !
|
|
15060
|
+
return !isProcessRunning2(pid);
|
|
14852
15061
|
}
|
|
14853
15062
|
function resolveAbpSessionDir(workspace) {
|
|
14854
15063
|
return path10__default.default.join(workspace.livePath, "abp-session");
|
|
@@ -15755,11 +15964,11 @@ function delay2(ms) {
|
|
|
15755
15964
|
function wrapCloudFetchError(error, input) {
|
|
15756
15965
|
if (!(error instanceof Error)) {
|
|
15757
15966
|
return new Error(
|
|
15758
|
-
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check
|
|
15967
|
+
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check the configured Opensteer cloud base URL and network reachability from this environment.`
|
|
15759
15968
|
);
|
|
15760
15969
|
}
|
|
15761
15970
|
const wrapped = new Error(
|
|
15762
|
-
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check
|
|
15971
|
+
`Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check the configured Opensteer cloud base URL and network reachability from this environment.`,
|
|
15763
15972
|
{
|
|
15764
15973
|
cause: error
|
|
15765
15974
|
}
|
|
@@ -15799,6 +16008,7 @@ function asCloudErrorPayload(value) {
|
|
|
15799
16008
|
}
|
|
15800
16009
|
|
|
15801
16010
|
// src/cloud/config.ts
|
|
16011
|
+
var DEFAULT_OPENSTEER_CLOUD_BASE_URL = "https://api.opensteer.com";
|
|
15802
16012
|
function resolveCloudConfig(input = {}) {
|
|
15803
16013
|
const provider = resolveOpensteerProvider({
|
|
15804
16014
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
@@ -15808,26 +16018,30 @@ function resolveCloudConfig(input = {}) {
|
|
|
15808
16018
|
return void 0;
|
|
15809
16019
|
}
|
|
15810
16020
|
const cloudProvider = input.provider?.mode === "cloud" ? input.provider : void 0;
|
|
15811
|
-
const apiKey = cloudProvider?.apiKey ?? input.environment?.OPENSTEER_API_KEY;
|
|
15812
|
-
if (
|
|
16021
|
+
const apiKey = normalizeOptionalCloudConfigValue(cloudProvider?.apiKey) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_API_KEY);
|
|
16022
|
+
if (apiKey === void 0) {
|
|
15813
16023
|
throw new Error("provider=cloud requires OPENSTEER_API_KEY or provider.apiKey.");
|
|
15814
16024
|
}
|
|
15815
|
-
const baseUrl = cloudProvider?.baseUrl ?? input.environment?.OPENSTEER_BASE_URL;
|
|
15816
|
-
|
|
15817
|
-
throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
|
|
15818
|
-
}
|
|
15819
|
-
const appBaseUrl = cloudProvider?.appBaseUrl ?? input.environment?.OPENSTEER_CLOUD_APP_BASE_URL;
|
|
16025
|
+
const baseUrl = normalizeOptionalCloudConfigValue(cloudProvider?.baseUrl) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_BASE_URL) ?? DEFAULT_OPENSTEER_CLOUD_BASE_URL;
|
|
16026
|
+
const appBaseUrl = normalizeOptionalCloudConfigValue(cloudProvider?.appBaseUrl) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_CLOUD_APP_BASE_URL);
|
|
15820
16027
|
return {
|
|
15821
|
-
apiKey
|
|
15822
|
-
baseUrl
|
|
15823
|
-
...appBaseUrl === void 0
|
|
16028
|
+
apiKey,
|
|
16029
|
+
baseUrl,
|
|
16030
|
+
...appBaseUrl === void 0 ? {} : { appBaseUrl },
|
|
15824
16031
|
...cloudProvider?.browserProfile === void 0 ? {} : { browserProfile: cloudProvider.browserProfile }
|
|
15825
16032
|
};
|
|
15826
16033
|
}
|
|
16034
|
+
function normalizeOptionalCloudConfigValue(value) {
|
|
16035
|
+
if (typeof value !== "string") {
|
|
16036
|
+
return void 0;
|
|
16037
|
+
}
|
|
16038
|
+
const normalized = value.trim().replace(/\/+$/, "");
|
|
16039
|
+
return normalized.length === 0 ? void 0 : normalized;
|
|
16040
|
+
}
|
|
15827
16041
|
|
|
15828
16042
|
// ../runtime-core/package.json
|
|
15829
16043
|
var package_default = {
|
|
15830
|
-
version: "0.2.
|
|
16044
|
+
version: "0.2.7"};
|
|
15831
16045
|
|
|
15832
16046
|
// ../runtime-core/src/version.ts
|
|
15833
16047
|
var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
|
|
@@ -16098,12 +16312,16 @@ function toOpensteerResolvedTarget(target) {
|
|
|
16098
16312
|
documentRef: target.documentRef,
|
|
16099
16313
|
documentEpoch: target.documentEpoch,
|
|
16100
16314
|
nodeRef: target.nodeRef,
|
|
16101
|
-
tagName: target.node.nodeName
|
|
16315
|
+
tagName: toOpensteerTagName(target.node.nodeName),
|
|
16102
16316
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
16103
16317
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
16104
16318
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
16105
16319
|
};
|
|
16106
16320
|
}
|
|
16321
|
+
function toOpensteerTagName(nodeName) {
|
|
16322
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
16323
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
16324
|
+
}
|
|
16107
16325
|
|
|
16108
16326
|
// ../runtime-core/src/runtimes/computer-use/runtime.ts
|
|
16109
16327
|
function createComputerUseRuntime(options) {
|
|
@@ -16137,7 +16355,7 @@ var DefaultComputerUseRuntime = class {
|
|
|
16137
16355
|
screenshot,
|
|
16138
16356
|
signal: input.timeout.signal,
|
|
16139
16357
|
remainingMs: () => input.timeout.remainingMs(),
|
|
16140
|
-
policySettle: async (pageRef, trigger) => {
|
|
16358
|
+
policySettle: async (pageRef, trigger, boundary) => {
|
|
16141
16359
|
try {
|
|
16142
16360
|
await settleWithPolicy(this.options.policy.settle, {
|
|
16143
16361
|
operation: "computer.execute",
|
|
@@ -16145,7 +16363,9 @@ var DefaultComputerUseRuntime = class {
|
|
|
16145
16363
|
engine: this.options.engine,
|
|
16146
16364
|
pageRef,
|
|
16147
16365
|
signal: input.timeout.signal,
|
|
16148
|
-
remainingMs: input.timeout.remainingMs()
|
|
16366
|
+
remainingMs: input.timeout.remainingMs(),
|
|
16367
|
+
...boundary?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary.observedMutationQuietMs },
|
|
16368
|
+
...boundary?.postLoadHandled === true ? { postLoadHandled: true } : {}
|
|
16149
16369
|
});
|
|
16150
16370
|
} catch (error) {
|
|
16151
16371
|
if (pageRef === input.pageRef && isSoftSettleTimeoutError(error, input.timeout.signal)) {
|
|
@@ -17323,28 +17543,24 @@ function restoreBoundedAttr(el, attr, value) {
|
|
|
17323
17543
|
}
|
|
17324
17544
|
setBoundedAttr(el, attr, value);
|
|
17325
17545
|
}
|
|
17326
|
-
function
|
|
17546
|
+
function deduplicateImagesInDom($) {
|
|
17327
17547
|
const seen = /* @__PURE__ */ new Set();
|
|
17328
|
-
|
|
17329
|
-
|
|
17330
|
-
|
|
17331
|
-
|
|
17332
|
-
const srcMatch = attrContent.match(/\bsrc\s*=\s*(["']?)(.*?)\1/);
|
|
17333
|
-
const srcsetMatch = attrContent.match(/\bsrcset\s*=\s*(["'])(.*?)\1/);
|
|
17334
|
-
let src = null;
|
|
17335
|
-
if (srcMatch && srcMatch[2]) {
|
|
17336
|
-
src = srcMatch[2].trim();
|
|
17337
|
-
} else if (srcsetMatch && srcsetMatch[2]) {
|
|
17338
|
-
src = srcsetMatch[2].split(",")[0]?.trim().split(" ")[0] ?? null;
|
|
17548
|
+
$("img").each(function deduplicateDomImage() {
|
|
17549
|
+
const el = $(this);
|
|
17550
|
+
if (el.attr("c") !== void 0) {
|
|
17551
|
+
return;
|
|
17339
17552
|
}
|
|
17553
|
+
const srcValue = el.attr("src")?.trim();
|
|
17554
|
+
const srcsetValue = el.attr("srcset");
|
|
17555
|
+
const src = srcValue && srcValue.length > 0 ? srcValue : srcsetValue?.split(",")[0]?.trim().split(/\s+/u)[0];
|
|
17340
17556
|
if (!src) {
|
|
17341
|
-
return
|
|
17557
|
+
return;
|
|
17342
17558
|
}
|
|
17343
17559
|
if (seen.has(src)) {
|
|
17344
|
-
|
|
17560
|
+
el.remove();
|
|
17561
|
+
return;
|
|
17345
17562
|
}
|
|
17346
17563
|
seen.add(src);
|
|
17347
|
-
return full;
|
|
17348
17564
|
});
|
|
17349
17565
|
}
|
|
17350
17566
|
function hasAttribute2(node, attr) {
|
|
@@ -17402,23 +17618,6 @@ function isPreservedImageElement(node) {
|
|
|
17402
17618
|
function getElementsInReverseDocumentOrder($) {
|
|
17403
17619
|
return $.root().find("*").toArray().reverse().filter((node) => node.type === "tag");
|
|
17404
17620
|
}
|
|
17405
|
-
function getNodeDepth(node) {
|
|
17406
|
-
let depth = 0;
|
|
17407
|
-
let current = node.parent;
|
|
17408
|
-
while (current) {
|
|
17409
|
-
depth++;
|
|
17410
|
-
current = current.parent;
|
|
17411
|
-
}
|
|
17412
|
-
return depth;
|
|
17413
|
-
}
|
|
17414
|
-
function getElementsByDepthDescending($) {
|
|
17415
|
-
const elements = $.root().find("*").toArray().filter((node) => node.type === "tag");
|
|
17416
|
-
const depths = /* @__PURE__ */ new Map();
|
|
17417
|
-
for (const el of elements) {
|
|
17418
|
-
depths.set(el, getNodeDepth(el));
|
|
17419
|
-
}
|
|
17420
|
-
return elements.sort((a, b) => (depths.get(b) ?? 0) - (depths.get(a) ?? 0));
|
|
17421
|
-
}
|
|
17422
17621
|
function flattenExtractionTree($) {
|
|
17423
17622
|
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
17424
17623
|
const el = $(node);
|
|
@@ -17436,19 +17635,6 @@ function flattenExtractionTree($) {
|
|
|
17436
17635
|
el.replaceWith(el.contents());
|
|
17437
17636
|
}
|
|
17438
17637
|
}
|
|
17439
|
-
function hasMarkedAncestor(el, attr) {
|
|
17440
|
-
let current = el[0]?.parent;
|
|
17441
|
-
while (current) {
|
|
17442
|
-
if (!isElementLikeNode(current)) {
|
|
17443
|
-
return false;
|
|
17444
|
-
}
|
|
17445
|
-
if (current.attribs?.[attr] !== void 0) {
|
|
17446
|
-
return true;
|
|
17447
|
-
}
|
|
17448
|
-
current = current.parent;
|
|
17449
|
-
}
|
|
17450
|
-
return false;
|
|
17451
|
-
}
|
|
17452
17638
|
function isIndicatorImage(node) {
|
|
17453
17639
|
return (node?.tagName || "").toLowerCase() === "img" && (hasAttribute2(node, "alt") || hasAttribute2(node, "src") || hasAttribute2(node, "srcset"));
|
|
17454
17640
|
}
|
|
@@ -17566,7 +17752,7 @@ function serializeForExtraction($, root) {
|
|
|
17566
17752
|
traverse(root, 0);
|
|
17567
17753
|
return lines.map((l) => l.trim()).filter((l) => l.length > 0).join("");
|
|
17568
17754
|
}
|
|
17569
|
-
function isClickable(
|
|
17755
|
+
function isClickable(el, context) {
|
|
17570
17756
|
if (context.hasPreMarked) {
|
|
17571
17757
|
return el.attr(OPENSTEER_INTERACTIVE_ATTR) !== void 0;
|
|
17572
17758
|
}
|
|
@@ -17600,21 +17786,17 @@ function isClickable($, el, context) {
|
|
|
17600
17786
|
}
|
|
17601
17787
|
return false;
|
|
17602
17788
|
}
|
|
17603
|
-
function
|
|
17789
|
+
function prepareExtractionSnapshotDom(html) {
|
|
17604
17790
|
if (!html.trim()) {
|
|
17605
|
-
return
|
|
17791
|
+
return void 0;
|
|
17606
17792
|
}
|
|
17607
17793
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
17608
17794
|
removeNoise($);
|
|
17609
17795
|
removeComments($);
|
|
17610
17796
|
markInlineSelfHiddenFallback($);
|
|
17611
17797
|
pruneSelfHiddenNodes($);
|
|
17612
|
-
|
|
17613
|
-
|
|
17614
|
-
{ xmlMode: false }
|
|
17615
|
-
);
|
|
17616
|
-
$clean("*").each(function stripAndRestoreExtractionAttrs() {
|
|
17617
|
-
const el = $clean(this);
|
|
17798
|
+
$("*").each(function stripAndRestoreExtractionAttrs() {
|
|
17799
|
+
const el = $(this);
|
|
17618
17800
|
const node = el[0];
|
|
17619
17801
|
if (!node) {
|
|
17620
17802
|
return;
|
|
@@ -17655,16 +17837,20 @@ function cleanForExtraction(html) {
|
|
|
17655
17837
|
restoreBoundedAttr(el, "href", hrefValue);
|
|
17656
17838
|
}
|
|
17657
17839
|
});
|
|
17658
|
-
flattenExtractionTree($
|
|
17659
|
-
|
|
17840
|
+
flattenExtractionTree($);
|
|
17841
|
+
deduplicateImagesInDom($);
|
|
17842
|
+
return $;
|
|
17843
|
+
}
|
|
17844
|
+
function serializePreparedExtractionSnapshot($) {
|
|
17845
|
+
const root = $.root()[0];
|
|
17660
17846
|
if (root === void 0) {
|
|
17661
17847
|
return "";
|
|
17662
17848
|
}
|
|
17663
|
-
return
|
|
17849
|
+
return serializeForExtraction($, root);
|
|
17664
17850
|
}
|
|
17665
|
-
function
|
|
17851
|
+
function prepareActionSnapshotDom(html) {
|
|
17666
17852
|
if (!html.trim()) {
|
|
17667
|
-
return
|
|
17853
|
+
return void 0;
|
|
17668
17854
|
}
|
|
17669
17855
|
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
17670
17856
|
removeNoise($);
|
|
@@ -17673,13 +17859,12 @@ function cleanForAction(html) {
|
|
|
17673
17859
|
pruneSelfHiddenNodes($);
|
|
17674
17860
|
const clickableMark = "data-clickable-marker";
|
|
17675
17861
|
const indicatorMark = "data-keep-indicator";
|
|
17676
|
-
const branchMark = "data-keep-branch";
|
|
17677
17862
|
const context = {
|
|
17678
17863
|
hasPreMarked: $(`[${OPENSTEER_INTERACTIVE_ATTR}]`).length > 0
|
|
17679
17864
|
};
|
|
17680
17865
|
$("*").each(function markClickables() {
|
|
17681
17866
|
const el = $(this);
|
|
17682
|
-
if (isClickable(
|
|
17867
|
+
if (isClickable(el, context)) {
|
|
17683
17868
|
el.attr(clickableMark, "1");
|
|
17684
17869
|
}
|
|
17685
17870
|
});
|
|
@@ -17709,25 +17894,7 @@ function cleanForAction(html) {
|
|
|
17709
17894
|
el.remove();
|
|
17710
17895
|
}
|
|
17711
17896
|
});
|
|
17712
|
-
|
|
17713
|
-
let current = $(this).parent();
|
|
17714
|
-
while (current.length > 0) {
|
|
17715
|
-
const node = current[0];
|
|
17716
|
-
if (!node || node.type !== "tag") {
|
|
17717
|
-
break;
|
|
17718
|
-
}
|
|
17719
|
-
const ancestor = current;
|
|
17720
|
-
const tag = (node.tagName || "").toLowerCase();
|
|
17721
|
-
if (ROOT_TAGS.has(tag) || ancestor.attr(clickableMark) !== void 0) {
|
|
17722
|
-
break;
|
|
17723
|
-
}
|
|
17724
|
-
if (!isBoundaryTag(tag)) {
|
|
17725
|
-
ancestor.attr(branchMark, "1");
|
|
17726
|
-
}
|
|
17727
|
-
current = ancestor.parent();
|
|
17728
|
-
}
|
|
17729
|
-
});
|
|
17730
|
-
for (const node of getElementsByDepthDescending($)) {
|
|
17897
|
+
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
17731
17898
|
const el = $(node);
|
|
17732
17899
|
const tag = (node.tagName || "").toLowerCase();
|
|
17733
17900
|
if (ROOT_TAGS.has(tag) || isBoundaryTag(tag)) {
|
|
@@ -17736,17 +17903,7 @@ function cleanForAction(html) {
|
|
|
17736
17903
|
if (el.attr(clickableMark) !== void 0 || el.attr(indicatorMark) !== void 0) {
|
|
17737
17904
|
continue;
|
|
17738
17905
|
}
|
|
17739
|
-
const insideClickable = hasMarkedAncestor(el, clickableMark);
|
|
17740
|
-
const preserveBranch = el.attr(branchMark) !== void 0;
|
|
17741
17906
|
const hasContent = hasElementChildren(node) || hasDirectText(node);
|
|
17742
|
-
if (insideClickable || preserveBranch) {
|
|
17743
|
-
if (!hasContent) {
|
|
17744
|
-
el.remove();
|
|
17745
|
-
} else {
|
|
17746
|
-
unwrapActionNode($, el);
|
|
17747
|
-
}
|
|
17748
|
-
continue;
|
|
17749
|
-
}
|
|
17750
17907
|
if (!hasContent) {
|
|
17751
17908
|
el.remove();
|
|
17752
17909
|
continue;
|
|
@@ -17847,13 +18004,20 @@ function cleanForAction(html) {
|
|
|
17847
18004
|
}
|
|
17848
18005
|
el.removeAttr(clickableMark);
|
|
17849
18006
|
el.removeAttr(indicatorMark);
|
|
17850
|
-
el.removeAttr(branchMark);
|
|
17851
18007
|
el.removeAttr(OPENSTEER_INTERACTIVE_ATTR);
|
|
17852
18008
|
el.removeAttr(OPENSTEER_HIDDEN_ATTR);
|
|
17853
18009
|
el.removeAttr(OPENSTEER_SCROLLABLE_ATTR);
|
|
17854
18010
|
el.removeAttr(OPENSTEER_SELF_HIDDEN_ATTR);
|
|
17855
18011
|
});
|
|
17856
|
-
|
|
18012
|
+
deduplicateImagesInDom($);
|
|
18013
|
+
return $;
|
|
18014
|
+
}
|
|
18015
|
+
function serializePreparedActionSnapshot($) {
|
|
18016
|
+
const normalized = compactHtml($.html());
|
|
18017
|
+
if (normalized.length === 0) {
|
|
18018
|
+
return "";
|
|
18019
|
+
}
|
|
18020
|
+
return cheerio__namespace.load(normalized, { xmlMode: false }).html();
|
|
17857
18021
|
}
|
|
17858
18022
|
var VOID_TAGS2 = /* @__PURE__ */ new Set([
|
|
17859
18023
|
"area",
|
|
@@ -18076,27 +18240,32 @@ async function markLiveSnapshotSemantics(options) {
|
|
|
18076
18240
|
const frames = await options.engine.listFrames({
|
|
18077
18241
|
pageRef: options.pageRef
|
|
18078
18242
|
});
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
frame.frameRef,
|
|
18083
|
-
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
18084
|
-
SNAPSHOT_SEMANTIC_ARGS
|
|
18085
|
-
);
|
|
18086
|
-
}
|
|
18087
|
-
return async () => {
|
|
18088
|
-
for (const frame of frames) {
|
|
18089
|
-
await evaluateFrameBestEffort(
|
|
18243
|
+
await Promise.all(
|
|
18244
|
+
frames.map(
|
|
18245
|
+
(frame) => evaluateFrameBestEffort(
|
|
18090
18246
|
options.engine,
|
|
18091
18247
|
frame.frameRef,
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
)
|
|
18095
|
-
|
|
18248
|
+
MARK_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
18249
|
+
SNAPSHOT_SEMANTIC_ARGS
|
|
18250
|
+
)
|
|
18251
|
+
)
|
|
18252
|
+
);
|
|
18253
|
+
return async () => {
|
|
18254
|
+
await Promise.all(
|
|
18255
|
+
frames.map(
|
|
18256
|
+
(frame) => evaluateFrameBestEffort(
|
|
18257
|
+
options.engine,
|
|
18258
|
+
frame.frameRef,
|
|
18259
|
+
CLEAR_SNAPSHOT_SEMANTICS_SCRIPT,
|
|
18260
|
+
CLEAR_SNAPSHOT_SEMANTIC_ARGS
|
|
18261
|
+
)
|
|
18262
|
+
)
|
|
18263
|
+
);
|
|
18096
18264
|
};
|
|
18097
18265
|
}
|
|
18098
18266
|
|
|
18099
18267
|
// ../runtime-core/src/sdk/snapshot/compiler.ts
|
|
18268
|
+
var EXTRACTION_SKIPPED_COUNTER_TAGS = /* @__PURE__ */ new Set(["html", "head", "body"]);
|
|
18100
18269
|
var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
|
|
18101
18270
|
"c",
|
|
18102
18271
|
OPENSTEER_BOUNDARY_ATTR,
|
|
@@ -18111,7 +18280,7 @@ var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
|
|
|
18111
18280
|
var MAX_LIVE_COUNTER_SYNC_ATTEMPTS = 4;
|
|
18112
18281
|
var CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
|
|
18113
18282
|
const walk = (root) => {
|
|
18114
|
-
for (const child of root
|
|
18283
|
+
for (const child of Array.from(root?.children || [])) {
|
|
18115
18284
|
child.removeAttribute("c");
|
|
18116
18285
|
child.removeAttribute(sparseCounterAttr);
|
|
18117
18286
|
walk(child);
|
|
@@ -18127,7 +18296,7 @@ var CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
|
|
|
18127
18296
|
var ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
|
|
18128
18297
|
let counter = startCounter;
|
|
18129
18298
|
const walk = (root) => {
|
|
18130
|
-
for (const child of root
|
|
18299
|
+
for (const child of Array.from(root?.children || [])) {
|
|
18131
18300
|
child.setAttribute(sparseCounterAttr, String(counter++));
|
|
18132
18301
|
walk(child);
|
|
18133
18302
|
if (child.shadowRoot) {
|
|
@@ -18141,7 +18310,7 @@ var ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
|
|
|
18141
18310
|
})`;
|
|
18142
18311
|
var APPLY_DENSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, mapping }) => {
|
|
18143
18312
|
const walk = (root) => {
|
|
18144
|
-
for (const child of root
|
|
18313
|
+
for (const child of Array.from(root?.children || [])) {
|
|
18145
18314
|
child.removeAttribute("c");
|
|
18146
18315
|
const sparse = child.getAttribute(sparseCounterAttr);
|
|
18147
18316
|
if (sparse !== null) {
|
|
@@ -18204,20 +18373,22 @@ function ensureSparseCountersForAllRecords(counterRecords) {
|
|
|
18204
18373
|
async function clearOpensteerLiveCounters(engine, pageRef) {
|
|
18205
18374
|
const frames = await engine.listFrames({ pageRef });
|
|
18206
18375
|
const failures = [];
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18376
|
+
await Promise.all(
|
|
18377
|
+
frames.map(async (frame) => {
|
|
18378
|
+
try {
|
|
18379
|
+
await engine.evaluateFrame({
|
|
18380
|
+
frameRef: frame.frameRef,
|
|
18381
|
+
script: CLEAR_LIVE_COUNTERS_SCRIPT,
|
|
18382
|
+
args: [{ sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR }]
|
|
18383
|
+
});
|
|
18384
|
+
} catch (error) {
|
|
18385
|
+
if (isDetachedFrameSyncError(error)) {
|
|
18386
|
+
return;
|
|
18387
|
+
}
|
|
18388
|
+
failures.push(`frame ${frame.frameRef} could not be cleared (${describeError(error)}).`);
|
|
18217
18389
|
}
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
}
|
|
18390
|
+
})
|
|
18391
|
+
);
|
|
18221
18392
|
if (failures.length > 0) {
|
|
18222
18393
|
throw buildLiveCounterSyncError("clear live counters", failures);
|
|
18223
18394
|
}
|
|
@@ -18266,25 +18437,29 @@ async function syncDenseCountersToLiveDom(engine, pageRef, sparseToDirectMapping
|
|
|
18266
18437
|
denseCounter
|
|
18267
18438
|
])
|
|
18268
18439
|
);
|
|
18269
|
-
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
|
|
18275
|
-
|
|
18276
|
-
|
|
18277
|
-
|
|
18278
|
-
|
|
18279
|
-
|
|
18280
|
-
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
18440
|
+
await Promise.all(
|
|
18441
|
+
frames.map(async (frame) => {
|
|
18442
|
+
try {
|
|
18443
|
+
await engine.evaluateFrame({
|
|
18444
|
+
frameRef: frame.frameRef,
|
|
18445
|
+
script: APPLY_DENSE_COUNTERS_SCRIPT,
|
|
18446
|
+
args: [
|
|
18447
|
+
{
|
|
18448
|
+
sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR,
|
|
18449
|
+
mapping: mappingObj
|
|
18450
|
+
}
|
|
18451
|
+
]
|
|
18452
|
+
});
|
|
18453
|
+
} catch (error) {
|
|
18454
|
+
if (isDetachedFrameSyncError(error)) {
|
|
18455
|
+
return;
|
|
18456
|
+
}
|
|
18457
|
+
failures.push(
|
|
18458
|
+
`frame ${frame.frameRef} could not be synchronized (${describeError(error)}).`
|
|
18459
|
+
);
|
|
18284
18460
|
}
|
|
18285
|
-
|
|
18286
|
-
|
|
18287
|
-
}
|
|
18461
|
+
})
|
|
18462
|
+
);
|
|
18288
18463
|
if (failures.length > 0) {
|
|
18289
18464
|
throw buildLiveCounterSyncError("synchronize dense counters", failures);
|
|
18290
18465
|
}
|
|
@@ -18302,26 +18477,26 @@ async function compileOpensteerSnapshot(options) {
|
|
|
18302
18477
|
await clearOpensteerLiveCounters(options.engine, options.pageRef);
|
|
18303
18478
|
await assignSparseCountersToLiveDom(options.engine, options.pageRef);
|
|
18304
18479
|
const pageInfo = await options.engine.getPageInfo({ pageRef: options.pageRef });
|
|
18305
|
-
const mainSnapshot = await
|
|
18306
|
-
|
|
18480
|
+
const { mainSnapshot, snapshotsByDocumentRef } = await getPageDocumentSnapshots(
|
|
18481
|
+
options.engine,
|
|
18482
|
+
options.pageRef
|
|
18483
|
+
);
|
|
18307
18484
|
await cleanupLiveSemantics();
|
|
18308
18485
|
cleanupLiveSemantics = async () => {
|
|
18309
18486
|
};
|
|
18310
|
-
const snapshotIndices = /* @__PURE__ */ new Map();
|
|
18311
18487
|
const renderedNodes = /* @__PURE__ */ new Map();
|
|
18312
18488
|
const rawHtml = renderDocumentSnapshot(
|
|
18313
18489
|
mainSnapshot.documentRef,
|
|
18314
18490
|
snapshotsByDocumentRef,
|
|
18315
|
-
snapshotIndices,
|
|
18316
18491
|
renderedNodes,
|
|
18317
18492
|
{
|
|
18318
18493
|
iframeDepth: 0,
|
|
18319
18494
|
shadowDepth: 0
|
|
18320
18495
|
}
|
|
18321
18496
|
);
|
|
18322
|
-
const
|
|
18323
|
-
const compiledHtml =
|
|
18324
|
-
const finalHtml = options.mode === "extraction" ?
|
|
18497
|
+
const preparedSnapshotDom = options.mode === "extraction" ? prepareExtractionSnapshotDom(rawHtml) : prepareActionSnapshotDom(rawHtml);
|
|
18498
|
+
const compiledHtml = assignCountersInDom(preparedSnapshotDom, renderedNodes, options.mode);
|
|
18499
|
+
const finalHtml = preparedSnapshotDom === void 0 ? "" : options.mode === "extraction" ? serializePreparedExtractionSnapshot(preparedSnapshotDom) : serializePreparedActionSnapshot(preparedSnapshotDom);
|
|
18325
18500
|
ensureSparseCountersForAllRecords(compiledHtml.counterRecords);
|
|
18326
18501
|
await syncDenseCountersToLiveDom(
|
|
18327
18502
|
options.engine,
|
|
@@ -18356,6 +18531,25 @@ async function getMainDocumentSnapshot(engine, pageRef) {
|
|
|
18356
18531
|
}
|
|
18357
18532
|
return engine.getDomSnapshot({ frameRef: mainFrame.frameRef });
|
|
18358
18533
|
}
|
|
18534
|
+
async function getPageDocumentSnapshots(engine, pageRef) {
|
|
18535
|
+
const bundleEngine = engine;
|
|
18536
|
+
const bundledSnapshots = await bundleEngine.getPageDomSnapshots?.({ pageRef });
|
|
18537
|
+
if (bundledSnapshots && bundledSnapshots.length > 0) {
|
|
18538
|
+
const mainSnapshot2 = bundledSnapshots.find((snapshot) => snapshot.parentDocumentRef === void 0) ?? bundledSnapshots[0];
|
|
18539
|
+
return {
|
|
18540
|
+
mainSnapshot: mainSnapshot2,
|
|
18541
|
+
snapshotsByDocumentRef: new Map(
|
|
18542
|
+
bundledSnapshots.map((snapshot) => [snapshot.documentRef, snapshot])
|
|
18543
|
+
)
|
|
18544
|
+
};
|
|
18545
|
+
}
|
|
18546
|
+
const mainSnapshot = await getMainDocumentSnapshot(engine, pageRef);
|
|
18547
|
+
const snapshotsByDocumentRef = await collectDocumentSnapshots(engine, mainSnapshot);
|
|
18548
|
+
return {
|
|
18549
|
+
mainSnapshot,
|
|
18550
|
+
snapshotsByDocumentRef
|
|
18551
|
+
};
|
|
18552
|
+
}
|
|
18359
18553
|
async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
18360
18554
|
const snapshotsByDocumentRef = /* @__PURE__ */ new Map([
|
|
18361
18555
|
[mainSnapshot.documentRef, mainSnapshot]
|
|
@@ -18374,7 +18568,7 @@ async function collectDocumentSnapshots(engine, mainSnapshot) {
|
|
|
18374
18568
|
}
|
|
18375
18569
|
return snapshotsByDocumentRef;
|
|
18376
18570
|
}
|
|
18377
|
-
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef,
|
|
18571
|
+
function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
18378
18572
|
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
18379
18573
|
if (!snapshot) {
|
|
18380
18574
|
return "";
|
|
@@ -18386,17 +18580,9 @@ function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, snapshotInd
|
|
|
18386
18580
|
`snapshot ${snapshot.documentRef} is missing root node ${String(snapshot.rootSnapshotNodeId)}`
|
|
18387
18581
|
);
|
|
18388
18582
|
}
|
|
18389
|
-
return renderNode(
|
|
18390
|
-
snapshot,
|
|
18391
|
-
rootNode,
|
|
18392
|
-
nodesById,
|
|
18393
|
-
snapshotsByDocumentRef,
|
|
18394
|
-
snapshotIndices,
|
|
18395
|
-
renderedNodes,
|
|
18396
|
-
depth
|
|
18397
|
-
);
|
|
18583
|
+
return renderNode(snapshot, rootNode, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18398
18584
|
}
|
|
18399
|
-
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
18585
|
+
function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
18400
18586
|
if (node.nodeType === 3) {
|
|
18401
18587
|
return escapeHtml(node.nodeValue || node.textContent || "");
|
|
18402
18588
|
}
|
|
@@ -18404,56 +18590,26 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18404
18590
|
return "";
|
|
18405
18591
|
}
|
|
18406
18592
|
if (node.nodeType === 9 || node.nodeType === 11) {
|
|
18407
|
-
return renderChildren(
|
|
18408
|
-
snapshot,
|
|
18409
|
-
node,
|
|
18410
|
-
nodesById,
|
|
18411
|
-
snapshotsByDocumentRef,
|
|
18412
|
-
snapshotIndices,
|
|
18413
|
-
renderedNodes,
|
|
18414
|
-
depth
|
|
18415
|
-
);
|
|
18593
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18416
18594
|
}
|
|
18417
18595
|
if (node.nodeType !== 1) {
|
|
18418
|
-
return renderChildren(
|
|
18419
|
-
snapshot,
|
|
18420
|
-
node,
|
|
18421
|
-
nodesById,
|
|
18422
|
-
snapshotsByDocumentRef,
|
|
18423
|
-
snapshotIndices,
|
|
18424
|
-
renderedNodes,
|
|
18425
|
-
depth
|
|
18426
|
-
);
|
|
18596
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18427
18597
|
}
|
|
18428
18598
|
const tagName = normalizeTagName(node.nodeName);
|
|
18429
18599
|
if (isPseudoElementTagName(tagName)) {
|
|
18430
|
-
return renderChildren(
|
|
18431
|
-
snapshot,
|
|
18432
|
-
node,
|
|
18433
|
-
nodesById,
|
|
18434
|
-
snapshotsByDocumentRef,
|
|
18435
|
-
snapshotIndices,
|
|
18436
|
-
renderedNodes,
|
|
18437
|
-
depth
|
|
18438
|
-
);
|
|
18600
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18439
18601
|
}
|
|
18440
18602
|
if ((depth.iframeDepth > 0 || depth.shadowDepth > 0) && (tagName === "html" || tagName === "head" || tagName === "body")) {
|
|
18441
|
-
return renderChildren(
|
|
18442
|
-
snapshot,
|
|
18443
|
-
node,
|
|
18444
|
-
nodesById,
|
|
18445
|
-
snapshotsByDocumentRef,
|
|
18446
|
-
snapshotIndices,
|
|
18447
|
-
renderedNodes,
|
|
18448
|
-
depth
|
|
18449
|
-
);
|
|
18603
|
+
return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
|
|
18450
18604
|
}
|
|
18451
18605
|
const snapshotAttributes = normalizeNodeAttributes(node.attributes);
|
|
18606
|
+
const snapshotAttributeIndex = indexNodeAttributes(snapshotAttributes);
|
|
18452
18607
|
const authoredAttributes = stripInternalSnapshotAttributes(snapshotAttributes);
|
|
18608
|
+
const authoredAttributeIndex = indexNodeAttributes(authoredAttributes);
|
|
18453
18609
|
const attributes = [...authoredAttributes];
|
|
18454
|
-
const subtreeHidden =
|
|
18455
|
-
const selfHidden = !subtreeHidden && (
|
|
18456
|
-
const interactive = !subtreeHidden && !selfHidden && (
|
|
18610
|
+
const subtreeHidden = snapshotAttributeIndex.has(OPENSTEER_HIDDEN_ATTR) || isLikelySubtreeHidden(node);
|
|
18611
|
+
const selfHidden = !subtreeHidden && (snapshotAttributeIndex.has(OPENSTEER_SELF_HIDDEN_ATTR) || isLikelySelfHidden(node, nodesById));
|
|
18612
|
+
const interactive = !subtreeHidden && !selfHidden && (snapshotAttributeIndex.has(OPENSTEER_INTERACTIVE_ATTR) || isLikelyInteractive(tagName, node, authoredAttributes, authoredAttributeIndex));
|
|
18457
18613
|
if (interactive) {
|
|
18458
18614
|
attributes.push({ name: OPENSTEER_INTERACTIVE_ATTR, value: "1" });
|
|
18459
18615
|
}
|
|
@@ -18462,7 +18618,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18462
18618
|
} else if (selfHidden) {
|
|
18463
18619
|
attributes.push({ name: OPENSTEER_SELF_HIDDEN_ATTR, value: "1" });
|
|
18464
18620
|
}
|
|
18465
|
-
const sparseCounter =
|
|
18621
|
+
const sparseCounter = snapshotAttributeIndex.get(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18466
18622
|
if (sparseCounter !== void 0) {
|
|
18467
18623
|
attributes.push({ name: OPENSTEER_SPARSE_COUNTER_ATTR, value: sparseCounter });
|
|
18468
18624
|
}
|
|
@@ -18473,21 +18629,18 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18473
18629
|
const syntheticNodeId = buildSyntheticNodeId(snapshot, node);
|
|
18474
18630
|
attributes.push({ name: OPENSTEER_NODE_ID_ATTR, value: syntheticNodeId });
|
|
18475
18631
|
renderedNodes.set(syntheticNodeId, {
|
|
18476
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
18477
|
-
anchor: buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices),
|
|
18478
18632
|
pageRef: snapshot.pageRef,
|
|
18479
18633
|
frameRef: snapshot.frameRef,
|
|
18480
18634
|
documentRef: snapshot.documentRef,
|
|
18481
18635
|
documentEpoch: snapshot.documentEpoch,
|
|
18482
18636
|
nodeRef: node.nodeRef,
|
|
18483
18637
|
tagName: tagName.toUpperCase(),
|
|
18484
|
-
pathHint: buildPathHint(tagName, authoredAttributes),
|
|
18485
|
-
...buildTextSnippet(node.textContent) === void 0 ? {} : { text: buildTextSnippet(node.textContent) },
|
|
18486
18638
|
...authoredAttributes.length === 0 ? {} : { attributes: authoredAttributes },
|
|
18487
18639
|
iframeDepth: depth.iframeDepth,
|
|
18488
18640
|
shadowDepth: depth.shadowDepth,
|
|
18489
18641
|
interactive,
|
|
18490
|
-
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById)
|
|
18642
|
+
liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById),
|
|
18643
|
+
...node.textContent === void 0 ? {} : { textContent: node.textContent }
|
|
18491
18644
|
});
|
|
18492
18645
|
}
|
|
18493
18646
|
const attributeText = attributesToHtml(attributes);
|
|
@@ -18496,7 +18649,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18496
18649
|
node,
|
|
18497
18650
|
nodesById,
|
|
18498
18651
|
snapshotsByDocumentRef,
|
|
18499
|
-
snapshotIndices,
|
|
18500
18652
|
renderedNodes,
|
|
18501
18653
|
depth
|
|
18502
18654
|
);
|
|
@@ -18507,7 +18659,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18507
18659
|
const iframeHtml = renderDocumentSnapshot(
|
|
18508
18660
|
node.contentDocumentRef,
|
|
18509
18661
|
snapshotsByDocumentRef,
|
|
18510
|
-
snapshotIndices,
|
|
18511
18662
|
renderedNodes,
|
|
18512
18663
|
{
|
|
18513
18664
|
iframeDepth: depth.iframeDepth + 1,
|
|
@@ -18519,7 +18670,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
18519
18670
|
}
|
|
18520
18671
|
return `${elementHtml}<${OPENSTEER_IFRAME_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="iframe">${iframeHtml}</${OPENSTEER_IFRAME_BOUNDARY_TAG}>`;
|
|
18521
18672
|
}
|
|
18522
|
-
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef,
|
|
18673
|
+
function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
|
|
18523
18674
|
const regularChildren = [];
|
|
18524
18675
|
const shadowChildren = [];
|
|
18525
18676
|
for (const childSnapshotNodeId of node.childSnapshotNodeIds) {
|
|
@@ -18536,18 +18687,10 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
18536
18687
|
const chunks = [];
|
|
18537
18688
|
if (shadowChildren.length > 0) {
|
|
18538
18689
|
const shadowHtml = shadowChildren.map(
|
|
18539
|
-
(child) => renderNode(
|
|
18540
|
-
|
|
18541
|
-
|
|
18542
|
-
|
|
18543
|
-
snapshotsByDocumentRef,
|
|
18544
|
-
snapshotIndices,
|
|
18545
|
-
renderedNodes,
|
|
18546
|
-
{
|
|
18547
|
-
iframeDepth: depth.iframeDepth,
|
|
18548
|
-
shadowDepth: depth.shadowDepth + 1
|
|
18549
|
-
}
|
|
18550
|
-
)
|
|
18690
|
+
(child) => renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, {
|
|
18691
|
+
iframeDepth: depth.iframeDepth,
|
|
18692
|
+
shadowDepth: depth.shadowDepth + 1
|
|
18693
|
+
})
|
|
18551
18694
|
).join("");
|
|
18552
18695
|
chunks.push(
|
|
18553
18696
|
`<${OPENSTEER_SHADOW_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="shadow">${shadowHtml}</${OPENSTEER_SHADOW_BOUNDARY_TAG}>`
|
|
@@ -18555,24 +18698,21 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
|
|
|
18555
18698
|
}
|
|
18556
18699
|
for (const child of regularChildren) {
|
|
18557
18700
|
chunks.push(
|
|
18558
|
-
renderNode(
|
|
18559
|
-
snapshot,
|
|
18560
|
-
child,
|
|
18561
|
-
nodesById,
|
|
18562
|
-
snapshotsByDocumentRef,
|
|
18563
|
-
snapshotIndices,
|
|
18564
|
-
renderedNodes,
|
|
18565
|
-
depth
|
|
18566
|
-
)
|
|
18701
|
+
renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, depth)
|
|
18567
18702
|
);
|
|
18568
18703
|
}
|
|
18569
18704
|
return chunks.join("");
|
|
18570
18705
|
}
|
|
18571
|
-
function
|
|
18572
|
-
const $ = cheerio__namespace.load(cleanedHtml, { xmlMode: false });
|
|
18706
|
+
function assignCountersInDom($, renderedNodes, mode) {
|
|
18573
18707
|
const counterRecords = /* @__PURE__ */ new Map();
|
|
18574
18708
|
const sparseToDirectMapping = /* @__PURE__ */ new Map();
|
|
18575
18709
|
let nextCounter = 1;
|
|
18710
|
+
if (!$) {
|
|
18711
|
+
return {
|
|
18712
|
+
counterRecords,
|
|
18713
|
+
sparseToDirectMapping
|
|
18714
|
+
};
|
|
18715
|
+
}
|
|
18576
18716
|
$("*").each(function assignElementCounter() {
|
|
18577
18717
|
const el = $(this);
|
|
18578
18718
|
const syntheticNodeId = el.attr(OPENSTEER_NODE_ID_ATTR);
|
|
@@ -18584,14 +18724,24 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
18584
18724
|
if (!rendered) {
|
|
18585
18725
|
return;
|
|
18586
18726
|
}
|
|
18727
|
+
if (mode === "extraction" && EXTRACTION_SKIPPED_COUNTER_TAGS.has(rendered.tagName.toLowerCase())) {
|
|
18728
|
+
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18729
|
+
return;
|
|
18730
|
+
}
|
|
18587
18731
|
const rawSparseCounter = el.attr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18588
18732
|
el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
|
|
18589
18733
|
const sparseCounter = rawSparseCounter ? Number.parseInt(rawSparseCounter, 10) : void 0;
|
|
18734
|
+
const replayableSparseCounter = typeof sparseCounter === "number" && Number.isFinite(sparseCounter) ? sparseCounter : void 0;
|
|
18735
|
+
if (rendered.liveCounterSyncEligible && replayableSparseCounter === void 0) {
|
|
18736
|
+
return;
|
|
18737
|
+
}
|
|
18590
18738
|
const counter = nextCounter++;
|
|
18591
18739
|
el.attr("c", String(counter));
|
|
18592
|
-
if (
|
|
18593
|
-
sparseToDirectMapping.set(
|
|
18740
|
+
if (replayableSparseCounter !== void 0) {
|
|
18741
|
+
sparseToDirectMapping.set(replayableSparseCounter, counter);
|
|
18594
18742
|
}
|
|
18743
|
+
const pathHint = buildPathHint(rendered.tagName.toLowerCase(), rendered.attributes ?? []);
|
|
18744
|
+
const text = buildTextSnippet(rendered.textContent);
|
|
18595
18745
|
counterRecords.set(counter, {
|
|
18596
18746
|
element: counter,
|
|
18597
18747
|
pageRef: rendered.pageRef,
|
|
@@ -18600,20 +18750,17 @@ function assignCounters(cleanedHtml, renderedNodes) {
|
|
|
18600
18750
|
documentEpoch: rendered.documentEpoch,
|
|
18601
18751
|
nodeRef: rendered.nodeRef,
|
|
18602
18752
|
tagName: rendered.tagName,
|
|
18603
|
-
pathHint
|
|
18604
|
-
...
|
|
18753
|
+
pathHint,
|
|
18754
|
+
...text === void 0 ? {} : { text },
|
|
18605
18755
|
...rendered.attributes === void 0 ? {} : { attributes: rendered.attributes },
|
|
18606
18756
|
iframeDepth: rendered.iframeDepth,
|
|
18607
18757
|
shadowDepth: rendered.shadowDepth,
|
|
18608
18758
|
interactive: rendered.interactive,
|
|
18609
18759
|
liveCounterSyncEligible: rendered.liveCounterSyncEligible,
|
|
18610
|
-
|
|
18611
|
-
anchor: rendered.anchor,
|
|
18612
|
-
...sparseCounter !== void 0 && Number.isFinite(sparseCounter) ? { sparseCounter } : {}
|
|
18760
|
+
...replayableSparseCounter === void 0 ? {} : { sparseCounter: replayableSparseCounter }
|
|
18613
18761
|
});
|
|
18614
18762
|
});
|
|
18615
18763
|
return {
|
|
18616
|
-
html: $.html(),
|
|
18617
18764
|
counterRecords,
|
|
18618
18765
|
sparseToDirectMapping
|
|
18619
18766
|
};
|
|
@@ -18687,28 +18834,28 @@ function isLikelySelfHidden(node, nodesById) {
|
|
|
18687
18834
|
}
|
|
18688
18835
|
return !hasVisibleOutOfFlowChild(node, nodesById);
|
|
18689
18836
|
}
|
|
18690
|
-
function isLikelyInteractive(tagName, node, attributes) {
|
|
18837
|
+
function isLikelyInteractive(tagName, node, attributes, attributeIndex) {
|
|
18691
18838
|
if (NATIVE_INTERACTIVE_TAGS.has(tagName)) {
|
|
18692
|
-
if (tagName === "input" &&
|
|
18839
|
+
if (tagName === "input" && attributeIndex.get("type")?.toLowerCase() === "hidden") {
|
|
18693
18840
|
return false;
|
|
18694
18841
|
}
|
|
18695
18842
|
if (tagName !== "a") {
|
|
18696
18843
|
return true;
|
|
18697
18844
|
}
|
|
18698
18845
|
}
|
|
18699
|
-
if (tagName === "a" &&
|
|
18846
|
+
if (tagName === "a" && attributeIndex.has("href")) {
|
|
18700
18847
|
return true;
|
|
18701
18848
|
}
|
|
18702
|
-
if (
|
|
18849
|
+
if (attributeIndex.has("onclick") || attributeIndex.has("onmousedown") || attributeIndex.has("onmouseup") || attributeIndex.has("data-action") || attributeIndex.has("data-click") || attributeIndex.has("data-toggle")) {
|
|
18703
18850
|
return true;
|
|
18704
18851
|
}
|
|
18705
|
-
if (hasNonNegativeTabIndex(
|
|
18852
|
+
if (hasNonNegativeTabIndex(attributeIndex.get("tabindex"))) {
|
|
18706
18853
|
return true;
|
|
18707
18854
|
}
|
|
18708
|
-
if (
|
|
18855
|
+
if (attributeIndex.get("contenteditable")?.toLowerCase() === "true") {
|
|
18709
18856
|
return true;
|
|
18710
18857
|
}
|
|
18711
|
-
const role =
|
|
18858
|
+
const role = attributeIndex.get("role")?.toLowerCase();
|
|
18712
18859
|
return role !== void 0 && INTERACTIVE_ROLE_SET.has(role);
|
|
18713
18860
|
}
|
|
18714
18861
|
function hasVisibleOutOfFlowChild(node, nodesById) {
|
|
@@ -18771,14 +18918,6 @@ function parseOpacity(value) {
|
|
|
18771
18918
|
const parsed = Number.parseFloat(value);
|
|
18772
18919
|
return Number.isFinite(parsed) ? parsed : Number.NaN;
|
|
18773
18920
|
}
|
|
18774
|
-
function hasAttribute3(attributes, name) {
|
|
18775
|
-
const normalizedName = name.toLowerCase();
|
|
18776
|
-
return attributes.some((attribute) => attribute.name.toLowerCase() === normalizedName);
|
|
18777
|
-
}
|
|
18778
|
-
function unwrapExtractionHtml(html) {
|
|
18779
|
-
const $ = cheerio__namespace.load(html, { xmlMode: false });
|
|
18780
|
-
return $("body").html()?.trim() || html;
|
|
18781
|
-
}
|
|
18782
18921
|
function buildSyntheticNodeId(snapshot, node) {
|
|
18783
18922
|
return `${snapshot.documentRef}:${String(snapshot.documentEpoch)}:${String(node.snapshotNodeId)}`;
|
|
18784
18923
|
}
|
|
@@ -18825,6 +18964,13 @@ function findAttributeValue(attributes, name) {
|
|
|
18825
18964
|
const normalizedName = name.toLowerCase();
|
|
18826
18965
|
return attributes.find((attribute) => attribute.name.toLowerCase() === normalizedName)?.value;
|
|
18827
18966
|
}
|
|
18967
|
+
function indexNodeAttributes(attributes) {
|
|
18968
|
+
const indexed = /* @__PURE__ */ new Map();
|
|
18969
|
+
for (const attribute of attributes) {
|
|
18970
|
+
indexed.set(attribute.name.toLowerCase(), attribute.value);
|
|
18971
|
+
}
|
|
18972
|
+
return indexed;
|
|
18973
|
+
}
|
|
18828
18974
|
function attributesToHtml(attributes) {
|
|
18829
18975
|
if (attributes.length === 0) {
|
|
18830
18976
|
return "";
|
|
@@ -18834,56 +18980,6 @@ function attributesToHtml(attributes) {
|
|
|
18834
18980
|
function escapeAttribute(value) {
|
|
18835
18981
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
18836
18982
|
}
|
|
18837
|
-
function buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices) {
|
|
18838
|
-
const index = getSnapshotIndex(snapshot.documentRef, snapshotsByDocumentRef, snapshotIndices);
|
|
18839
|
-
const localAnchor = buildLocalStructuralElementAnchor(index, node);
|
|
18840
|
-
return prefixIframeContext(snapshot, localAnchor, snapshotsByDocumentRef, snapshotIndices);
|
|
18841
|
-
}
|
|
18842
|
-
function prefixIframeContext(snapshot, localPath, snapshotsByDocumentRef, snapshotIndices) {
|
|
18843
|
-
if (snapshot.parentDocumentRef === void 0) {
|
|
18844
|
-
return sanitizeStructuralElementAnchor(localPath);
|
|
18845
|
-
}
|
|
18846
|
-
const parentSnapshot = snapshotsByDocumentRef.get(snapshot.parentDocumentRef);
|
|
18847
|
-
if (!parentSnapshot) {
|
|
18848
|
-
throw new Error(
|
|
18849
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no parent snapshot`
|
|
18850
|
-
);
|
|
18851
|
-
}
|
|
18852
|
-
const parentIndex = getSnapshotIndex(
|
|
18853
|
-
parentSnapshot.documentRef,
|
|
18854
|
-
snapshotsByDocumentRef,
|
|
18855
|
-
snapshotIndices
|
|
18856
|
-
);
|
|
18857
|
-
const iframeHost = findIframeHostNode(parentIndex, snapshot.documentRef);
|
|
18858
|
-
if (!iframeHost) {
|
|
18859
|
-
throw new Error(
|
|
18860
|
-
`document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no iframe host`
|
|
18861
|
-
);
|
|
18862
|
-
}
|
|
18863
|
-
const hostPath = buildSnapshotElementAnchor(
|
|
18864
|
-
parentSnapshot,
|
|
18865
|
-
iframeHost,
|
|
18866
|
-
snapshotsByDocumentRef,
|
|
18867
|
-
snapshotIndices
|
|
18868
|
-
);
|
|
18869
|
-
return sanitizeStructuralElementAnchor({
|
|
18870
|
-
context: [...hostPath.context, { kind: "iframe", host: hostPath.nodes }, ...localPath.context],
|
|
18871
|
-
nodes: localPath.nodes
|
|
18872
|
-
});
|
|
18873
|
-
}
|
|
18874
|
-
function getSnapshotIndex(documentRef, snapshotsByDocumentRef, snapshotIndices) {
|
|
18875
|
-
const existing = snapshotIndices.get(documentRef);
|
|
18876
|
-
if (existing) {
|
|
18877
|
-
return existing;
|
|
18878
|
-
}
|
|
18879
|
-
const snapshot = snapshotsByDocumentRef.get(documentRef);
|
|
18880
|
-
if (!snapshot) {
|
|
18881
|
-
throw new Error(`missing DOM snapshot for ${documentRef}`);
|
|
18882
|
-
}
|
|
18883
|
-
const index = createSnapshotIndex(snapshot);
|
|
18884
|
-
snapshotIndices.set(documentRef, index);
|
|
18885
|
-
return index;
|
|
18886
|
-
}
|
|
18887
18983
|
function escapeHtml(value) {
|
|
18888
18984
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
18889
18985
|
}
|
|
@@ -20016,7 +20112,10 @@ var OpensteerSessionRuntime = class {
|
|
|
20016
20112
|
sessionRef;
|
|
20017
20113
|
pageRef;
|
|
20018
20114
|
runId;
|
|
20019
|
-
|
|
20115
|
+
observationSessions = /* @__PURE__ */ new Map();
|
|
20116
|
+
openingObservationSessions = /* @__PURE__ */ new Map();
|
|
20117
|
+
openedObservationSessions = /* @__PURE__ */ new Set();
|
|
20118
|
+
observationSessionStorage = new async_hooks.AsyncLocalStorage();
|
|
20020
20119
|
operationEventStorage = new async_hooks.AsyncLocalStorage();
|
|
20021
20120
|
pendingOperationEventCaptures = [];
|
|
20022
20121
|
ownsEngine = false;
|
|
@@ -20068,18 +20167,26 @@ var OpensteerSessionRuntime = class {
|
|
|
20068
20167
|
}
|
|
20069
20168
|
async setObservabilityConfig(input) {
|
|
20070
20169
|
this.observationConfig = normalizeObservabilityConfig(input);
|
|
20071
|
-
|
|
20072
|
-
if (observationSessionId === void 0) {
|
|
20073
|
-
return this.observationConfig;
|
|
20074
|
-
}
|
|
20075
|
-
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
20076
|
-
this.observations = await sink.openSession({
|
|
20077
|
-
sessionId: observationSessionId,
|
|
20078
|
-
openedAt: Date.now(),
|
|
20079
|
-
config: this.observationConfig
|
|
20080
|
-
});
|
|
20170
|
+
await this.ensureConfiguredObservationSession();
|
|
20081
20171
|
return this.observationConfig;
|
|
20082
20172
|
}
|
|
20173
|
+
async withObservationSessionId(sessionId, task) {
|
|
20174
|
+
return await this.observationSessionStorage.run(
|
|
20175
|
+
{
|
|
20176
|
+
mode: "session",
|
|
20177
|
+
sessionId: normalizeNonEmptyString("sessionId", sessionId)
|
|
20178
|
+
},
|
|
20179
|
+
task
|
|
20180
|
+
);
|
|
20181
|
+
}
|
|
20182
|
+
async withoutObservationSession(task) {
|
|
20183
|
+
return await this.observationSessionStorage.run(
|
|
20184
|
+
{
|
|
20185
|
+
mode: "disabled"
|
|
20186
|
+
},
|
|
20187
|
+
task
|
|
20188
|
+
);
|
|
20189
|
+
}
|
|
20083
20190
|
async open(input = {}, options = {}) {
|
|
20084
20191
|
assertValidSemanticOperationInput("session.open", input);
|
|
20085
20192
|
if (input.workspace !== void 0 && normalizeNamespace2(input.workspace) !== this.workspace) {
|
|
@@ -20096,7 +20203,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20096
20203
|
options
|
|
20097
20204
|
);
|
|
20098
20205
|
}
|
|
20099
|
-
return this.
|
|
20206
|
+
return this.readNavigationSummary();
|
|
20100
20207
|
}
|
|
20101
20208
|
const startedAt = Date.now();
|
|
20102
20209
|
const root = await this.ensureRoot();
|
|
@@ -20117,7 +20224,8 @@ var OpensteerSessionRuntime = class {
|
|
|
20117
20224
|
openedSessionRef = sessionRef;
|
|
20118
20225
|
const createdPage = await timeout.runStep(
|
|
20119
20226
|
() => engine.createPage({
|
|
20120
|
-
sessionRef
|
|
20227
|
+
sessionRef,
|
|
20228
|
+
...input.url === void 0 ? {} : { url: input.url }
|
|
20121
20229
|
})
|
|
20122
20230
|
);
|
|
20123
20231
|
openedPageRef = createdPage.data.pageRef;
|
|
@@ -20127,18 +20235,19 @@ var OpensteerSessionRuntime = class {
|
|
|
20127
20235
|
await timeout.runStep(() => this.ensureSemantics());
|
|
20128
20236
|
let frameRef2 = createdPage.frameRef;
|
|
20129
20237
|
if (input.url !== void 0) {
|
|
20130
|
-
|
|
20131
|
-
{
|
|
20238
|
+
await timeout.runStep(
|
|
20239
|
+
() => settleWithPolicy(this.policy.settle, {
|
|
20132
20240
|
operation: "session.open",
|
|
20241
|
+
trigger: "navigation",
|
|
20242
|
+
engine: this.requireEngine(),
|
|
20133
20243
|
pageRef: createdPage.data.pageRef,
|
|
20134
|
-
|
|
20135
|
-
|
|
20136
|
-
|
|
20244
|
+
signal: timeout.signal,
|
|
20245
|
+
remainingMs: timeout.remainingMs()
|
|
20246
|
+
})
|
|
20137
20247
|
);
|
|
20138
|
-
frameRef2 = navigation.data.mainFrame.frameRef;
|
|
20139
20248
|
}
|
|
20140
20249
|
return {
|
|
20141
|
-
state: await timeout.runStep(() => this.
|
|
20250
|
+
state: await timeout.runStep(() => this.readNavigationSummary()),
|
|
20142
20251
|
frameRef: frameRef2
|
|
20143
20252
|
};
|
|
20144
20253
|
},
|
|
@@ -20231,7 +20340,11 @@ var OpensteerSessionRuntime = class {
|
|
|
20231
20340
|
"page.new cannot use openerPageRef before a session exists"
|
|
20232
20341
|
);
|
|
20233
20342
|
}
|
|
20234
|
-
|
|
20343
|
+
const summary = await this.open(input.url === void 0 ? {} : { url: input.url }, options);
|
|
20344
|
+
return {
|
|
20345
|
+
pageRef: await this.ensurePageRef(),
|
|
20346
|
+
...summary
|
|
20347
|
+
};
|
|
20235
20348
|
}
|
|
20236
20349
|
const startedAt = Date.now();
|
|
20237
20350
|
try {
|
|
@@ -20246,7 +20359,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20246
20359
|
})
|
|
20247
20360
|
);
|
|
20248
20361
|
this.pageRef = created.data.pageRef;
|
|
20249
|
-
return this.
|
|
20362
|
+
return this.readCreatedPageOutput(created.data.pageRef);
|
|
20250
20363
|
},
|
|
20251
20364
|
options
|
|
20252
20365
|
);
|
|
@@ -20288,7 +20401,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20288
20401
|
() => this.requireEngine().activatePage({ pageRef: input.pageRef })
|
|
20289
20402
|
);
|
|
20290
20403
|
this.pageRef = input.pageRef;
|
|
20291
|
-
return this.
|
|
20404
|
+
return this.readNavigationSummary(input.pageRef);
|
|
20292
20405
|
},
|
|
20293
20406
|
options
|
|
20294
20407
|
);
|
|
@@ -20414,7 +20527,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20414
20527
|
timeout.throwIfAborted();
|
|
20415
20528
|
return {
|
|
20416
20529
|
navigation: navigation2,
|
|
20417
|
-
state: await timeout.runStep(() => this.
|
|
20530
|
+
state: await timeout.runStep(() => this.readNavigationSummary(pageRef))
|
|
20418
20531
|
};
|
|
20419
20532
|
},
|
|
20420
20533
|
(diagnostics) => {
|
|
@@ -21648,7 +21761,7 @@ var OpensteerSessionRuntime = class {
|
|
|
21648
21761
|
let mutationCaptureDiagnostics;
|
|
21649
21762
|
let boundaryDiagnostics;
|
|
21650
21763
|
try {
|
|
21651
|
-
const { artifacts, output } = await this.runMutationCapturedOperation(
|
|
21764
|
+
const { artifacts, output, result } = await this.runMutationCapturedOperation(
|
|
21652
21765
|
"computer.execute",
|
|
21653
21766
|
{
|
|
21654
21767
|
...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
|
|
@@ -21666,9 +21779,14 @@ var OpensteerSessionRuntime = class {
|
|
|
21666
21779
|
await this.invalidateLiveSnapshotCounters([pageRef, output2.pageRef], timeout);
|
|
21667
21780
|
this.pageRef = output2.pageRef;
|
|
21668
21781
|
const artifacts2 = await this.persistComputerArtifacts(output2, timeout);
|
|
21782
|
+
const result2 = {
|
|
21783
|
+
...await timeout.runStep(() => this.readNavigationSummary(output2.pageRef)),
|
|
21784
|
+
screenshot: artifacts2.screenshot
|
|
21785
|
+
};
|
|
21669
21786
|
return {
|
|
21670
21787
|
artifacts: { manifests: artifacts2.manifests },
|
|
21671
|
-
output:
|
|
21788
|
+
output: output2,
|
|
21789
|
+
result: result2
|
|
21672
21790
|
};
|
|
21673
21791
|
} catch (error) {
|
|
21674
21792
|
boundaryDiagnostics ??= takeActionBoundaryDiagnostics(timeout.signal);
|
|
@@ -21705,7 +21823,7 @@ var OpensteerSessionRuntime = class {
|
|
|
21705
21823
|
documentEpoch: output.screenshot.documentEpoch
|
|
21706
21824
|
})
|
|
21707
21825
|
});
|
|
21708
|
-
return
|
|
21826
|
+
return result;
|
|
21709
21827
|
} catch (error) {
|
|
21710
21828
|
await this.appendTrace({
|
|
21711
21829
|
operation: "computer.execute",
|
|
@@ -21853,8 +21971,9 @@ var OpensteerSessionRuntime = class {
|
|
|
21853
21971
|
mutationCaptureDiagnostics = diagnostics;
|
|
21854
21972
|
}
|
|
21855
21973
|
);
|
|
21856
|
-
const output = toOpensteerActionResult(executed.result);
|
|
21974
|
+
const output = toOpensteerActionResult(executed.result.resolved);
|
|
21857
21975
|
const actionEvents = "events" in executed.result ? executed.result.events : void 0;
|
|
21976
|
+
const resolvedTarget = toOpensteerResolvedTarget2(executed.result.resolved);
|
|
21858
21977
|
await this.appendTrace({
|
|
21859
21978
|
operation,
|
|
21860
21979
|
startedAt,
|
|
@@ -21862,8 +21981,13 @@ var OpensteerSessionRuntime = class {
|
|
|
21862
21981
|
outcome: "ok",
|
|
21863
21982
|
...actionEvents === void 0 ? {} : { events: actionEvents },
|
|
21864
21983
|
data: {
|
|
21865
|
-
target:
|
|
21866
|
-
...
|
|
21984
|
+
target: resolvedTarget,
|
|
21985
|
+
..."point" in executed.result && executed.result.point !== void 0 ? {
|
|
21986
|
+
point: {
|
|
21987
|
+
x: executed.result.point.x,
|
|
21988
|
+
y: executed.result.point.y
|
|
21989
|
+
}
|
|
21990
|
+
} : {},
|
|
21867
21991
|
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
21868
21992
|
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
21869
21993
|
},
|
|
@@ -23328,20 +23452,20 @@ var OpensteerSessionRuntime = class {
|
|
|
23328
23452
|
throw error;
|
|
23329
23453
|
}
|
|
23330
23454
|
}
|
|
23331
|
-
async
|
|
23332
|
-
const pageRef = await this.ensurePageRef();
|
|
23455
|
+
async readNavigationSummary(targetPageRef) {
|
|
23456
|
+
const pageRef = targetPageRef ?? await this.ensurePageRef();
|
|
23333
23457
|
const pageInfo = await this.requireEngine().getPageInfo({ pageRef });
|
|
23334
|
-
const sessionRef = this.sessionRef;
|
|
23335
|
-
if (!sessionRef) {
|
|
23336
|
-
throw new Error("Opensteer session is not initialized");
|
|
23337
|
-
}
|
|
23338
23458
|
return {
|
|
23339
|
-
sessionRef,
|
|
23340
|
-
pageRef,
|
|
23341
23459
|
url: pageInfo.url,
|
|
23342
23460
|
title: pageInfo.title
|
|
23343
23461
|
};
|
|
23344
23462
|
}
|
|
23463
|
+
async readCreatedPageOutput(pageRef) {
|
|
23464
|
+
return {
|
|
23465
|
+
pageRef,
|
|
23466
|
+
...await this.readNavigationSummary(pageRef)
|
|
23467
|
+
};
|
|
23468
|
+
}
|
|
23345
23469
|
async captureSnapshotArtifacts(pageRef, options, timeout) {
|
|
23346
23470
|
const root = this.requireRoot();
|
|
23347
23471
|
const mainFrame = await timeout.runStep(() => getMainFrame(this.requireEngine(), pageRef));
|
|
@@ -23413,12 +23537,12 @@ var OpensteerSessionRuntime = class {
|
|
|
23413
23537
|
const screenshotPayload = manifestToExternalBinaryLocation(root.rootPath, screenshotManifest);
|
|
23414
23538
|
return {
|
|
23415
23539
|
manifests,
|
|
23416
|
-
|
|
23417
|
-
|
|
23418
|
-
|
|
23419
|
-
|
|
23420
|
-
|
|
23421
|
-
}
|
|
23540
|
+
screenshot: {
|
|
23541
|
+
payload: screenshotPayload,
|
|
23542
|
+
format: output.screenshot.format,
|
|
23543
|
+
size: output.screenshot.size,
|
|
23544
|
+
coordinateSpace: output.screenshot.coordinateSpace,
|
|
23545
|
+
...output.screenshot.clip === void 0 ? {} : { clip: output.screenshot.clip }
|
|
23422
23546
|
}
|
|
23423
23547
|
};
|
|
23424
23548
|
}
|
|
@@ -23506,7 +23630,7 @@ var OpensteerSessionRuntime = class {
|
|
|
23506
23630
|
}
|
|
23507
23631
|
async resetRuntimeState(options) {
|
|
23508
23632
|
const engine = this.engine;
|
|
23509
|
-
const
|
|
23633
|
+
const observationSessions = [...this.openedObservationSessions];
|
|
23510
23634
|
this.networkHistory.clear();
|
|
23511
23635
|
this.sessionRef = void 0;
|
|
23512
23636
|
this.pageRef = void 0;
|
|
@@ -23515,9 +23639,15 @@ var OpensteerSessionRuntime = class {
|
|
|
23515
23639
|
this.computer = void 0;
|
|
23516
23640
|
this.extractionDescriptors = void 0;
|
|
23517
23641
|
this.engine = void 0;
|
|
23518
|
-
this.
|
|
23642
|
+
this.observationSessions.clear();
|
|
23643
|
+
this.openingObservationSessions.clear();
|
|
23644
|
+
this.openedObservationSessions.clear();
|
|
23519
23645
|
this.pendingOperationEventCaptures.length = 0;
|
|
23520
|
-
await
|
|
23646
|
+
await Promise.allSettled(
|
|
23647
|
+
observationSessions.map(
|
|
23648
|
+
(observationSession) => observationSession.close("runtime_reset").catch(() => void 0)
|
|
23649
|
+
)
|
|
23650
|
+
);
|
|
23521
23651
|
if (options.disposeEngine && this.ownsEngine && engine?.dispose) {
|
|
23522
23652
|
await engine.dispose();
|
|
23523
23653
|
}
|
|
@@ -23527,23 +23657,64 @@ var OpensteerSessionRuntime = class {
|
|
|
23527
23657
|
if (this.observationConfig.profile === "off") {
|
|
23528
23658
|
return void 0;
|
|
23529
23659
|
}
|
|
23530
|
-
|
|
23531
|
-
|
|
23660
|
+
const observationSessionId = this.resolveObservationSessionId();
|
|
23661
|
+
if (observationSessionId === void 0) {
|
|
23662
|
+
return void 0;
|
|
23663
|
+
}
|
|
23664
|
+
const existingObservationSession = this.observationSessions.get(observationSessionId);
|
|
23665
|
+
if (existingObservationSession !== void 0) {
|
|
23666
|
+
return existingObservationSession;
|
|
23667
|
+
}
|
|
23668
|
+
const openingObservationSession = this.openingObservationSessions.get(observationSessionId);
|
|
23669
|
+
if (openingObservationSession !== void 0) {
|
|
23670
|
+
return await openingObservationSession;
|
|
23671
|
+
}
|
|
23672
|
+
const openObservationSessionTask = this.openObservationSession(observationSessionId).finally(
|
|
23673
|
+
() => {
|
|
23674
|
+
this.openingObservationSessions.delete(observationSessionId);
|
|
23675
|
+
}
|
|
23676
|
+
);
|
|
23677
|
+
this.openingObservationSessions.set(observationSessionId, openObservationSessionTask);
|
|
23678
|
+
return await openObservationSessionTask;
|
|
23679
|
+
}
|
|
23680
|
+
async ensureConfiguredObservationSession() {
|
|
23681
|
+
if (this.observationConfig.profile === "off") {
|
|
23682
|
+
return void 0;
|
|
23532
23683
|
}
|
|
23533
23684
|
const observationSessionId = this.resolveObservationSessionId();
|
|
23534
23685
|
if (observationSessionId === void 0) {
|
|
23535
23686
|
return void 0;
|
|
23536
23687
|
}
|
|
23688
|
+
const hadObservationSession = this.observationSessions.has(observationSessionId) || this.openingObservationSessions.has(observationSessionId);
|
|
23689
|
+
const observationSession = await this.ensureObservationSession();
|
|
23690
|
+
if (observationSession !== void 0 && hadObservationSession) {
|
|
23691
|
+
await observationSession.configure?.({
|
|
23692
|
+
config: this.observationConfig,
|
|
23693
|
+
updatedAt: Date.now()
|
|
23694
|
+
});
|
|
23695
|
+
}
|
|
23696
|
+
return observationSession;
|
|
23697
|
+
}
|
|
23698
|
+
resolveObservationSessionId() {
|
|
23699
|
+
const scopedSession = this.observationSessionStorage.getStore();
|
|
23700
|
+
if (scopedSession?.mode === "session") {
|
|
23701
|
+
return scopedSession.sessionId;
|
|
23702
|
+
}
|
|
23703
|
+
if (scopedSession?.mode === "disabled") {
|
|
23704
|
+
return void 0;
|
|
23705
|
+
}
|
|
23706
|
+
return this.observationSessionId ?? this.sessionRef;
|
|
23707
|
+
}
|
|
23708
|
+
async openObservationSession(sessionId) {
|
|
23537
23709
|
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
23538
|
-
|
|
23539
|
-
sessionId
|
|
23710
|
+
const observationSession = await sink.openSession({
|
|
23711
|
+
sessionId,
|
|
23540
23712
|
openedAt: Date.now(),
|
|
23541
23713
|
config: this.observationConfig
|
|
23542
23714
|
});
|
|
23543
|
-
|
|
23544
|
-
|
|
23545
|
-
|
|
23546
|
-
return this.observationSessionId ?? this.sessionRef;
|
|
23715
|
+
this.observationSessions.set(sessionId, observationSession);
|
|
23716
|
+
this.openedObservationSessions.add(observationSession);
|
|
23717
|
+
return observationSession;
|
|
23547
23718
|
}
|
|
23548
23719
|
runWithOperationTimeout(operation, callback, options = {}) {
|
|
23549
23720
|
const timeoutPolicy = options.timeoutMs === void 0 ? this.policy.timeout : {
|
|
@@ -24941,15 +25112,10 @@ function normalizeNamespace2(value) {
|
|
|
24941
25112
|
const normalized = String(value ?? "default").trim();
|
|
24942
25113
|
return normalized.length === 0 ? "default" : normalized;
|
|
24943
25114
|
}
|
|
24944
|
-
function toOpensteerActionResult(
|
|
25115
|
+
function toOpensteerActionResult(target) {
|
|
24945
25116
|
return {
|
|
24946
|
-
|
|
24947
|
-
...
|
|
24948
|
-
point: {
|
|
24949
|
-
x: result.point.x,
|
|
24950
|
-
y: result.point.y
|
|
24951
|
-
}
|
|
24952
|
-
}
|
|
25117
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
25118
|
+
...target.persist === void 0 ? {} : { persist: target.persist }
|
|
24953
25119
|
};
|
|
24954
25120
|
}
|
|
24955
25121
|
function toOpensteerResolvedTarget2(target) {
|
|
@@ -24959,12 +25125,16 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
24959
25125
|
documentRef: target.documentRef,
|
|
24960
25126
|
documentEpoch: target.documentEpoch,
|
|
24961
25127
|
nodeRef: target.nodeRef,
|
|
24962
|
-
tagName: target.node.nodeName
|
|
25128
|
+
tagName: toOpensteerTagName2(target.node.nodeName),
|
|
24963
25129
|
pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
|
|
24964
25130
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
24965
25131
|
...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
|
|
24966
25132
|
};
|
|
24967
25133
|
}
|
|
25134
|
+
function toOpensteerTagName2(nodeName) {
|
|
25135
|
+
const tagName = String(nodeName).trim().toLowerCase();
|
|
25136
|
+
return tagName.length === 0 ? "element" : tagName;
|
|
25137
|
+
}
|
|
24968
25138
|
function normalizeOpensteerError(error) {
|
|
24969
25139
|
return normalizeThrownOpensteerError2(error, "Unknown Opensteer runtime failure");
|
|
24970
25140
|
}
|
|
@@ -26220,7 +26390,29 @@ function isLoopbackBaseUrl(baseUrl) {
|
|
|
26220
26390
|
}
|
|
26221
26391
|
return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1" || url.hostname === "[::1]";
|
|
26222
26392
|
}
|
|
26223
|
-
var
|
|
26393
|
+
var LocalActivePageHintRuntime = class extends OpensteerSessionRuntime {
|
|
26394
|
+
async completeWithLocalActivePageHint(operation) {
|
|
26395
|
+
const output = await operation();
|
|
26396
|
+
await persistLocalActivePageHint(this, this.rootPath);
|
|
26397
|
+
return output;
|
|
26398
|
+
}
|
|
26399
|
+
async open(input = {}, options = {}) {
|
|
26400
|
+
return this.completeWithLocalActivePageHint(() => super.open(input, options));
|
|
26401
|
+
}
|
|
26402
|
+
async newPage(input = {}, options = {}) {
|
|
26403
|
+
return this.completeWithLocalActivePageHint(() => super.newPage(input, options));
|
|
26404
|
+
}
|
|
26405
|
+
async activatePage(input, options = {}) {
|
|
26406
|
+
return this.completeWithLocalActivePageHint(() => super.activatePage(input, options));
|
|
26407
|
+
}
|
|
26408
|
+
async closePage(input = {}, options = {}) {
|
|
26409
|
+
return this.completeWithLocalActivePageHint(() => super.closePage(input, options));
|
|
26410
|
+
}
|
|
26411
|
+
async goto(input, options = {}) {
|
|
26412
|
+
return this.completeWithLocalActivePageHint(() => super.goto(input, options));
|
|
26413
|
+
}
|
|
26414
|
+
};
|
|
26415
|
+
var OpensteerRuntime = class extends LocalActivePageHintRuntime {
|
|
26224
26416
|
constructor(options = {}) {
|
|
26225
26417
|
const publicWorkspace = normalizeWorkspace2(options.workspace);
|
|
26226
26418
|
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ? path10__default.default.resolve(options.rootDir ?? process.cwd(), ".opensteer", "temporary", crypto.randomUUID()) : resolveFilesystemWorkspacePath({
|
|
@@ -26258,6 +26450,41 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
|
26258
26450
|
);
|
|
26259
26451
|
}
|
|
26260
26452
|
};
|
|
26453
|
+
async function persistLocalActivePageHint(runtime, rootPath) {
|
|
26454
|
+
try {
|
|
26455
|
+
await syncPersistedLocalActivePageHint(runtime, rootPath);
|
|
26456
|
+
} catch {
|
|
26457
|
+
}
|
|
26458
|
+
}
|
|
26459
|
+
async function syncPersistedLocalActivePageHint(runtime, rootPath) {
|
|
26460
|
+
const record = await readPersistedLocalBrowserSessionRecord(rootPath);
|
|
26461
|
+
if (!record) {
|
|
26462
|
+
return;
|
|
26463
|
+
}
|
|
26464
|
+
const sessionInfo = await runtime.info();
|
|
26465
|
+
const activePageRef = sessionInfo.activePageRef;
|
|
26466
|
+
let activePageUrl;
|
|
26467
|
+
let activePageTitle;
|
|
26468
|
+
if (activePageRef !== void 0) {
|
|
26469
|
+
const pages = await runtime.listPages();
|
|
26470
|
+
const activePage = pages.pages.find((page) => page.pageRef === activePageRef);
|
|
26471
|
+
activePageUrl = activePage?.url;
|
|
26472
|
+
activePageTitle = activePage?.title;
|
|
26473
|
+
}
|
|
26474
|
+
const {
|
|
26475
|
+
activePageRef: _previousActivePageRef,
|
|
26476
|
+
activePageUrl: _previousActivePageUrl,
|
|
26477
|
+
activePageTitle: _previousActivePageTitle,
|
|
26478
|
+
...restRecord
|
|
26479
|
+
} = record;
|
|
26480
|
+
await writePersistedSessionRecord(rootPath, {
|
|
26481
|
+
...restRecord,
|
|
26482
|
+
updatedAt: Date.now(),
|
|
26483
|
+
...activePageRef === void 0 ? {} : { activePageRef },
|
|
26484
|
+
...activePageUrl === void 0 ? {} : { activePageUrl },
|
|
26485
|
+
...activePageTitle === void 0 ? {} : { activePageTitle }
|
|
26486
|
+
});
|
|
26487
|
+
}
|
|
26261
26488
|
function buildSharedRuntimeOptions(input) {
|
|
26262
26489
|
const ownership = resolveOwnership(input.browser);
|
|
26263
26490
|
const engineFactory = input.engineFactory ?? ((factoryOptions) => new OpensteerBrowserManager({
|
|
@@ -26758,6 +26985,7 @@ function delay3(ms) {
|
|
|
26758
26985
|
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
26759
26986
|
}
|
|
26760
26987
|
|
|
26988
|
+
exports.DEFAULT_OPENSTEER_CLOUD_BASE_URL = DEFAULT_OPENSTEER_CLOUD_BASE_URL;
|
|
26761
26989
|
exports.DEFAULT_OPENSTEER_ENGINE = DEFAULT_OPENSTEER_ENGINE;
|
|
26762
26990
|
exports.DEFERRED_MATCH_ATTR_KEYS = DEFERRED_MATCH_ATTR_KEYS;
|
|
26763
26991
|
exports.ElementPathError = ElementPathError;
|