opensteer 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{chunk-BVRIPCWA.js → chunk-3OHKIPBD.js} +316 -465
  2. package/dist/chunk-3OHKIPBD.js.map +1 -0
  3. package/dist/{chunk-L4NF74KI.js → chunk-52UNH5UW.js} +5 -5
  4. package/dist/{chunk-L4NF74KI.js.map → chunk-52UNH5UW.js.map} +1 -1
  5. package/dist/{chunk-3XBQRZZC.js → chunk-PJXN7HED.js} +115 -14
  6. package/dist/chunk-PJXN7HED.js.map +1 -0
  7. package/dist/{chunk-3I3A5OLB.js → chunk-R33BXCMQ.js} +16 -7
  8. package/dist/chunk-R33BXCMQ.js.map +1 -0
  9. package/dist/{chunk-T5P2QGZ3.js → chunk-U4BUCIZ4.js} +153 -12
  10. package/dist/chunk-U4BUCIZ4.js.map +1 -0
  11. package/dist/cli/bin.cjs +663 -544
  12. package/dist/cli/bin.cjs.map +1 -1
  13. package/dist/cli/bin.js +66 -50
  14. package/dist/cli/bin.js.map +1 -1
  15. package/dist/index.cjs +584 -495
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +26 -50
  18. package/dist/index.d.ts +26 -50
  19. package/dist/index.js +4 -4
  20. package/dist/local-view/public/assets/app.js +10 -1
  21. package/dist/local-view/serve-entry.cjs +687 -494
  22. package/dist/local-view/serve-entry.cjs.map +1 -1
  23. package/dist/local-view/serve-entry.js +2 -2
  24. package/dist/opensteer-CY2QUJEG.js +6 -0
  25. package/dist/{opensteer-UGA6YBRN.js.map → opensteer-CY2QUJEG.js.map} +1 -1
  26. package/dist/{session-control-U3L5H2ZI.js → session-control-FIP6ZJLH.js} +4 -4
  27. package/dist/{session-control-U3L5H2ZI.js.map → session-control-FIP6ZJLH.js.map} +1 -1
  28. package/package.json +7 -7
  29. package/dist/chunk-3I3A5OLB.js.map +0 -1
  30. package/dist/chunk-3XBQRZZC.js.map +0 -1
  31. package/dist/chunk-BVRIPCWA.js.map +0 -1
  32. package/dist/chunk-T5P2QGZ3.js.map +0 -1
  33. package/dist/opensteer-UGA6YBRN.js +0 -6
@@ -1,5 +1,5 @@
1
- import { objectSchema, stringSchema, literalSchema, JSON_SCHEMA_DRAFT_2020_12, integerSchema, enumSchema, oneOfSchema, numberSchema, arraySchema, recordSchema, defineSchema, opensteerCapabilitySetSchema, opensteerErrorSchema, OpensteerProtocolError, resolveFilesystemWorkspacePath, createFilesystemOpensteerWorkspace, DEFAULT_OPENSTEER_ENGINE, createOpensteerError, assertSupportedEngineOptions, normalizeObservabilityConfig, manifestToExternalBinaryLocation, normalizeObservationContext, OpensteerBrowserManager, isOpensteerProtocolError, toOpensteerError } from './chunk-3XBQRZZC.js';
2
- import { canonicalJsonString, toCanonicalJsonValue, readPersistedCloudSessionRecord, writePersistedSessionRecord, clearPersistedSessionRecord, resolveBrandUserDataDir, sha256Hex, getBrowserBrand, detectInstalledBrowserBrands, __require } from './chunk-T5P2QGZ3.js';
1
+ import { objectSchema, stringSchema, literalSchema, JSON_SCHEMA_DRAFT_2020_12, integerSchema, enumSchema, oneOfSchema, numberSchema, arraySchema, recordSchema, defineSchema, opensteerCapabilitySetSchema, opensteerErrorSchema, OpensteerProtocolError, resolveFilesystemWorkspacePath, createFilesystemOpensteerWorkspace, DEFAULT_OPENSTEER_ENGINE, createOpensteerError, assertSupportedEngineOptions, normalizeObservabilityConfig, manifestToExternalBinaryLocation, normalizeObservationContext, OpensteerBrowserManager, isOpensteerProtocolError, toOpensteerError } from './chunk-PJXN7HED.js';
2
+ import { canonicalJsonString, toCanonicalJsonValue, readPersistedCloudSessionRecord, writePersistedSessionRecord, clearPersistedSessionRecord, resolveBrandUserDataDir, sha256Hex, getBrowserBrand, detectInstalledBrowserBrands, __require } from './chunk-U4BUCIZ4.js';
3
3
  import { selectAll } from 'css-select';
4
4
  import { createHash, randomUUID, pbkdf2Sync, createDecipheriv } from 'crypto';
5
5
  import { existsSync, readFileSync } from 'fs';
@@ -238,14 +238,14 @@ var DEFAULT_SETTLE_DELAYS = {
238
238
  snapshot: 0
239
239
  };
240
240
  var DOM_ACTION_VISUAL_STABILITY_PROFILES = {
241
- "dom.click": { settleMs: 750, scope: "visible-frames", timeoutMs: 7e3 },
242
- "dom.input": { settleMs: 750, scope: "visible-frames", timeoutMs: 7e3 },
243
- "dom.scroll": { settleMs: 600, scope: "visible-frames", timeoutMs: 7e3 },
241
+ "dom.click": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
242
+ "dom.input": { settleMs: 750, scope: "main-frame", timeoutMs: 7e3 },
243
+ "dom.scroll": { settleMs: 600, scope: "main-frame", timeoutMs: 7e3 },
244
244
  "dom.hover": { settleMs: 200, scope: "main-frame", timeoutMs: 2500 }
245
245
  };
246
246
  var DEFAULT_DOM_ACTION_VISUAL_STABILITY_PROFILE = {
247
247
  settleMs: 750,
248
- scope: "visible-frames",
248
+ scope: "main-frame",
249
249
  timeoutMs: 7e3
250
250
  };
251
251
  var NAVIGATION_VISUAL_STABILITY_PROFILE = {
@@ -269,6 +269,7 @@ var defaultDomActionSettleObserver = {
269
269
  pageRef: input.pageRef,
270
270
  timeoutMs: effectiveTimeout,
271
271
  settleMs: profile.settleMs,
272
+ ...input.observedMutationQuietMs === void 0 ? {} : { initialQuietMs: input.observedMutationQuietMs },
272
273
  scope: profile.scope
273
274
  });
274
275
  return true;
@@ -289,15 +290,20 @@ var defaultNavigationSettleObserver = {
289
290
  return false;
290
291
  }
291
292
  try {
292
- const startedAt = Date.now();
293
- await input.engine.waitForPostLoadQuiet({
294
- pageRef: input.pageRef,
295
- timeoutMs: effectiveTimeout,
296
- quietMs: DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS,
297
- captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
298
- signal: input.signal
299
- });
300
- const visualTimeout = Math.max(0, effectiveTimeout - (Date.now() - startedAt));
293
+ let visualTimeout = effectiveTimeout;
294
+ let initialQuietMs = input.observedMutationQuietMs ?? 0;
295
+ if (!input.postLoadHandled) {
296
+ const startedAt = Date.now();
297
+ await input.engine.waitForPostLoadQuiet({
298
+ pageRef: input.pageRef,
299
+ timeoutMs: effectiveTimeout,
300
+ quietMs: DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS,
301
+ captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
302
+ signal: input.signal
303
+ });
304
+ visualTimeout = Math.max(0, effectiveTimeout - (Date.now() - startedAt));
305
+ initialQuietMs = Math.max(initialQuietMs, DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS);
306
+ }
301
307
  if (visualTimeout <= 0) {
302
308
  return true;
303
309
  }
@@ -305,6 +311,7 @@ var defaultNavigationSettleObserver = {
305
311
  pageRef: input.pageRef,
306
312
  timeoutMs: visualTimeout,
307
313
  settleMs: profile.settleMs,
314
+ ...initialQuietMs <= 0 ? {} : { initialQuietMs },
308
315
  scope: profile.scope
309
316
  });
310
317
  return true;
@@ -626,7 +633,7 @@ function isJsonValueEqual(expected, actual) {
626
633
 
627
634
  // ../protocol/src/version.ts
628
635
  var OPENSTEER_PROTOCOL_NAME = "opensteer";
629
- var OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION = 2;
636
+ var OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION = 3;
630
637
  var OPENSTEER_PROTOCOL_VERSION = `0.${OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION}.0`;
631
638
  var OPENSTEER_PROTOCOL_REST_BASE_PATH = `/api/v${OPENSTEER_PROTOCOL_COMPATIBILITY_REVISION}`;
632
639
  objectSchema(
@@ -815,7 +822,7 @@ var visualViewportSchema = objectSchema(
815
822
  required: ["origin", "offsetWithinLayoutViewport", "size"]
816
823
  }
817
824
  );
818
- var viewportMetricsSchema = objectSchema(
825
+ objectSchema(
819
826
  {
820
827
  layoutViewport: layoutViewportSchema,
821
828
  visualViewport: visualViewportSchema,
@@ -2266,7 +2273,7 @@ var domSnapshotSchema = objectSchema(
2266
2273
  ]
2267
2274
  }
2268
2275
  );
2269
- var hitTestResultSchema = objectSchema(
2276
+ objectSchema(
2270
2277
  {
2271
2278
  inputPoint: pointSchema,
2272
2279
  inputCoordinateSpace: coordinateSpaceSchema,
@@ -3573,39 +3580,14 @@ var opensteerTargetInputSchema = oneOfSchema(
3573
3580
  title: "OpensteerTargetInput"
3574
3581
  }
3575
3582
  );
3576
- var opensteerResolvedTargetSchema = objectSchema(
3577
- {
3578
- pageRef: pageRefSchema,
3579
- frameRef: frameRefSchema,
3580
- documentRef: documentRefSchema,
3581
- documentEpoch: documentEpochSchema,
3582
- nodeRef: nodeRefSchema,
3583
- tagName: stringSchema(),
3584
- pathHint: stringSchema(),
3585
- persist: stringSchema(),
3586
- selectorUsed: stringSchema()
3587
- },
3588
- {
3589
- title: "OpensteerResolvedTarget",
3590
- required: [
3591
- "pageRef",
3592
- "frameRef",
3593
- "documentRef",
3594
- "documentEpoch",
3595
- "nodeRef",
3596
- "tagName",
3597
- "pathHint"
3598
- ]
3599
- }
3600
- );
3601
3583
  var opensteerActionResultSchema = objectSchema(
3602
3584
  {
3603
- target: opensteerResolvedTargetSchema,
3604
- point: pointSchema
3585
+ tagName: stringSchema({ minLength: 1 }),
3586
+ persist: stringSchema({ minLength: 1 })
3605
3587
  },
3606
3588
  {
3607
3589
  title: "OpensteerActionResult",
3608
- required: ["target"]
3590
+ required: ["tagName"]
3609
3591
  }
3610
3592
  );
3611
3593
  var opensteerSnapshotCounterSchema = objectSchema(
@@ -3651,16 +3633,14 @@ var opensteerSnapshotCounterSchema = objectSchema(
3651
3633
  ]
3652
3634
  }
3653
3635
  );
3654
- var opensteerSessionStateSchema = objectSchema(
3636
+ var opensteerNavigationSummarySchema = objectSchema(
3655
3637
  {
3656
- sessionRef: sessionRefSchema,
3657
- pageRef: pageRefSchema,
3658
3638
  url: stringSchema(),
3659
3639
  title: stringSchema()
3660
3640
  },
3661
3641
  {
3662
- title: "OpensteerSessionState",
3663
- required: ["sessionRef", "pageRef", "url", "title"]
3642
+ title: "OpensteerNavigationSummary",
3643
+ required: ["url", "title"]
3664
3644
  }
3665
3645
  );
3666
3646
  var opensteerOpenInputSchema = objectSchema(
@@ -3728,6 +3708,17 @@ var opensteerPageCloseOutputSchema = objectSchema(
3728
3708
  required: ["closedPageRef", "pages"]
3729
3709
  }
3730
3710
  );
3711
+ var opensteerPageNewOutputSchema = objectSchema(
3712
+ {
3713
+ pageRef: pageRefSchema,
3714
+ url: stringSchema(),
3715
+ title: stringSchema()
3716
+ },
3717
+ {
3718
+ title: "OpensteerPageNewOutput",
3719
+ required: ["pageRef", "url", "title"]
3720
+ }
3721
+ );
3731
3722
  var opensteerPageGotoInputSchema = objectSchema(
3732
3723
  {
3733
3724
  url: stringSchema(),
@@ -4114,72 +4105,28 @@ var opensteerComputerExecuteInputSchema = objectSchema(
4114
4105
  required: ["action"]
4115
4106
  }
4116
4107
  );
4117
- var opensteerComputerTracePointSchema = objectSchema(
4118
- {
4119
- role: enumSchema(["point", "start", "end"]),
4120
- point: pointSchema,
4121
- hitTest: hitTestResultSchema,
4122
- target: opensteerResolvedTargetSchema
4123
- },
4124
- {
4125
- title: "OpensteerComputerTracePoint",
4126
- required: ["role", "point"]
4127
- }
4128
- );
4129
- var opensteerComputerTraceEnrichmentSchema = objectSchema(
4130
- {
4131
- points: arraySchema(opensteerComputerTracePointSchema)
4132
- },
4133
- {
4134
- title: "OpensteerComputerTraceEnrichment",
4135
- required: ["points"]
4136
- }
4137
- );
4138
- var opensteerComputerExecuteTimingSchema = objectSchema(
4139
- {
4140
- actionMs: integerSchema({ minimum: 0 }),
4141
- waitMs: integerSchema({ minimum: 0 }),
4142
- totalMs: integerSchema({ minimum: 0 })
4143
- },
4144
- {
4145
- title: "OpensteerComputerExecuteTiming",
4146
- required: ["actionMs", "waitMs", "totalMs"]
4147
- }
4148
- );
4149
- var opensteerComputerDisplayScaleSchema = objectSchema(
4108
+ var opensteerScreenshotSummarySchema = objectSchema(
4150
4109
  {
4151
- x: numberSchema({ exclusiveMinimum: 0 }),
4152
- y: numberSchema({ exclusiveMinimum: 0 })
4110
+ payload: externalBinaryLocationSchema,
4111
+ format: screenshotFormatSchema,
4112
+ size: sizeSchema,
4113
+ coordinateSpace: coordinateSpaceSchema,
4114
+ clip: rectSchema
4153
4115
  },
4154
4116
  {
4155
- title: "OpensteerComputerDisplayScale",
4156
- required: ["x", "y"]
4117
+ title: "OpensteerScreenshotSummary",
4118
+ required: ["payload", "format", "size", "coordinateSpace"]
4157
4119
  }
4158
4120
  );
4159
4121
  var opensteerComputerExecuteOutputSchema = objectSchema(
4160
4122
  {
4161
- action: opensteerComputerActionSchema,
4162
- pageRef: pageRefSchema,
4163
- screenshot: screenshotArtifactSchema,
4164
- displayViewport: viewportMetricsSchema,
4165
- nativeViewport: viewportMetricsSchema,
4166
- displayScale: opensteerComputerDisplayScaleSchema,
4167
- events: arraySchema(opensteerEventSchema),
4168
- timing: opensteerComputerExecuteTimingSchema,
4169
- trace: opensteerComputerTraceEnrichmentSchema
4123
+ url: stringSchema(),
4124
+ title: stringSchema(),
4125
+ screenshot: opensteerScreenshotSummarySchema
4170
4126
  },
4171
4127
  {
4172
4128
  title: "OpensteerComputerExecuteOutput",
4173
- required: [
4174
- "action",
4175
- "pageRef",
4176
- "screenshot",
4177
- "displayViewport",
4178
- "nativeViewport",
4179
- "displayScale",
4180
- "events",
4181
- "timing"
4182
- ]
4129
+ required: ["url", "title", "screenshot"]
4183
4130
  }
4184
4131
  );
4185
4132
  function assertValidSemanticOperationInput(name, input) {
@@ -4205,7 +4152,7 @@ var opensteerSemanticOperationSpecificationsBase = [
4205
4152
  name: "session.open",
4206
4153
  description: "Open or resume the current Opensteer session and primary page.",
4207
4154
  inputSchema: opensteerOpenInputSchema,
4208
- outputSchema: opensteerSessionStateSchema,
4155
+ outputSchema: opensteerNavigationSummarySchema,
4209
4156
  requiredCapabilities: ["sessions.manage", "pages.manage"],
4210
4157
  resolveRequiredCapabilities: (input) => input.url === void 0 ? ["sessions.manage", "pages.manage"] : ["sessions.manage", "pages.manage", "pages.navigate"]
4211
4158
  }),
@@ -4220,7 +4167,7 @@ var opensteerSemanticOperationSpecificationsBase = [
4220
4167
  name: "page.new",
4221
4168
  description: "Create and optionally navigate a new top-level page in the current session.",
4222
4169
  inputSchema: opensteerPageNewInputSchema,
4223
- outputSchema: opensteerSessionStateSchema,
4170
+ outputSchema: opensteerPageNewOutputSchema,
4224
4171
  requiredCapabilities: ["pages.manage"],
4225
4172
  resolveRequiredCapabilities: (input) => input.url === void 0 ? ["pages.manage"] : ["pages.manage", "pages.navigate"]
4226
4173
  }),
@@ -4228,7 +4175,7 @@ var opensteerSemanticOperationSpecificationsBase = [
4228
4175
  name: "page.activate",
4229
4176
  description: "Activate an existing top-level page in the current session.",
4230
4177
  inputSchema: opensteerPageActivateInputSchema,
4231
- outputSchema: opensteerSessionStateSchema,
4178
+ outputSchema: opensteerNavigationSummarySchema,
4232
4179
  requiredCapabilities: ["pages.manage", "inspect.pages"]
4233
4180
  }),
4234
4181
  defineSemanticOperationSpec({
@@ -4242,7 +4189,7 @@ var opensteerSemanticOperationSpecificationsBase = [
4242
4189
  name: "page.goto",
4243
4190
  description: "Navigate the current Opensteer page to a new URL.",
4244
4191
  inputSchema: opensteerPageGotoInputSchema,
4245
- outputSchema: opensteerSessionStateSchema,
4192
+ outputSchema: opensteerNavigationSummarySchema,
4246
4193
  requiredCapabilities: ["pages.navigate"]
4247
4194
  }),
4248
4195
  defineSemanticOperationSpec({
@@ -6498,7 +6445,7 @@ var DomActionExecutor = class {
6498
6445
  ...snapshot === void 0 ? {} : { snapshot },
6499
6446
  signal: timeout.signal,
6500
6447
  remainingMs: () => timeout.remainingMs(),
6501
- policySettle: async (targetPageRef, trigger) => {
6448
+ policySettle: async (targetPageRef, trigger, boundary2) => {
6502
6449
  try {
6503
6450
  await settleWithPolicy(this.options.policy.settle, {
6504
6451
  operation,
@@ -6506,7 +6453,9 @@ var DomActionExecutor = class {
6506
6453
  engine: this.options.engine,
6507
6454
  pageRef: targetPageRef,
6508
6455
  signal: timeout.signal,
6509
- remainingMs: timeout.remainingMs()
6456
+ remainingMs: timeout.remainingMs(),
6457
+ ...boundary2?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary2.observedMutationQuietMs },
6458
+ ...boundary2?.postLoadHandled === true ? { postLoadHandled: true } : {}
6510
6459
  });
6511
6460
  } catch (error) {
6512
6461
  if (snapshot !== void 0 && isSoftSettleTimeoutError(error, timeout.signal)) {
@@ -10487,7 +10436,7 @@ async function dispatchSemanticOperation(runtime, operation, input, options = {}
10487
10436
 
10488
10437
  // ../runtime-core/package.json
10489
10438
  var package_default = {
10490
- version: "0.2.5"};
10439
+ version: "0.2.6"};
10491
10440
 
10492
10441
  // ../runtime-core/src/version.ts
10493
10442
  var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
@@ -10758,12 +10707,16 @@ function toOpensteerResolvedTarget(target) {
10758
10707
  documentRef: target.documentRef,
10759
10708
  documentEpoch: target.documentEpoch,
10760
10709
  nodeRef: target.nodeRef,
10761
- tagName: target.node.nodeName.toUpperCase(),
10710
+ tagName: toOpensteerTagName(target.node.nodeName),
10762
10711
  pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
10763
10712
  ...target.persist === void 0 ? {} : { persist: target.persist },
10764
10713
  ...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
10765
10714
  };
10766
10715
  }
10716
+ function toOpensteerTagName(nodeName) {
10717
+ const tagName = String(nodeName).trim().toLowerCase();
10718
+ return tagName.length === 0 ? "element" : tagName;
10719
+ }
10767
10720
 
10768
10721
  // ../runtime-core/src/runtimes/computer-use/runtime.ts
10769
10722
  function createComputerUseRuntime(options) {
@@ -10797,7 +10750,7 @@ var DefaultComputerUseRuntime = class {
10797
10750
  screenshot,
10798
10751
  signal: input.timeout.signal,
10799
10752
  remainingMs: () => input.timeout.remainingMs(),
10800
- policySettle: async (pageRef, trigger) => {
10753
+ policySettle: async (pageRef, trigger, boundary) => {
10801
10754
  try {
10802
10755
  await settleWithPolicy(this.options.policy.settle, {
10803
10756
  operation: "computer.execute",
@@ -10805,7 +10758,9 @@ var DefaultComputerUseRuntime = class {
10805
10758
  engine: this.options.engine,
10806
10759
  pageRef,
10807
10760
  signal: input.timeout.signal,
10808
- remainingMs: input.timeout.remainingMs()
10761
+ remainingMs: input.timeout.remainingMs(),
10762
+ ...boundary?.observedMutationQuietMs === void 0 ? {} : { observedMutationQuietMs: boundary.observedMutationQuietMs },
10763
+ ...boundary?.postLoadHandled === true ? { postLoadHandled: true } : {}
10809
10764
  });
10810
10765
  } catch (error) {
10811
10766
  if (pageRef === input.pageRef && isSoftSettleTimeoutError(error, input.timeout.signal)) {
@@ -11983,28 +11938,24 @@ function restoreBoundedAttr(el, attr, value) {
11983
11938
  }
11984
11939
  setBoundedAttr(el, attr, value);
11985
11940
  }
11986
- function deduplicateImages(html) {
11941
+ function deduplicateImagesInDom($) {
11987
11942
  const seen = /* @__PURE__ */ new Set();
11988
- return html.replace(/<img\b([^>]*)>/gi, (full, attrContent) => {
11989
- if (/\bc\s*=/.test(attrContent)) {
11990
- return full;
11991
- }
11992
- const srcMatch = attrContent.match(/\bsrc\s*=\s*(["']?)(.*?)\1/);
11993
- const srcsetMatch = attrContent.match(/\bsrcset\s*=\s*(["'])(.*?)\1/);
11994
- let src = null;
11995
- if (srcMatch && srcMatch[2]) {
11996
- src = srcMatch[2].trim();
11997
- } else if (srcsetMatch && srcsetMatch[2]) {
11998
- src = srcsetMatch[2].split(",")[0]?.trim().split(" ")[0] ?? null;
11943
+ $("img").each(function deduplicateDomImage() {
11944
+ const el = $(this);
11945
+ if (el.attr("c") !== void 0) {
11946
+ return;
11999
11947
  }
11948
+ const srcValue = el.attr("src")?.trim();
11949
+ const srcsetValue = el.attr("srcset");
11950
+ const src = srcValue && srcValue.length > 0 ? srcValue : srcsetValue?.split(",")[0]?.trim().split(/\s+/u)[0];
12000
11951
  if (!src) {
12001
- return full;
11952
+ return;
12002
11953
  }
12003
11954
  if (seen.has(src)) {
12004
- return "";
11955
+ el.remove();
11956
+ return;
12005
11957
  }
12006
11958
  seen.add(src);
12007
- return full;
12008
11959
  });
12009
11960
  }
12010
11961
  function hasAttribute2(node, attr) {
@@ -12062,23 +12013,6 @@ function isPreservedImageElement(node) {
12062
12013
  function getElementsInReverseDocumentOrder($) {
12063
12014
  return $.root().find("*").toArray().reverse().filter((node) => node.type === "tag");
12064
12015
  }
12065
- function getNodeDepth(node) {
12066
- let depth = 0;
12067
- let current = node.parent;
12068
- while (current) {
12069
- depth++;
12070
- current = current.parent;
12071
- }
12072
- return depth;
12073
- }
12074
- function getElementsByDepthDescending($) {
12075
- const elements = $.root().find("*").toArray().filter((node) => node.type === "tag");
12076
- const depths = /* @__PURE__ */ new Map();
12077
- for (const el of elements) {
12078
- depths.set(el, getNodeDepth(el));
12079
- }
12080
- return elements.sort((a, b) => (depths.get(b) ?? 0) - (depths.get(a) ?? 0));
12081
- }
12082
12016
  function flattenExtractionTree($) {
12083
12017
  for (const node of getElementsInReverseDocumentOrder($)) {
12084
12018
  const el = $(node);
@@ -12096,19 +12030,6 @@ function flattenExtractionTree($) {
12096
12030
  el.replaceWith(el.contents());
12097
12031
  }
12098
12032
  }
12099
- function hasMarkedAncestor(el, attr) {
12100
- let current = el[0]?.parent;
12101
- while (current) {
12102
- if (!isElementLikeNode(current)) {
12103
- return false;
12104
- }
12105
- if (current.attribs?.[attr] !== void 0) {
12106
- return true;
12107
- }
12108
- current = current.parent;
12109
- }
12110
- return false;
12111
- }
12112
12033
  function isIndicatorImage(node) {
12113
12034
  return (node?.tagName || "").toLowerCase() === "img" && (hasAttribute2(node, "alt") || hasAttribute2(node, "src") || hasAttribute2(node, "srcset"));
12114
12035
  }
@@ -12226,7 +12147,7 @@ function serializeForExtraction($, root) {
12226
12147
  traverse(root, 0);
12227
12148
  return lines.map((l) => l.trim()).filter((l) => l.length > 0).join("");
12228
12149
  }
12229
- function isClickable($, el, context) {
12150
+ function isClickable(el, context) {
12230
12151
  if (context.hasPreMarked) {
12231
12152
  return el.attr(OPENSTEER_INTERACTIVE_ATTR) !== void 0;
12232
12153
  }
@@ -12260,21 +12181,17 @@ function isClickable($, el, context) {
12260
12181
  }
12261
12182
  return false;
12262
12183
  }
12263
- function cleanForExtraction(html) {
12184
+ function prepareExtractionSnapshotDom(html) {
12264
12185
  if (!html.trim()) {
12265
- return "";
12186
+ return void 0;
12266
12187
  }
12267
12188
  const $ = cheerio.load(html, { xmlMode: false });
12268
12189
  removeNoise($);
12269
12190
  removeComments($);
12270
12191
  markInlineSelfHiddenFallback($);
12271
12192
  pruneSelfHiddenNodes($);
12272
- const $clean = cheerio.load(
12273
- $.html().replace(/\n{2,}/g, "\n").trim(),
12274
- { xmlMode: false }
12275
- );
12276
- $clean("*").each(function stripAndRestoreExtractionAttrs() {
12277
- const el = $clean(this);
12193
+ $("*").each(function stripAndRestoreExtractionAttrs() {
12194
+ const el = $(this);
12278
12195
  const node = el[0];
12279
12196
  if (!node) {
12280
12197
  return;
@@ -12315,16 +12232,20 @@ function cleanForExtraction(html) {
12315
12232
  restoreBoundedAttr(el, "href", hrefValue);
12316
12233
  }
12317
12234
  });
12318
- flattenExtractionTree($clean);
12319
- const root = $clean.root()[0];
12235
+ flattenExtractionTree($);
12236
+ deduplicateImagesInDom($);
12237
+ return $;
12238
+ }
12239
+ function serializePreparedExtractionSnapshot($) {
12240
+ const root = $.root()[0];
12320
12241
  if (root === void 0) {
12321
12242
  return "";
12322
12243
  }
12323
- return deduplicateImages(serializeForExtraction($clean, root));
12244
+ return serializeForExtraction($, root);
12324
12245
  }
12325
- function cleanForAction(html) {
12246
+ function prepareActionSnapshotDom(html) {
12326
12247
  if (!html.trim()) {
12327
- return "";
12248
+ return void 0;
12328
12249
  }
12329
12250
  const $ = cheerio.load(html, { xmlMode: false });
12330
12251
  removeNoise($);
@@ -12333,13 +12254,12 @@ function cleanForAction(html) {
12333
12254
  pruneSelfHiddenNodes($);
12334
12255
  const clickableMark = "data-clickable-marker";
12335
12256
  const indicatorMark = "data-keep-indicator";
12336
- const branchMark = "data-keep-branch";
12337
12257
  const context = {
12338
12258
  hasPreMarked: $(`[${OPENSTEER_INTERACTIVE_ATTR}]`).length > 0
12339
12259
  };
12340
12260
  $("*").each(function markClickables() {
12341
12261
  const el = $(this);
12342
- if (isClickable($, el, context)) {
12262
+ if (isClickable(el, context)) {
12343
12263
  el.attr(clickableMark, "1");
12344
12264
  }
12345
12265
  });
@@ -12369,25 +12289,7 @@ function cleanForAction(html) {
12369
12289
  el.remove();
12370
12290
  }
12371
12291
  });
12372
- $(`[${clickableMark}], [${indicatorMark}]`).each(function markBranches() {
12373
- let current = $(this).parent();
12374
- while (current.length > 0) {
12375
- const node = current[0];
12376
- if (!node || node.type !== "tag") {
12377
- break;
12378
- }
12379
- const ancestor = current;
12380
- const tag = (node.tagName || "").toLowerCase();
12381
- if (ROOT_TAGS.has(tag) || ancestor.attr(clickableMark) !== void 0) {
12382
- break;
12383
- }
12384
- if (!isBoundaryTag(tag)) {
12385
- ancestor.attr(branchMark, "1");
12386
- }
12387
- current = ancestor.parent();
12388
- }
12389
- });
12390
- for (const node of getElementsByDepthDescending($)) {
12292
+ for (const node of getElementsInReverseDocumentOrder($)) {
12391
12293
  const el = $(node);
12392
12294
  const tag = (node.tagName || "").toLowerCase();
12393
12295
  if (ROOT_TAGS.has(tag) || isBoundaryTag(tag)) {
@@ -12396,17 +12298,7 @@ function cleanForAction(html) {
12396
12298
  if (el.attr(clickableMark) !== void 0 || el.attr(indicatorMark) !== void 0) {
12397
12299
  continue;
12398
12300
  }
12399
- const insideClickable = hasMarkedAncestor(el, clickableMark);
12400
- const preserveBranch = el.attr(branchMark) !== void 0;
12401
12301
  const hasContent = hasElementChildren(node) || hasDirectText(node);
12402
- if (insideClickable || preserveBranch) {
12403
- if (!hasContent) {
12404
- el.remove();
12405
- } else {
12406
- unwrapActionNode($, el);
12407
- }
12408
- continue;
12409
- }
12410
12302
  if (!hasContent) {
12411
12303
  el.remove();
12412
12304
  continue;
@@ -12507,13 +12399,20 @@ function cleanForAction(html) {
12507
12399
  }
12508
12400
  el.removeAttr(clickableMark);
12509
12401
  el.removeAttr(indicatorMark);
12510
- el.removeAttr(branchMark);
12511
12402
  el.removeAttr(OPENSTEER_INTERACTIVE_ATTR);
12512
12403
  el.removeAttr(OPENSTEER_HIDDEN_ATTR);
12513
12404
  el.removeAttr(OPENSTEER_SCROLLABLE_ATTR);
12514
12405
  el.removeAttr(OPENSTEER_SELF_HIDDEN_ATTR);
12515
12406
  });
12516
- return compactHtml(deduplicateImages($.html()));
12407
+ deduplicateImagesInDom($);
12408
+ return $;
12409
+ }
12410
+ function serializePreparedActionSnapshot($) {
12411
+ const normalized = compactHtml($.html());
12412
+ if (normalized.length === 0) {
12413
+ return "";
12414
+ }
12415
+ return cheerio.load(normalized, { xmlMode: false }).html();
12517
12416
  }
12518
12417
  var VOID_TAGS2 = /* @__PURE__ */ new Set([
12519
12418
  "area",
@@ -12736,27 +12635,32 @@ async function markLiveSnapshotSemantics(options) {
12736
12635
  const frames = await options.engine.listFrames({
12737
12636
  pageRef: options.pageRef
12738
12637
  });
12739
- for (const frame of frames) {
12740
- await evaluateFrameBestEffort(
12741
- options.engine,
12742
- frame.frameRef,
12743
- MARK_SNAPSHOT_SEMANTICS_SCRIPT,
12744
- SNAPSHOT_SEMANTIC_ARGS
12745
- );
12746
- }
12747
- return async () => {
12748
- for (const frame of frames) {
12749
- await evaluateFrameBestEffort(
12638
+ await Promise.all(
12639
+ frames.map(
12640
+ (frame) => evaluateFrameBestEffort(
12750
12641
  options.engine,
12751
12642
  frame.frameRef,
12752
- CLEAR_SNAPSHOT_SEMANTICS_SCRIPT,
12753
- CLEAR_SNAPSHOT_SEMANTIC_ARGS
12754
- );
12755
- }
12643
+ MARK_SNAPSHOT_SEMANTICS_SCRIPT,
12644
+ SNAPSHOT_SEMANTIC_ARGS
12645
+ )
12646
+ )
12647
+ );
12648
+ return async () => {
12649
+ await Promise.all(
12650
+ frames.map(
12651
+ (frame) => evaluateFrameBestEffort(
12652
+ options.engine,
12653
+ frame.frameRef,
12654
+ CLEAR_SNAPSHOT_SEMANTICS_SCRIPT,
12655
+ CLEAR_SNAPSHOT_SEMANTIC_ARGS
12656
+ )
12657
+ )
12658
+ );
12756
12659
  };
12757
12660
  }
12758
12661
 
12759
12662
  // ../runtime-core/src/sdk/snapshot/compiler.ts
12663
+ var EXTRACTION_SKIPPED_COUNTER_TAGS = /* @__PURE__ */ new Set(["html", "head", "body"]);
12760
12664
  var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
12761
12665
  "c",
12762
12666
  OPENSTEER_BOUNDARY_ATTR,
@@ -12771,7 +12675,7 @@ var INTERNAL_SNAPSHOT_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
12771
12675
  var MAX_LIVE_COUNTER_SYNC_ATTEMPTS = 4;
12772
12676
  var CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
12773
12677
  const walk = (root) => {
12774
- for (const child of root.children) {
12678
+ for (const child of Array.from(root?.children || [])) {
12775
12679
  child.removeAttribute("c");
12776
12680
  child.removeAttribute(sparseCounterAttr);
12777
12681
  walk(child);
@@ -12787,7 +12691,7 @@ var CLEAR_LIVE_COUNTERS_SCRIPT = `(({ sparseCounterAttr }) => {
12787
12691
  var ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
12788
12692
  let counter = startCounter;
12789
12693
  const walk = (root) => {
12790
- for (const child of root.children) {
12694
+ for (const child of Array.from(root?.children || [])) {
12791
12695
  child.setAttribute(sparseCounterAttr, String(counter++));
12792
12696
  walk(child);
12793
12697
  if (child.shadowRoot) {
@@ -12801,7 +12705,7 @@ var ASSIGN_SPARSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, startCounter }) => {
12801
12705
  })`;
12802
12706
  var APPLY_DENSE_COUNTERS_SCRIPT = `(({ sparseCounterAttr, mapping }) => {
12803
12707
  const walk = (root) => {
12804
- for (const child of root.children) {
12708
+ for (const child of Array.from(root?.children || [])) {
12805
12709
  child.removeAttribute("c");
12806
12710
  const sparse = child.getAttribute(sparseCounterAttr);
12807
12711
  if (sparse !== null) {
@@ -12864,20 +12768,22 @@ function ensureSparseCountersForAllRecords(counterRecords) {
12864
12768
  async function clearOpensteerLiveCounters(engine, pageRef) {
12865
12769
  const frames = await engine.listFrames({ pageRef });
12866
12770
  const failures = [];
12867
- for (const frame of frames) {
12868
- try {
12869
- await engine.evaluateFrame({
12870
- frameRef: frame.frameRef,
12871
- script: CLEAR_LIVE_COUNTERS_SCRIPT,
12872
- args: [{ sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR }]
12873
- });
12874
- } catch (error) {
12875
- if (isDetachedFrameSyncError(error)) {
12876
- continue;
12771
+ await Promise.all(
12772
+ frames.map(async (frame) => {
12773
+ try {
12774
+ await engine.evaluateFrame({
12775
+ frameRef: frame.frameRef,
12776
+ script: CLEAR_LIVE_COUNTERS_SCRIPT,
12777
+ args: [{ sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR }]
12778
+ });
12779
+ } catch (error) {
12780
+ if (isDetachedFrameSyncError(error)) {
12781
+ return;
12782
+ }
12783
+ failures.push(`frame ${frame.frameRef} could not be cleared (${describeError(error)}).`);
12877
12784
  }
12878
- failures.push(`frame ${frame.frameRef} could not be cleared (${describeError(error)}).`);
12879
- }
12880
- }
12785
+ })
12786
+ );
12881
12787
  if (failures.length > 0) {
12882
12788
  throw buildLiveCounterSyncError("clear live counters", failures);
12883
12789
  }
@@ -12926,25 +12832,29 @@ async function syncDenseCountersToLiveDom(engine, pageRef, sparseToDirectMapping
12926
12832
  denseCounter
12927
12833
  ])
12928
12834
  );
12929
- for (const frame of frames) {
12930
- try {
12931
- await engine.evaluateFrame({
12932
- frameRef: frame.frameRef,
12933
- script: APPLY_DENSE_COUNTERS_SCRIPT,
12934
- args: [
12935
- {
12936
- sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR,
12937
- mapping: mappingObj
12938
- }
12939
- ]
12940
- });
12941
- } catch (error) {
12942
- if (isDetachedFrameSyncError(error)) {
12943
- continue;
12835
+ await Promise.all(
12836
+ frames.map(async (frame) => {
12837
+ try {
12838
+ await engine.evaluateFrame({
12839
+ frameRef: frame.frameRef,
12840
+ script: APPLY_DENSE_COUNTERS_SCRIPT,
12841
+ args: [
12842
+ {
12843
+ sparseCounterAttr: OPENSTEER_SPARSE_COUNTER_ATTR,
12844
+ mapping: mappingObj
12845
+ }
12846
+ ]
12847
+ });
12848
+ } catch (error) {
12849
+ if (isDetachedFrameSyncError(error)) {
12850
+ return;
12851
+ }
12852
+ failures.push(
12853
+ `frame ${frame.frameRef} could not be synchronized (${describeError(error)}).`
12854
+ );
12944
12855
  }
12945
- failures.push(`frame ${frame.frameRef} could not be synchronized (${describeError(error)}).`);
12946
- }
12947
- }
12856
+ })
12857
+ );
12948
12858
  if (failures.length > 0) {
12949
12859
  throw buildLiveCounterSyncError("synchronize dense counters", failures);
12950
12860
  }
@@ -12962,26 +12872,26 @@ async function compileOpensteerSnapshot(options) {
12962
12872
  await clearOpensteerLiveCounters(options.engine, options.pageRef);
12963
12873
  await assignSparseCountersToLiveDom(options.engine, options.pageRef);
12964
12874
  const pageInfo = await options.engine.getPageInfo({ pageRef: options.pageRef });
12965
- const mainSnapshot = await getMainDocumentSnapshot(options.engine, options.pageRef);
12966
- const snapshotsByDocumentRef = await collectDocumentSnapshots(options.engine, mainSnapshot);
12875
+ const { mainSnapshot, snapshotsByDocumentRef } = await getPageDocumentSnapshots(
12876
+ options.engine,
12877
+ options.pageRef
12878
+ );
12967
12879
  await cleanupLiveSemantics();
12968
12880
  cleanupLiveSemantics = async () => {
12969
12881
  };
12970
- const snapshotIndices = /* @__PURE__ */ new Map();
12971
12882
  const renderedNodes = /* @__PURE__ */ new Map();
12972
12883
  const rawHtml = renderDocumentSnapshot(
12973
12884
  mainSnapshot.documentRef,
12974
12885
  snapshotsByDocumentRef,
12975
- snapshotIndices,
12976
12886
  renderedNodes,
12977
12887
  {
12978
12888
  iframeDepth: 0,
12979
12889
  shadowDepth: 0
12980
12890
  }
12981
12891
  );
12982
- const cleanedHtml = options.mode === "extraction" ? cleanForExtraction(rawHtml) : cleanForAction(rawHtml);
12983
- const compiledHtml = assignCounters(cleanedHtml, renderedNodes);
12984
- const finalHtml = options.mode === "extraction" ? unwrapExtractionHtml(compiledHtml.html) : compiledHtml.html;
12892
+ const preparedSnapshotDom = options.mode === "extraction" ? prepareExtractionSnapshotDom(rawHtml) : prepareActionSnapshotDom(rawHtml);
12893
+ const compiledHtml = assignCountersInDom(preparedSnapshotDom, renderedNodes, options.mode);
12894
+ const finalHtml = preparedSnapshotDom === void 0 ? "" : options.mode === "extraction" ? serializePreparedExtractionSnapshot(preparedSnapshotDom) : serializePreparedActionSnapshot(preparedSnapshotDom);
12985
12895
  ensureSparseCountersForAllRecords(compiledHtml.counterRecords);
12986
12896
  await syncDenseCountersToLiveDom(
12987
12897
  options.engine,
@@ -13016,6 +12926,25 @@ async function getMainDocumentSnapshot(engine, pageRef) {
13016
12926
  }
13017
12927
  return engine.getDomSnapshot({ frameRef: mainFrame.frameRef });
13018
12928
  }
12929
+ async function getPageDocumentSnapshots(engine, pageRef) {
12930
+ const bundleEngine = engine;
12931
+ const bundledSnapshots = await bundleEngine.getPageDomSnapshots?.({ pageRef });
12932
+ if (bundledSnapshots && bundledSnapshots.length > 0) {
12933
+ const mainSnapshot2 = bundledSnapshots.find((snapshot) => snapshot.parentDocumentRef === void 0) ?? bundledSnapshots[0];
12934
+ return {
12935
+ mainSnapshot: mainSnapshot2,
12936
+ snapshotsByDocumentRef: new Map(
12937
+ bundledSnapshots.map((snapshot) => [snapshot.documentRef, snapshot])
12938
+ )
12939
+ };
12940
+ }
12941
+ const mainSnapshot = await getMainDocumentSnapshot(engine, pageRef);
12942
+ const snapshotsByDocumentRef = await collectDocumentSnapshots(engine, mainSnapshot);
12943
+ return {
12944
+ mainSnapshot,
12945
+ snapshotsByDocumentRef
12946
+ };
12947
+ }
13019
12948
  async function collectDocumentSnapshots(engine, mainSnapshot) {
13020
12949
  const snapshotsByDocumentRef = /* @__PURE__ */ new Map([
13021
12950
  [mainSnapshot.documentRef, mainSnapshot]
@@ -13034,7 +12963,7 @@ async function collectDocumentSnapshots(engine, mainSnapshot) {
13034
12963
  }
13035
12964
  return snapshotsByDocumentRef;
13036
12965
  }
13037
- function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, snapshotIndices, renderedNodes, depth) {
12966
+ function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, renderedNodes, depth) {
13038
12967
  const snapshot = snapshotsByDocumentRef.get(documentRef);
13039
12968
  if (!snapshot) {
13040
12969
  return "";
@@ -13046,17 +12975,9 @@ function renderDocumentSnapshot(documentRef, snapshotsByDocumentRef, snapshotInd
13046
12975
  `snapshot ${snapshot.documentRef} is missing root node ${String(snapshot.rootSnapshotNodeId)}`
13047
12976
  );
13048
12977
  }
13049
- return renderNode(
13050
- snapshot,
13051
- rootNode,
13052
- nodesById,
13053
- snapshotsByDocumentRef,
13054
- snapshotIndices,
13055
- renderedNodes,
13056
- depth
13057
- );
12978
+ return renderNode(snapshot, rootNode, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
13058
12979
  }
13059
- function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotIndices, renderedNodes, depth) {
12980
+ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
13060
12981
  if (node.nodeType === 3) {
13061
12982
  return escapeHtml(node.nodeValue || node.textContent || "");
13062
12983
  }
@@ -13064,56 +12985,26 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
13064
12985
  return "";
13065
12986
  }
13066
12987
  if (node.nodeType === 9 || node.nodeType === 11) {
13067
- return renderChildren(
13068
- snapshot,
13069
- node,
13070
- nodesById,
13071
- snapshotsByDocumentRef,
13072
- snapshotIndices,
13073
- renderedNodes,
13074
- depth
13075
- );
12988
+ return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
13076
12989
  }
13077
12990
  if (node.nodeType !== 1) {
13078
- return renderChildren(
13079
- snapshot,
13080
- node,
13081
- nodesById,
13082
- snapshotsByDocumentRef,
13083
- snapshotIndices,
13084
- renderedNodes,
13085
- depth
13086
- );
12991
+ return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
13087
12992
  }
13088
12993
  const tagName = normalizeTagName(node.nodeName);
13089
12994
  if (isPseudoElementTagName(tagName)) {
13090
- return renderChildren(
13091
- snapshot,
13092
- node,
13093
- nodesById,
13094
- snapshotsByDocumentRef,
13095
- snapshotIndices,
13096
- renderedNodes,
13097
- depth
13098
- );
12995
+ return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
13099
12996
  }
13100
12997
  if ((depth.iframeDepth > 0 || depth.shadowDepth > 0) && (tagName === "html" || tagName === "head" || tagName === "body")) {
13101
- return renderChildren(
13102
- snapshot,
13103
- node,
13104
- nodesById,
13105
- snapshotsByDocumentRef,
13106
- snapshotIndices,
13107
- renderedNodes,
13108
- depth
13109
- );
12998
+ return renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth);
13110
12999
  }
13111
13000
  const snapshotAttributes = normalizeNodeAttributes(node.attributes);
13001
+ const snapshotAttributeIndex = indexNodeAttributes(snapshotAttributes);
13112
13002
  const authoredAttributes = stripInternalSnapshotAttributes(snapshotAttributes);
13003
+ const authoredAttributeIndex = indexNodeAttributes(authoredAttributes);
13113
13004
  const attributes = [...authoredAttributes];
13114
- const subtreeHidden = hasAttribute3(snapshotAttributes, OPENSTEER_HIDDEN_ATTR) || isLikelySubtreeHidden(node);
13115
- const selfHidden = !subtreeHidden && (hasAttribute3(snapshotAttributes, OPENSTEER_SELF_HIDDEN_ATTR) || isLikelySelfHidden(node, nodesById));
13116
- const interactive = !subtreeHidden && !selfHidden && (hasAttribute3(snapshotAttributes, OPENSTEER_INTERACTIVE_ATTR) || isLikelyInteractive(tagName, node, authoredAttributes));
13005
+ const subtreeHidden = snapshotAttributeIndex.has(OPENSTEER_HIDDEN_ATTR) || isLikelySubtreeHidden(node);
13006
+ const selfHidden = !subtreeHidden && (snapshotAttributeIndex.has(OPENSTEER_SELF_HIDDEN_ATTR) || isLikelySelfHidden(node, nodesById));
13007
+ const interactive = !subtreeHidden && !selfHidden && (snapshotAttributeIndex.has(OPENSTEER_INTERACTIVE_ATTR) || isLikelyInteractive(tagName, node, authoredAttributes, authoredAttributeIndex));
13117
13008
  if (interactive) {
13118
13009
  attributes.push({ name: OPENSTEER_INTERACTIVE_ATTR, value: "1" });
13119
13010
  }
@@ -13122,7 +13013,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
13122
13013
  } else if (selfHidden) {
13123
13014
  attributes.push({ name: OPENSTEER_SELF_HIDDEN_ATTR, value: "1" });
13124
13015
  }
13125
- const sparseCounter = findAttributeValue(snapshotAttributes, OPENSTEER_SPARSE_COUNTER_ATTR);
13016
+ const sparseCounter = snapshotAttributeIndex.get(OPENSTEER_SPARSE_COUNTER_ATTR);
13126
13017
  if (sparseCounter !== void 0) {
13127
13018
  attributes.push({ name: OPENSTEER_SPARSE_COUNTER_ATTR, value: sparseCounter });
13128
13019
  }
@@ -13133,21 +13024,18 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
13133
13024
  const syntheticNodeId = buildSyntheticNodeId(snapshot, node);
13134
13025
  attributes.push({ name: OPENSTEER_NODE_ID_ATTR, value: syntheticNodeId });
13135
13026
  renderedNodes.set(syntheticNodeId, {
13136
- locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
13137
- anchor: buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices),
13138
13027
  pageRef: snapshot.pageRef,
13139
13028
  frameRef: snapshot.frameRef,
13140
13029
  documentRef: snapshot.documentRef,
13141
13030
  documentEpoch: snapshot.documentEpoch,
13142
13031
  nodeRef: node.nodeRef,
13143
13032
  tagName: tagName.toUpperCase(),
13144
- pathHint: buildPathHint(tagName, authoredAttributes),
13145
- ...buildTextSnippet(node.textContent) === void 0 ? {} : { text: buildTextSnippet(node.textContent) },
13146
13033
  ...authoredAttributes.length === 0 ? {} : { attributes: authoredAttributes },
13147
13034
  iframeDepth: depth.iframeDepth,
13148
13035
  shadowDepth: depth.shadowDepth,
13149
13036
  interactive,
13150
- liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById)
13037
+ liveCounterSyncEligible: isLiveCounterSyncEligible(node, nodesById),
13038
+ ...node.textContent === void 0 ? {} : { textContent: node.textContent }
13151
13039
  });
13152
13040
  }
13153
13041
  const attributeText = attributesToHtml(attributes);
@@ -13156,7 +13044,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
13156
13044
  node,
13157
13045
  nodesById,
13158
13046
  snapshotsByDocumentRef,
13159
- snapshotIndices,
13160
13047
  renderedNodes,
13161
13048
  depth
13162
13049
  );
@@ -13167,7 +13054,6 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
13167
13054
  const iframeHtml = renderDocumentSnapshot(
13168
13055
  node.contentDocumentRef,
13169
13056
  snapshotsByDocumentRef,
13170
- snapshotIndices,
13171
13057
  renderedNodes,
13172
13058
  {
13173
13059
  iframeDepth: depth.iframeDepth + 1,
@@ -13179,7 +13065,7 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
13179
13065
  }
13180
13066
  return `${elementHtml}<${OPENSTEER_IFRAME_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="iframe">${iframeHtml}</${OPENSTEER_IFRAME_BOUNDARY_TAG}>`;
13181
13067
  }
13182
- function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotIndices, renderedNodes, depth) {
13068
+ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, renderedNodes, depth) {
13183
13069
  const regularChildren = [];
13184
13070
  const shadowChildren = [];
13185
13071
  for (const childSnapshotNodeId of node.childSnapshotNodeIds) {
@@ -13196,18 +13082,10 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
13196
13082
  const chunks = [];
13197
13083
  if (shadowChildren.length > 0) {
13198
13084
  const shadowHtml = shadowChildren.map(
13199
- (child) => renderNode(
13200
- snapshot,
13201
- child,
13202
- nodesById,
13203
- snapshotsByDocumentRef,
13204
- snapshotIndices,
13205
- renderedNodes,
13206
- {
13207
- iframeDepth: depth.iframeDepth,
13208
- shadowDepth: depth.shadowDepth + 1
13209
- }
13210
- )
13085
+ (child) => renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, {
13086
+ iframeDepth: depth.iframeDepth,
13087
+ shadowDepth: depth.shadowDepth + 1
13088
+ })
13211
13089
  ).join("");
13212
13090
  chunks.push(
13213
13091
  `<${OPENSTEER_SHADOW_BOUNDARY_TAG} ${OPENSTEER_BOUNDARY_ATTR}="shadow">${shadowHtml}</${OPENSTEER_SHADOW_BOUNDARY_TAG}>`
@@ -13215,24 +13093,21 @@ function renderChildren(snapshot, node, nodesById, snapshotsByDocumentRef, snaps
13215
13093
  }
13216
13094
  for (const child of regularChildren) {
13217
13095
  chunks.push(
13218
- renderNode(
13219
- snapshot,
13220
- child,
13221
- nodesById,
13222
- snapshotsByDocumentRef,
13223
- snapshotIndices,
13224
- renderedNodes,
13225
- depth
13226
- )
13096
+ renderNode(snapshot, child, nodesById, snapshotsByDocumentRef, renderedNodes, depth)
13227
13097
  );
13228
13098
  }
13229
13099
  return chunks.join("");
13230
13100
  }
13231
- function assignCounters(cleanedHtml, renderedNodes) {
13232
- const $ = cheerio.load(cleanedHtml, { xmlMode: false });
13101
+ function assignCountersInDom($, renderedNodes, mode) {
13233
13102
  const counterRecords = /* @__PURE__ */ new Map();
13234
13103
  const sparseToDirectMapping = /* @__PURE__ */ new Map();
13235
13104
  let nextCounter = 1;
13105
+ if (!$) {
13106
+ return {
13107
+ counterRecords,
13108
+ sparseToDirectMapping
13109
+ };
13110
+ }
13236
13111
  $("*").each(function assignElementCounter() {
13237
13112
  const el = $(this);
13238
13113
  const syntheticNodeId = el.attr(OPENSTEER_NODE_ID_ATTR);
@@ -13244,14 +13119,24 @@ function assignCounters(cleanedHtml, renderedNodes) {
13244
13119
  if (!rendered) {
13245
13120
  return;
13246
13121
  }
13122
+ if (mode === "extraction" && EXTRACTION_SKIPPED_COUNTER_TAGS.has(rendered.tagName.toLowerCase())) {
13123
+ el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
13124
+ return;
13125
+ }
13247
13126
  const rawSparseCounter = el.attr(OPENSTEER_SPARSE_COUNTER_ATTR);
13248
13127
  el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
13249
13128
  const sparseCounter = rawSparseCounter ? Number.parseInt(rawSparseCounter, 10) : void 0;
13129
+ const replayableSparseCounter = typeof sparseCounter === "number" && Number.isFinite(sparseCounter) ? sparseCounter : void 0;
13130
+ if (rendered.liveCounterSyncEligible && replayableSparseCounter === void 0) {
13131
+ return;
13132
+ }
13250
13133
  const counter = nextCounter++;
13251
13134
  el.attr("c", String(counter));
13252
- if (sparseCounter !== void 0 && Number.isFinite(sparseCounter)) {
13253
- sparseToDirectMapping.set(sparseCounter, counter);
13135
+ if (replayableSparseCounter !== void 0) {
13136
+ sparseToDirectMapping.set(replayableSparseCounter, counter);
13254
13137
  }
13138
+ const pathHint = buildPathHint(rendered.tagName.toLowerCase(), rendered.attributes ?? []);
13139
+ const text = buildTextSnippet(rendered.textContent);
13255
13140
  counterRecords.set(counter, {
13256
13141
  element: counter,
13257
13142
  pageRef: rendered.pageRef,
@@ -13260,20 +13145,17 @@ function assignCounters(cleanedHtml, renderedNodes) {
13260
13145
  documentEpoch: rendered.documentEpoch,
13261
13146
  nodeRef: rendered.nodeRef,
13262
13147
  tagName: rendered.tagName,
13263
- pathHint: rendered.pathHint,
13264
- ...rendered.text === void 0 ? {} : { text: rendered.text },
13148
+ pathHint,
13149
+ ...text === void 0 ? {} : { text },
13265
13150
  ...rendered.attributes === void 0 ? {} : { attributes: rendered.attributes },
13266
13151
  iframeDepth: rendered.iframeDepth,
13267
13152
  shadowDepth: rendered.shadowDepth,
13268
13153
  interactive: rendered.interactive,
13269
13154
  liveCounterSyncEligible: rendered.liveCounterSyncEligible,
13270
- locator: rendered.locator,
13271
- anchor: rendered.anchor,
13272
- ...sparseCounter !== void 0 && Number.isFinite(sparseCounter) ? { sparseCounter } : {}
13155
+ ...replayableSparseCounter === void 0 ? {} : { sparseCounter: replayableSparseCounter }
13273
13156
  });
13274
13157
  });
13275
13158
  return {
13276
- html: $.html(),
13277
13159
  counterRecords,
13278
13160
  sparseToDirectMapping
13279
13161
  };
@@ -13347,28 +13229,28 @@ function isLikelySelfHidden(node, nodesById) {
13347
13229
  }
13348
13230
  return !hasVisibleOutOfFlowChild(node, nodesById);
13349
13231
  }
13350
- function isLikelyInteractive(tagName, node, attributes) {
13232
+ function isLikelyInteractive(tagName, node, attributes, attributeIndex) {
13351
13233
  if (NATIVE_INTERACTIVE_TAGS.has(tagName)) {
13352
- if (tagName === "input" && findAttributeValue(attributes, "type")?.toLowerCase() === "hidden") {
13234
+ if (tagName === "input" && attributeIndex.get("type")?.toLowerCase() === "hidden") {
13353
13235
  return false;
13354
13236
  }
13355
13237
  if (tagName !== "a") {
13356
13238
  return true;
13357
13239
  }
13358
13240
  }
13359
- if (tagName === "a" && findAttributeValue(attributes, "href") !== void 0) {
13241
+ if (tagName === "a" && attributeIndex.has("href")) {
13360
13242
  return true;
13361
13243
  }
13362
- if (findAttributeValue(attributes, "onclick") !== void 0 || findAttributeValue(attributes, "onmousedown") !== void 0 || findAttributeValue(attributes, "onmouseup") !== void 0 || findAttributeValue(attributes, "data-action") !== void 0 || findAttributeValue(attributes, "data-click") !== void 0 || findAttributeValue(attributes, "data-toggle") !== void 0) {
13244
+ if (attributeIndex.has("onclick") || attributeIndex.has("onmousedown") || attributeIndex.has("onmouseup") || attributeIndex.has("data-action") || attributeIndex.has("data-click") || attributeIndex.has("data-toggle")) {
13363
13245
  return true;
13364
13246
  }
13365
- if (hasNonNegativeTabIndex(findAttributeValue(attributes, "tabindex"))) {
13247
+ if (hasNonNegativeTabIndex(attributeIndex.get("tabindex"))) {
13366
13248
  return true;
13367
13249
  }
13368
- if (findAttributeValue(attributes, "contenteditable")?.toLowerCase() === "true") {
13250
+ if (attributeIndex.get("contenteditable")?.toLowerCase() === "true") {
13369
13251
  return true;
13370
13252
  }
13371
- const role = findAttributeValue(attributes, "role")?.toLowerCase();
13253
+ const role = attributeIndex.get("role")?.toLowerCase();
13372
13254
  return role !== void 0 && INTERACTIVE_ROLE_SET.has(role);
13373
13255
  }
13374
13256
  function hasVisibleOutOfFlowChild(node, nodesById) {
@@ -13431,14 +13313,6 @@ function parseOpacity(value) {
13431
13313
  const parsed = Number.parseFloat(value);
13432
13314
  return Number.isFinite(parsed) ? parsed : Number.NaN;
13433
13315
  }
13434
- function hasAttribute3(attributes, name) {
13435
- const normalizedName = name.toLowerCase();
13436
- return attributes.some((attribute) => attribute.name.toLowerCase() === normalizedName);
13437
- }
13438
- function unwrapExtractionHtml(html) {
13439
- const $ = cheerio.load(html, { xmlMode: false });
13440
- return $("body").html()?.trim() || html;
13441
- }
13442
13316
  function buildSyntheticNodeId(snapshot, node) {
13443
13317
  return `${snapshot.documentRef}:${String(snapshot.documentEpoch)}:${String(node.snapshotNodeId)}`;
13444
13318
  }
@@ -13485,6 +13359,13 @@ function findAttributeValue(attributes, name) {
13485
13359
  const normalizedName = name.toLowerCase();
13486
13360
  return attributes.find((attribute) => attribute.name.toLowerCase() === normalizedName)?.value;
13487
13361
  }
13362
+ function indexNodeAttributes(attributes) {
13363
+ const indexed = /* @__PURE__ */ new Map();
13364
+ for (const attribute of attributes) {
13365
+ indexed.set(attribute.name.toLowerCase(), attribute.value);
13366
+ }
13367
+ return indexed;
13368
+ }
13488
13369
  function attributesToHtml(attributes) {
13489
13370
  if (attributes.length === 0) {
13490
13371
  return "";
@@ -13494,56 +13375,6 @@ function attributesToHtml(attributes) {
13494
13375
  function escapeAttribute(value) {
13495
13376
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
13496
13377
  }
13497
- function buildSnapshotElementAnchor(snapshot, node, snapshotsByDocumentRef, snapshotIndices) {
13498
- const index = getSnapshotIndex(snapshot.documentRef, snapshotsByDocumentRef, snapshotIndices);
13499
- const localAnchor = buildLocalStructuralElementAnchor(index, node);
13500
- return prefixIframeContext(snapshot, localAnchor, snapshotsByDocumentRef, snapshotIndices);
13501
- }
13502
- function prefixIframeContext(snapshot, localPath, snapshotsByDocumentRef, snapshotIndices) {
13503
- if (snapshot.parentDocumentRef === void 0) {
13504
- return sanitizeStructuralElementAnchor(localPath);
13505
- }
13506
- const parentSnapshot = snapshotsByDocumentRef.get(snapshot.parentDocumentRef);
13507
- if (!parentSnapshot) {
13508
- throw new Error(
13509
- `document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no parent snapshot`
13510
- );
13511
- }
13512
- const parentIndex = getSnapshotIndex(
13513
- parentSnapshot.documentRef,
13514
- snapshotsByDocumentRef,
13515
- snapshotIndices
13516
- );
13517
- const iframeHost = findIframeHostNode(parentIndex, snapshot.documentRef);
13518
- if (!iframeHost) {
13519
- throw new Error(
13520
- `document ${snapshot.documentRef} has parent ${snapshot.parentDocumentRef} but no iframe host`
13521
- );
13522
- }
13523
- const hostPath = buildSnapshotElementAnchor(
13524
- parentSnapshot,
13525
- iframeHost,
13526
- snapshotsByDocumentRef,
13527
- snapshotIndices
13528
- );
13529
- return sanitizeStructuralElementAnchor({
13530
- context: [...hostPath.context, { kind: "iframe", host: hostPath.nodes }, ...localPath.context],
13531
- nodes: localPath.nodes
13532
- });
13533
- }
13534
- function getSnapshotIndex(documentRef, snapshotsByDocumentRef, snapshotIndices) {
13535
- const existing = snapshotIndices.get(documentRef);
13536
- if (existing) {
13537
- return existing;
13538
- }
13539
- const snapshot = snapshotsByDocumentRef.get(documentRef);
13540
- if (!snapshot) {
13541
- throw new Error(`missing DOM snapshot for ${documentRef}`);
13542
- }
13543
- const index = createSnapshotIndex(snapshot);
13544
- snapshotIndices.set(documentRef, index);
13545
- return index;
13546
- }
13547
13378
  function escapeHtml(value) {
13548
13379
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
13549
13380
  }
@@ -14756,7 +14587,7 @@ var OpensteerSessionRuntime = class {
14756
14587
  options
14757
14588
  );
14758
14589
  }
14759
- return this.readSessionState();
14590
+ return this.readNavigationSummary();
14760
14591
  }
14761
14592
  const startedAt = Date.now();
14762
14593
  const root = await this.ensureRoot();
@@ -14777,7 +14608,8 @@ var OpensteerSessionRuntime = class {
14777
14608
  openedSessionRef = sessionRef;
14778
14609
  const createdPage = await timeout.runStep(
14779
14610
  () => engine.createPage({
14780
- sessionRef
14611
+ sessionRef,
14612
+ ...input.url === void 0 ? {} : { url: input.url }
14781
14613
  })
14782
14614
  );
14783
14615
  openedPageRef = createdPage.data.pageRef;
@@ -14787,18 +14619,19 @@ var OpensteerSessionRuntime = class {
14787
14619
  await timeout.runStep(() => this.ensureSemantics());
14788
14620
  let frameRef2 = createdPage.frameRef;
14789
14621
  if (input.url !== void 0) {
14790
- const navigation = await this.navigatePage(
14791
- {
14622
+ await timeout.runStep(
14623
+ () => settleWithPolicy(this.policy.settle, {
14792
14624
  operation: "session.open",
14625
+ trigger: "navigation",
14626
+ engine: this.requireEngine(),
14793
14627
  pageRef: createdPage.data.pageRef,
14794
- url: input.url
14795
- },
14796
- timeout
14628
+ signal: timeout.signal,
14629
+ remainingMs: timeout.remainingMs()
14630
+ })
14797
14631
  );
14798
- frameRef2 = navigation.data.mainFrame.frameRef;
14799
14632
  }
14800
14633
  return {
14801
- state: await timeout.runStep(() => this.readSessionState()),
14634
+ state: await timeout.runStep(() => this.readNavigationSummary()),
14802
14635
  frameRef: frameRef2
14803
14636
  };
14804
14637
  },
@@ -14891,7 +14724,11 @@ var OpensteerSessionRuntime = class {
14891
14724
  "page.new cannot use openerPageRef before a session exists"
14892
14725
  );
14893
14726
  }
14894
- return this.open(input.url === void 0 ? {} : { url: input.url }, options);
14727
+ const summary = await this.open(input.url === void 0 ? {} : { url: input.url }, options);
14728
+ return {
14729
+ pageRef: await this.ensurePageRef(),
14730
+ ...summary
14731
+ };
14895
14732
  }
14896
14733
  const startedAt = Date.now();
14897
14734
  try {
@@ -14906,7 +14743,7 @@ var OpensteerSessionRuntime = class {
14906
14743
  })
14907
14744
  );
14908
14745
  this.pageRef = created.data.pageRef;
14909
- return this.readSessionState();
14746
+ return this.readCreatedPageOutput(created.data.pageRef);
14910
14747
  },
14911
14748
  options
14912
14749
  );
@@ -14948,7 +14785,7 @@ var OpensteerSessionRuntime = class {
14948
14785
  () => this.requireEngine().activatePage({ pageRef: input.pageRef })
14949
14786
  );
14950
14787
  this.pageRef = input.pageRef;
14951
- return this.readSessionState();
14788
+ return this.readNavigationSummary(input.pageRef);
14952
14789
  },
14953
14790
  options
14954
14791
  );
@@ -15074,7 +14911,7 @@ var OpensteerSessionRuntime = class {
15074
14911
  timeout.throwIfAborted();
15075
14912
  return {
15076
14913
  navigation: navigation2,
15077
- state: await timeout.runStep(() => this.readSessionState())
14914
+ state: await timeout.runStep(() => this.readNavigationSummary(pageRef))
15078
14915
  };
15079
14916
  },
15080
14917
  (diagnostics) => {
@@ -16308,7 +16145,7 @@ var OpensteerSessionRuntime = class {
16308
16145
  let mutationCaptureDiagnostics;
16309
16146
  let boundaryDiagnostics;
16310
16147
  try {
16311
- const { artifacts, output } = await this.runMutationCapturedOperation(
16148
+ const { artifacts, output, result } = await this.runMutationCapturedOperation(
16312
16149
  "computer.execute",
16313
16150
  {
16314
16151
  ...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
@@ -16326,9 +16163,14 @@ var OpensteerSessionRuntime = class {
16326
16163
  await this.invalidateLiveSnapshotCounters([pageRef, output2.pageRef], timeout);
16327
16164
  this.pageRef = output2.pageRef;
16328
16165
  const artifacts2 = await this.persistComputerArtifacts(output2, timeout);
16166
+ const result2 = {
16167
+ ...await timeout.runStep(() => this.readNavigationSummary(output2.pageRef)),
16168
+ screenshot: artifacts2.screenshot
16169
+ };
16329
16170
  return {
16330
16171
  artifacts: { manifests: artifacts2.manifests },
16331
- output: artifacts2.output
16172
+ output: output2,
16173
+ result: result2
16332
16174
  };
16333
16175
  } catch (error) {
16334
16176
  boundaryDiagnostics ??= takeActionBoundaryDiagnostics(timeout.signal);
@@ -16365,7 +16207,7 @@ var OpensteerSessionRuntime = class {
16365
16207
  documentEpoch: output.screenshot.documentEpoch
16366
16208
  })
16367
16209
  });
16368
- return output;
16210
+ return result;
16369
16211
  } catch (error) {
16370
16212
  await this.appendTrace({
16371
16213
  operation: "computer.execute",
@@ -16513,8 +16355,9 @@ var OpensteerSessionRuntime = class {
16513
16355
  mutationCaptureDiagnostics = diagnostics;
16514
16356
  }
16515
16357
  );
16516
- const output = toOpensteerActionResult(executed.result);
16358
+ const output = toOpensteerActionResult(executed.result.resolved);
16517
16359
  const actionEvents = "events" in executed.result ? executed.result.events : void 0;
16360
+ const resolvedTarget = toOpensteerResolvedTarget2(executed.result.resolved);
16518
16361
  await this.appendTrace({
16519
16362
  operation,
16520
16363
  startedAt,
@@ -16522,8 +16365,13 @@ var OpensteerSessionRuntime = class {
16522
16365
  outcome: "ok",
16523
16366
  ...actionEvents === void 0 ? {} : { events: actionEvents },
16524
16367
  data: {
16525
- target: output.target,
16526
- ...output.point === void 0 ? {} : { point: output.point },
16368
+ target: resolvedTarget,
16369
+ ..."point" in executed.result && executed.result.point !== void 0 ? {
16370
+ point: {
16371
+ x: executed.result.point.x,
16372
+ y: executed.result.point.y
16373
+ }
16374
+ } : {},
16527
16375
  ...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
16528
16376
  ...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
16529
16377
  },
@@ -17988,20 +17836,20 @@ var OpensteerSessionRuntime = class {
17988
17836
  throw error;
17989
17837
  }
17990
17838
  }
17991
- async readSessionState() {
17992
- const pageRef = await this.ensurePageRef();
17839
+ async readNavigationSummary(targetPageRef) {
17840
+ const pageRef = targetPageRef ?? await this.ensurePageRef();
17993
17841
  const pageInfo = await this.requireEngine().getPageInfo({ pageRef });
17994
- const sessionRef = this.sessionRef;
17995
- if (!sessionRef) {
17996
- throw new Error("Opensteer session is not initialized");
17997
- }
17998
17842
  return {
17999
- sessionRef,
18000
- pageRef,
18001
17843
  url: pageInfo.url,
18002
17844
  title: pageInfo.title
18003
17845
  };
18004
17846
  }
17847
+ async readCreatedPageOutput(pageRef) {
17848
+ return {
17849
+ pageRef,
17850
+ ...await this.readNavigationSummary(pageRef)
17851
+ };
17852
+ }
18005
17853
  async captureSnapshotArtifacts(pageRef, options, timeout) {
18006
17854
  const root = this.requireRoot();
18007
17855
  const mainFrame = await timeout.runStep(() => getMainFrame(this.requireEngine(), pageRef));
@@ -18073,12 +17921,12 @@ var OpensteerSessionRuntime = class {
18073
17921
  const screenshotPayload = manifestToExternalBinaryLocation(root.rootPath, screenshotManifest);
18074
17922
  return {
18075
17923
  manifests,
18076
- output: {
18077
- ...output,
18078
- screenshot: {
18079
- ...output.screenshot,
18080
- payload: screenshotPayload
18081
- }
17924
+ screenshot: {
17925
+ payload: screenshotPayload,
17926
+ format: output.screenshot.format,
17927
+ size: output.screenshot.size,
17928
+ coordinateSpace: output.screenshot.coordinateSpace,
17929
+ ...output.screenshot.clip === void 0 ? {} : { clip: output.screenshot.clip }
18082
17930
  }
18083
17931
  };
18084
17932
  }
@@ -19601,15 +19449,10 @@ function normalizeNamespace2(value) {
19601
19449
  const normalized = String(value ?? "default").trim();
19602
19450
  return normalized.length === 0 ? "default" : normalized;
19603
19451
  }
19604
- function toOpensteerActionResult(result) {
19452
+ function toOpensteerActionResult(target) {
19605
19453
  return {
19606
- target: toOpensteerResolvedTarget2(result.resolved),
19607
- ...result.point === void 0 ? {} : {
19608
- point: {
19609
- x: result.point.x,
19610
- y: result.point.y
19611
- }
19612
- }
19454
+ tagName: toOpensteerTagName2(target.node.nodeName),
19455
+ ...target.persist === void 0 ? {} : { persist: target.persist }
19613
19456
  };
19614
19457
  }
19615
19458
  function toOpensteerResolvedTarget2(target) {
@@ -19619,12 +19462,16 @@ function toOpensteerResolvedTarget2(target) {
19619
19462
  documentRef: target.documentRef,
19620
19463
  documentEpoch: target.documentEpoch,
19621
19464
  nodeRef: target.nodeRef,
19622
- tagName: target.node.nodeName.toUpperCase(),
19465
+ tagName: toOpensteerTagName2(target.node.nodeName),
19623
19466
  pathHint: buildPathSelectorHint(target.replayPath ?? target.anchor),
19624
19467
  ...target.persist === void 0 ? {} : { persist: target.persist },
19625
19468
  ...target.selectorUsed === void 0 ? {} : { selectorUsed: target.selectorUsed }
19626
19469
  };
19627
19470
  }
19471
+ function toOpensteerTagName2(nodeName) {
19472
+ const tagName = String(nodeName).trim().toLowerCase();
19473
+ return tagName.length === 0 ? "element" : tagName;
19474
+ }
19628
19475
  function normalizeOpensteerError(error) {
19629
19476
  return normalizeThrownOpensteerError(error, "Unknown Opensteer runtime failure");
19630
19477
  }
@@ -21260,7 +21107,11 @@ function generateReplayScript(options) {
21260
21107
  ``,
21261
21108
  ...renderOpensteerBootstrap(replayTarget),
21262
21109
  ``,
21263
- `const ${initialPageId} = (await opensteer.open(${JSON.stringify(initialPages[0]?.initialUrl ?? "")})).pageRef;`,
21110
+ `await opensteer.open(${JSON.stringify(initialPages[0]?.initialUrl ?? "")});`,
21111
+ `const ${initialPageId} = (await opensteer.listPages()).activePageRef;`,
21112
+ `if (!${initialPageId}) {`,
21113
+ ` throw new Error("Opensteer did not report an active page after open().");`,
21114
+ `}`,
21264
21115
  `let activePageRef: string | undefined = ${initialPageId};`,
21265
21116
  ``,
21266
21117
  `async function ensureActive(pageRef: string): Promise<void> {`,
@@ -22774,5 +22625,5 @@ function createOpensteerSemanticRuntime(input = {}) {
22774
22625
  }
22775
22626
 
22776
22627
  export { CloudSessionProxy, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, FlowRecorderCollector, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OpensteerCloudClient, STABLE_PRIMARY_ATTR_KEYS, assertProviderSupportsEngine, buildArrayFieldPathCandidates, buildDomDescriptorKey, buildDomDescriptorPayload, buildDomDescriptorVersion, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createDomDescriptorStore, createDomRuntime, createOpensteerExtractionDescriptorStore, createOpensteerSemanticRuntime, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, dispatchSemanticOperation, generateReplayScript, hashDomDescriptorPersist, isBrowserCoreError, isCurrentUrlField, isValidCssAttributeKey, loadEnvironment, normalizeExtractedValue, normalizeOpensteerProviderMode, parseDomDescriptorRecord, parseExtractionDescriptorRecord, requireCloudAppBaseUrl, resolveCloudConfig, resolveDomActionBridge, resolveExtractedValueInContext, resolveOpensteerEnvironment, resolveOpensteerProvider, resolveOpensteerRuntimeConfig, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath };
22777
- //# sourceMappingURL=chunk-BVRIPCWA.js.map
22778
- //# sourceMappingURL=chunk-BVRIPCWA.js.map
22628
+ //# sourceMappingURL=chunk-3OHKIPBD.js.map
22629
+ //# sourceMappingURL=chunk-3OHKIPBD.js.map