@mercuryo-ai/agentbrowse 0.2.57 → 0.2.61

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 (100) hide show
  1. package/README.md +76 -57
  2. package/dist/browser-session-state.d.ts +39 -0
  3. package/dist/browser-session-state.d.ts.map +1 -1
  4. package/dist/browser-session-state.js +63 -1
  5. package/dist/command-name.js +1 -1
  6. package/dist/commands/act.d.ts.map +1 -1
  7. package/dist/commands/act.js +540 -528
  8. package/dist/commands/action-executor-helpers.d.ts.map +1 -1
  9. package/dist/commands/action-executor-helpers.js +10 -8
  10. package/dist/commands/attach.d.ts.map +1 -1
  11. package/dist/commands/attach.js +5 -10
  12. package/dist/commands/browser-connection-failure.d.ts +9 -0
  13. package/dist/commands/browser-connection-failure.d.ts.map +1 -0
  14. package/dist/commands/browser-connection-failure.js +15 -0
  15. package/dist/commands/browser-status.d.ts.map +1 -1
  16. package/dist/commands/browser-status.js +26 -30
  17. package/dist/commands/click-activation-policy.d.ts.map +1 -1
  18. package/dist/commands/click-activation-policy.js +6 -2
  19. package/dist/commands/close.d.ts.map +1 -1
  20. package/dist/commands/close.js +5 -0
  21. package/dist/commands/extract.d.ts.map +1 -1
  22. package/dist/commands/extract.js +147 -144
  23. package/dist/commands/launch.d.ts +0 -1
  24. package/dist/commands/launch.d.ts.map +1 -1
  25. package/dist/commands/launch.js +13 -16
  26. package/dist/commands/navigate.d.ts.map +1 -1
  27. package/dist/commands/navigate.js +79 -73
  28. package/dist/commands/observe-inventory.d.ts +6 -1
  29. package/dist/commands/observe-inventory.d.ts.map +1 -1
  30. package/dist/commands/observe-inventory.js +331 -8
  31. package/dist/commands/observe-persistence.d.ts.map +1 -1
  32. package/dist/commands/observe-persistence.js +2 -0
  33. package/dist/commands/observe-projection.d.ts +3 -2
  34. package/dist/commands/observe-projection.d.ts.map +1 -1
  35. package/dist/commands/observe-projection.js +1 -0
  36. package/dist/commands/observe-protected.d.ts +3 -1
  37. package/dist/commands/observe-protected.d.ts.map +1 -1
  38. package/dist/commands/observe-protected.js +23 -1
  39. package/dist/commands/observe-semantics.d.ts.map +1 -1
  40. package/dist/commands/observe-semantics.js +70 -0
  41. package/dist/commands/observe.d.ts +1 -0
  42. package/dist/commands/observe.d.ts.map +1 -1
  43. package/dist/commands/observe.js +260 -270
  44. package/dist/commands/screenshot.d.ts.map +1 -1
  45. package/dist/commands/screenshot.js +50 -64
  46. package/dist/control-semantics.d.ts.map +1 -1
  47. package/dist/control-semantics.js +5 -0
  48. package/dist/date-value-normalization.d.ts +16 -0
  49. package/dist/date-value-normalization.d.ts.map +1 -0
  50. package/dist/date-value-normalization.js +117 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +5 -24
  53. package/dist/library.d.ts +5 -1
  54. package/dist/library.d.ts.map +1 -1
  55. package/dist/library.js +4 -1
  56. package/dist/protected-fill.d.ts +3 -2
  57. package/dist/protected-fill.d.ts.map +1 -1
  58. package/dist/protected-fill.js +46 -7
  59. package/dist/runtime-protected-state.d.ts.map +1 -1
  60. package/dist/runtime-protected-state.js +8 -1
  61. package/dist/runtime-state.d.ts +11 -0
  62. package/dist/runtime-state.d.ts.map +1 -1
  63. package/dist/secrets/form-matcher.d.ts +1 -2
  64. package/dist/secrets/form-matcher.d.ts.map +1 -1
  65. package/dist/secrets/form-matcher.js +125 -119
  66. package/dist/secrets/matching-helpers.d.ts +13 -0
  67. package/dist/secrets/matching-helpers.d.ts.map +1 -0
  68. package/dist/secrets/matching-helpers.js +147 -0
  69. package/dist/secrets/observed-field-resolution.d.ts +43 -0
  70. package/dist/secrets/observed-field-resolution.d.ts.map +1 -0
  71. package/dist/secrets/observed-field-resolution.js +223 -0
  72. package/dist/secrets/protected-field-semantics.d.ts.map +1 -1
  73. package/dist/secrets/protected-field-semantics.js +3 -2
  74. package/dist/secrets/protected-fill.d.ts +3 -1
  75. package/dist/secrets/protected-fill.d.ts.map +1 -1
  76. package/dist/secrets/protected-fill.js +31 -0
  77. package/dist/secrets/protected-value-adapters.d.ts.map +1 -1
  78. package/dist/secrets/protected-value-adapters.js +14 -22
  79. package/dist/secrets/types.d.ts +3 -0
  80. package/dist/secrets/types.d.ts.map +1 -1
  81. package/dist/sticky-owner-host-entry.d.ts +2 -0
  82. package/dist/sticky-owner-host-entry.d.ts.map +1 -0
  83. package/dist/sticky-owner-host-entry.js +97 -0
  84. package/dist/sticky-owner.d.ts +15 -0
  85. package/dist/sticky-owner.d.ts.map +1 -0
  86. package/dist/sticky-owner.js +431 -0
  87. package/docs/README.md +15 -2
  88. package/docs/api-reference.md +13 -3
  89. package/docs/assistive-runtime.md +63 -7
  90. package/docs/configuration.md +48 -8
  91. package/docs/getting-started.md +42 -9
  92. package/docs/integration-checklist.md +8 -7
  93. package/docs/protected-fill.md +40 -7
  94. package/docs/testing.md +4 -3
  95. package/docs/troubleshooting.md +126 -36
  96. package/examples/README.md +9 -2
  97. package/package.json +8 -3
  98. package/dist/protected-fill-browser.d.ts +0 -22
  99. package/dist/protected-fill-browser.d.ts.map +0 -1
  100. package/dist/protected-fill-browser.js +0 -52
@@ -62,12 +62,22 @@ export function inferDirectionalControlFallbackFromEvidence(evidence) {
62
62
  }
63
63
  return undefined;
64
64
  }
65
+ export function sanitizeClassNameForStateInference(value) {
66
+ return (value ?? '')
67
+ .replace(/\s+/g, ' ')
68
+ .trim()
69
+ .toLowerCase()
70
+ .split(' ')
71
+ .filter(Boolean)
72
+ .filter((token) => !token.includes(':'))
73
+ .join(' ');
74
+ }
65
75
  export function inferDisabledStateFromSemanticEvidence(evidence) {
66
76
  const normalize = (value) => (value ?? '').replace(/\s+/g, ' ').trim().toLowerCase();
67
77
  const tagName = normalize(evidence.tagName);
68
78
  const role = normalize(evidence.role);
69
79
  const inputType = normalize(evidence.inputType);
70
- const className = normalize(evidence.className);
80
+ const className = sanitizeClassNameForStateInference(evidence.className);
71
81
  const nonClassBlob = [
72
82
  evidence.datasetText,
73
83
  evidence.dataState,
@@ -98,6 +108,7 @@ export function inferDisabledStateFromSemanticEvidence(evidence) {
98
108
  return disabledLikeRe.test(collectionOrButtonLike ? fullSemanticBlob : nonClassBlob);
99
109
  }
100
110
  const INFER_STRUCTURED_CELL_VARIANT_HELPER_SCRIPT = `const inferStructuredCellVariantFromEvidence = ${inferStructuredCellVariantFromEvidence.toString()};`;
111
+ const SANITIZE_CLASS_NAME_FOR_STATE_INFERENCE_HELPER_SCRIPT = `const sanitizeClassNameForStateInference = ${sanitizeClassNameForStateInference.toString()};`;
101
112
  const INFER_DISABLED_STATE_FROM_SEMANTIC_EVIDENCE_HELPER_SCRIPT = String.raw `
102
113
  const inferDisabledStateFromSemanticEvidence = (evidence) => {
103
114
  const normalizeDisabledSemanticValue = (value) =>
@@ -106,7 +117,7 @@ const INFER_DISABLED_STATE_FROM_SEMANTIC_EVIDENCE_HELPER_SCRIPT = String.raw `
106
117
  const tagName = normalizeDisabledSemanticValue(evidence?.tagName);
107
118
  const role = normalizeDisabledSemanticValue(evidence?.role);
108
119
  const inputType = normalizeDisabledSemanticValue(evidence?.inputType);
109
- const className = normalizeDisabledSemanticValue(evidence?.className);
120
+ const className = sanitizeClassNameForStateInference(evidence?.className);
110
121
  const nonClassBlob = [
111
122
  evidence?.datasetText,
112
123
  evidence?.dataState,
@@ -204,6 +215,10 @@ function applyInheritedDomTargetMetadata(target, options) {
204
215
  framePath: normalizedFramePath,
205
216
  frameUrl: normalizedFrameUrl,
206
217
  pageSignature: normalizedPageSignature,
218
+ pageFormSelector: target.pageFormSelector ??
219
+ (typeof options?.pageFormSelector === 'string' && options.pageFormSelector.trim().length > 0
220
+ ? options.pageFormSelector
221
+ : undefined),
207
222
  };
208
223
  }
209
224
  function enrichObservedTargetSemantics(target) {
@@ -405,11 +420,13 @@ async function collectDomTargetsFromDocument(context, options) {
405
420
  const inheritedFramePath = JSON.stringify(options?.framePath ?? []);
406
421
  const inheritedFrameUrl = JSON.stringify(options?.frameUrl ?? '');
407
422
  const inheritedPageSignature = JSON.stringify(options?.pageSignature ?? '');
423
+ const inheritedPageFormSelector = JSON.stringify(options?.pageFormSelector ?? '');
408
424
  const observedTargets = await context.evaluate(String.raw `(() => {
409
425
  const includeActivationAffordances = ${includeActivationAffordances ? 'true' : 'false'};
410
426
  const inheritedFramePath = ${inheritedFramePath};
411
427
  const inheritedFrameUrl = ${inheritedFrameUrl};
412
428
  const inheritedPageSignature = ${inheritedPageSignature};
429
+ const inheritedPageFormSelector = ${inheritedPageFormSelector};
413
430
  const domSignatureOf = (element) => {
414
431
  ${LOCATOR_DOM_SIGNATURE_SCRIPT}
415
432
  };
@@ -563,6 +580,7 @@ async function collectDomTargetsFromDocument(context, options) {
563
580
  ${TRANSPARENT_ACTIONABLE_CONTROL_HELPER_SCRIPT}
564
581
  ${OBSERVE_DOM_LABEL_CONTRACT_HELPER_SCRIPT}
565
582
  ${INFER_STRUCTURED_CELL_VARIANT_HELPER_SCRIPT}
583
+ ${SANITIZE_CLASS_NAME_FOR_STATE_INFERENCE_HELPER_SCRIPT}
566
584
  ${INFER_DISABLED_STATE_FROM_SEMANTIC_EVIDENCE_HELPER_SCRIPT}
567
585
  ${INFER_DIRECTIONAL_CONTROL_FALLBACK_HELPER_SCRIPT}
568
586
 
@@ -892,6 +910,152 @@ async function collectDomTargetsFromDocument(context, options) {
892
910
 
893
911
  const looseFieldLabelOf = (element) => observedLooseFieldLabelOf(element);
894
912
 
913
+ const controlledPopupSurfaceOf = (element) => {
914
+ const controlledId = element.getAttribute('aria-controls')?.trim();
915
+ if (!controlledId) {
916
+ return undefined;
917
+ }
918
+
919
+ const controlled = document.getElementById(controlledId);
920
+ return isHTMLElementNode(controlled) ? controlled : undefined;
921
+ };
922
+
923
+ const normalizeSelectionLabel = (value, explicitLabel) => {
924
+ const normalized = normalizeDescriptorText(value || '');
925
+ if (!isMeaningfulLabel(normalized)) {
926
+ return undefined;
927
+ }
928
+ if (normalized.length > 64) {
929
+ return undefined;
930
+ }
931
+ if (observedLooseActionTextRe.test(normalized)) {
932
+ return undefined;
933
+ }
934
+ if (explicitLabel && normalized.toLowerCase() === explicitLabel.toLowerCase()) {
935
+ return undefined;
936
+ }
937
+ return normalized;
938
+ };
939
+
940
+ const inlineSelectionLabelsOf = (element) => {
941
+ const explicitLabel = normalizeDescriptorText(explicitLabelOf(element) || '');
942
+ const labels = [];
943
+ const seen = new Set();
944
+ const anchors = [
945
+ composedParentElement(element),
946
+ composedParentElement(composedParentElement(element)),
947
+ ].filter(Boolean);
948
+
949
+ const pushLabel = (value) => {
950
+ const normalized = normalizeSelectionLabel(value, explicitLabel);
951
+ if (!normalized) {
952
+ return;
953
+ }
954
+ const key = normalized.toLowerCase();
955
+ if (seen.has(key)) {
956
+ return;
957
+ }
958
+ seen.add(key);
959
+ labels.push(normalized);
960
+ };
961
+
962
+ const collectCandidateLabels = (candidate, depth = 0) => {
963
+ if (!isHTMLElementNode(candidate)) {
964
+ return;
965
+ }
966
+ if (candidate === element || candidate.contains(element) || element.contains(candidate)) {
967
+ return;
968
+ }
969
+ if (candidate.getAttribute('aria-hidden')?.trim() === 'true') {
970
+ return;
971
+ }
972
+ if (observedMatchesSelector(candidate, observedLabelLikeSelector)) {
973
+ return;
974
+ }
975
+
976
+ const tag = candidate.tagName.toLowerCase();
977
+ if (['input', 'textarea', 'select', 'button', 'a', 'svg', 'img'].includes(tag)) {
978
+ return;
979
+ }
980
+
981
+ const visibleChildren = Array.from(candidate.children).filter(
982
+ (child) => isHTMLElementNode(child) && isVisible(child)
983
+ );
984
+ const candidateStyle = window.getComputedStyle(candidate);
985
+ const visibleOrTransparentGrouping =
986
+ isVisible(candidate) ||
987
+ (candidateStyle.display === 'contents' && visibleChildren.length > 0);
988
+ if (!visibleOrTransparentGrouping) {
989
+ return;
990
+ }
991
+ if (depth === 0 && visibleChildren.length > 1) {
992
+ for (const child of visibleChildren.slice(0, 6)) {
993
+ collectCandidateLabels(child, depth + 1);
994
+ }
995
+ return;
996
+ }
997
+
998
+ pushLabel(observedTextOf(candidate, element));
999
+ };
1000
+
1001
+ for (const anchor of anchors) {
1002
+ if (!isHTMLElementNode(anchor)) {
1003
+ continue;
1004
+ }
1005
+
1006
+ for (const child of Array.from(anchor.children).slice(0, 8)) {
1007
+ if (!isHTMLElementNode(child)) {
1008
+ continue;
1009
+ }
1010
+ if (!observedPrecedesElementInDocument(child, element)) {
1011
+ continue;
1012
+ }
1013
+ collectCandidateLabels(child);
1014
+ }
1015
+
1016
+ if (labels.length > 0) {
1017
+ break;
1018
+ }
1019
+ }
1020
+
1021
+ return labels;
1022
+ };
1023
+
1024
+ const selectionOf = (element) => {
1025
+ if (!isHTMLElementNode(element)) {
1026
+ return undefined;
1027
+ }
1028
+
1029
+ if (isHTMLSelectNode(element)) {
1030
+ const items = Array.from(element.selectedOptions)
1031
+ .map((option) => normalizeDescriptorText(option.textContent || option.value || ''))
1032
+ .filter((label) => isMeaningfulLabel(label))
1033
+ .map((label) => ({ label, selected: true }));
1034
+ if (items.length === 0) {
1035
+ return undefined;
1036
+ }
1037
+
1038
+ return {
1039
+ mode: element.multiple ? 'multiple' : 'single',
1040
+ items,
1041
+ };
1042
+ }
1043
+
1044
+ const inlineLabels = inlineSelectionLabelsOf(element);
1045
+ const controlledSurface = controlledPopupSurfaceOf(element);
1046
+ const ariaMultiSelectable =
1047
+ controlledSurface?.getAttribute('aria-multiselectable')?.trim() === 'true';
1048
+ const mode = inlineLabels.length > 1 || ariaMultiSelectable ? 'multiple' : undefined;
1049
+ if (!mode) {
1050
+ return undefined;
1051
+ }
1052
+
1053
+ return {
1054
+ mode,
1055
+ items: inlineLabels.map((label) => ({ label, selected: true })),
1056
+ };
1057
+ };
1058
+
895
1059
  const VALIDATION_TEXT_RE =
896
1060
  /(?:required|invalid|incorrect|too\s+(?:short|long)|must|error|format|please\s+(?:enter|select|choose|fill)|невер|ошиб|обязател|заполн|введите|укажите|выберите|долж|нужно|формат|цифр|символ)/i;
897
1061
 
@@ -1210,6 +1374,103 @@ async function collectDomTargetsFromDocument(context, options) {
1210
1374
  return Math.max(window.innerWidth || 0, 1) * Math.max(window.innerHeight || 0, 1);
1211
1375
  };
1212
1376
 
1377
+ const compactClickableCompanionTextOf = (element) => {
1378
+ const anchors = [
1379
+ composedParentElement(element),
1380
+ composedParentElement(composedParentElement(element)),
1381
+ ].filter(Boolean);
1382
+
1383
+ for (const anchor of anchors) {
1384
+ if (!isHTMLElementNode(anchor)) {
1385
+ continue;
1386
+ }
1387
+
1388
+ for (const child of Array.from(anchor.children).slice(0, 8)) {
1389
+ if (!isHTMLElementNode(child) || child === element) {
1390
+ continue;
1391
+ }
1392
+ if (child.contains(element) || element.contains(child) || !isVisible(child)) {
1393
+ continue;
1394
+ }
1395
+
1396
+ const tag = child.tagName.toLowerCase();
1397
+ if (['input', 'textarea', 'select', 'button', 'a', 'svg', 'img'].includes(tag)) {
1398
+ continue;
1399
+ }
1400
+
1401
+ const candidateText = normalizeDescriptorText(textOf(child));
1402
+ if (
1403
+ candidateText &&
1404
+ candidateText.length <= 64 &&
1405
+ !observedLooseActionTextRe.test(candidateText)
1406
+ ) {
1407
+ return candidateText;
1408
+ }
1409
+ }
1410
+ }
1411
+
1412
+ return undefined;
1413
+ };
1414
+
1415
+ const compactClickableItemOf = (element) => {
1416
+ const companionText = compactClickableCompanionTextOf(element);
1417
+ if (!companionText) {
1418
+ return undefined;
1419
+ }
1420
+
1421
+ let current = composedParentElement(element);
1422
+ let depth = 0;
1423
+ while (isHTMLElementNode(current) && depth < 2) {
1424
+ const currentText = normalizeDescriptorText(textOf(current, { container: true }));
1425
+ if (currentText && currentText.toLowerCase() === companionText.toLowerCase()) {
1426
+ return current;
1427
+ }
1428
+ current = composedParentElement(current);
1429
+ depth += 1;
1430
+ }
1431
+
1432
+ return undefined;
1433
+ };
1434
+
1435
+ const compactAffordanceIntentRe =
1436
+ /\b(remove|clear|close|delete|dismiss|cancel|minus|cross|убрать|удалить|очистить|закрыть)\b/i;
1437
+
1438
+ const isCompactGenericClickableAffordance = (element) => {
1439
+ if (!isHTMLElementNode(element)) return false;
1440
+ if (element.matches?.(selector)) return false;
1441
+ if (hasSemanticInteractiveAncestor(element)) return false;
1442
+
1443
+ const tag = element.tagName.toLowerCase();
1444
+ const associatedChoiceControl = associatedChoiceControlOf(element);
1445
+ if (['body', 'main', 'form'].includes(tag)) return false;
1446
+ if (tag === 'label' && !associatedChoiceControl) return false;
1447
+
1448
+ const style = window.getComputedStyle(element);
1449
+ if (style.pointerEvents === 'none') return false;
1450
+
1451
+ const explicitClick =
1452
+ element.hasAttribute('onclick') || typeof element.onclick === 'function';
1453
+ const cursorClick = style.cursor === 'pointer';
1454
+ if (!explicitClick && !cursorClick) return false;
1455
+
1456
+ const rect = element.getBoundingClientRect();
1457
+ const area = rect.width * rect.height;
1458
+ if (rect.width < 12 || rect.height < 12 || area < 120) return false;
1459
+ if (rect.width > 40 || rect.height > 40 || area > 1200) return false;
1460
+
1461
+ const intentText = normalizeDescriptorText(
1462
+ explicitLabelOf(element) ||
1463
+ element.getAttribute('title') ||
1464
+ element.getAttribute('aria-label') ||
1465
+ ''
1466
+ );
1467
+ if (!intentText || !compactAffordanceIntentRe.test(intentText)) {
1468
+ return false;
1469
+ }
1470
+
1471
+ return Boolean(compactClickableCompanionTextOf(element));
1472
+ };
1473
+
1213
1474
  const isBareFocusableClickTarget = (element) => {
1214
1475
  if (!isHTMLElementNode(element)) return false;
1215
1476
  if (!element.matches?.(selector)) return false;
@@ -1324,7 +1585,12 @@ async function collectDomTargetsFromDocument(context, options) {
1324
1585
  for (const candidate of descendants) {
1325
1586
  if (acc.length >= limit) break;
1326
1587
  if (!isHTMLElementNode(candidate) || seen.has(candidate)) continue;
1327
- if (!isGenericClickableElement(candidate)) continue;
1588
+ if (
1589
+ !isGenericClickableElement(candidate) &&
1590
+ !isCompactGenericClickableAffordance(candidate)
1591
+ ) {
1592
+ continue;
1593
+ }
1328
1594
  if (hasAcceptedGenericClickableAncestor(candidate, acc)) continue;
1329
1595
  seen.add(candidate);
1330
1596
  acc.push(candidate);
@@ -1885,7 +2151,7 @@ async function collectDomTargetsFromDocument(context, options) {
1885
2151
  states.hasSelection = true;
1886
2152
  }
1887
2153
 
1888
- const className = (element.getAttribute('class') || '').toLowerCase();
2154
+ const className = sanitizeClassNameForStateInference(element.getAttribute('class') || '');
1889
2155
  const dataset = Object.values(element.dataset || {})
1890
2156
  .join(' ')
1891
2157
  .toLowerCase();
@@ -2996,6 +3262,7 @@ async function collectDomTargetsFromDocument(context, options) {
2996
3262
  const visualSeatGrid = visualSeatGridMeta.get(element);
2997
3263
  const associatedChoiceControl = associatedChoiceControlOf(element);
2998
3264
  const genericClickable = isGenericClickableElement(element);
3265
+ const compactClickableAffordance = isCompactGenericClickableAffordance(element);
2999
3266
  const bareFocusableClickTarget = isBareFocusableClickTarget(element);
3000
3267
  const effectiveElement = element;
3001
3268
  const domSignature = domSignatureOf(effectiveElement);
@@ -3019,7 +3286,9 @@ async function collectDomTargetsFromDocument(context, options) {
3019
3286
  const container = containerOf(element);
3020
3287
  const landmark = composedClosest(element, contextSelector);
3021
3288
  const group = groupOf(element);
3022
- const item = itemOf(element);
3289
+ const item =
3290
+ (compactClickableAffordance ? compactClickableItemOf(element) : undefined) ||
3291
+ itemOf(element);
3023
3292
  const overlaySurface = composedClosest(element, overlaySurfaceSelector);
3024
3293
  const localSurface = localSurfaceCandidateOf(element);
3025
3294
  const selfSurface =
@@ -3038,6 +3307,7 @@ async function collectDomTargetsFromDocument(context, options) {
3038
3307
  );
3039
3308
  const fallbackLabel = directionalFallbackLabel || directFallbackLabel;
3040
3309
  const currentValue = popupCurrentValueOf(element);
3310
+ const selection = selectionOf(element);
3041
3311
  const role = inferRole(element) || inferRole(associatedChoiceControl);
3042
3312
  const surfaceKind = visualSeatGrid?.surfaceKind || surfaceKindOf(surface);
3043
3313
  const fallbackSurfaceLabel =
@@ -3055,9 +3325,12 @@ async function collectDomTargetsFromDocument(context, options) {
3055
3325
  fallbackLabel: visualSeatGrid?.label || fallbackLabel,
3056
3326
  interactionHint:
3057
3327
  visualSeatGrid?.interactionHint ||
3058
- (genericClickable || bareFocusableClickTarget ? 'click' : undefined),
3328
+ (genericClickable || compactClickableAffordance || bareFocusableClickTarget
3329
+ ? 'click'
3330
+ : undefined),
3059
3331
  role,
3060
3332
  currentValue: currentValue || undefined,
3333
+ selection: selection || undefined,
3061
3334
  text: textOf(element),
3062
3335
  placeholder: element.getAttribute('placeholder')?.trim() || undefined,
3063
3336
  inputName:
@@ -3095,6 +3368,7 @@ async function collectDomTargetsFromDocument(context, options) {
3095
3368
  controlsSurfaceSelector:
3096
3369
  selectorFromRelation(element, 'aria-controls') || selectorFromRelation(element, 'aria-owns'),
3097
3370
  formSelector: form ? buildSelector(form) : undefined,
3371
+ pageFormSelector: form ? buildSelector(form) : inheritedPageFormSelector || undefined,
3098
3372
  descendantInteractiveCount: element.querySelectorAll(selector).length,
3099
3373
  descendantEditableCount: element.querySelectorAll(
3100
3374
  'input:not([type="hidden"]), textarea, select, [contenteditable="true"]'
@@ -3260,6 +3534,7 @@ async function collectDomTargetsFromDocument(context, options) {
3260
3534
  framePath: options?.framePath,
3261
3535
  frameUrl: options?.frameUrl,
3262
3536
  pageSignature: options?.pageSignature,
3537
+ pageFormSelector: options?.pageFormSelector,
3263
3538
  })));
3264
3539
  }
3265
3540
  const FRAME_HOST_DESCRIPTOR_SCRIPT = String.raw `
@@ -3350,6 +3625,53 @@ const FRAME_HOST_DESCRIPTOR_SCRIPT = String.raw `
3350
3625
  ? {
3351
3626
  selector,
3352
3627
  userVisible: isUserVisible(element),
3628
+ pageFormSelector: (() => {
3629
+ const form = element.closest('form');
3630
+ if (!(form instanceof HTMLFormElement)) {
3631
+ return undefined;
3632
+ }
3633
+
3634
+ const buildSelector = (candidate) => {
3635
+ if (!(candidate instanceof HTMLElement)) {
3636
+ return undefined;
3637
+ }
3638
+
3639
+ if (candidate.id && isSelectorUniqueFor(candidate, '#' + cssEscape(candidate.id))) {
3640
+ return '#' + cssEscape(candidate.id);
3641
+ }
3642
+
3643
+ const path = [];
3644
+ let current = candidate;
3645
+ while (current && current.nodeType === Node.ELEMENT_NODE && path.length < 8) {
3646
+ const currentTag = current.tagName.toLowerCase();
3647
+ const parent = current.parentElement;
3648
+ const root = current.getRootNode?.();
3649
+ const siblingPool = parent
3650
+ ? Array.from(parent.children)
3651
+ : isShadowRootNode(root)
3652
+ ? Array.from(root.children)
3653
+ : [];
3654
+ const siblings = siblingPool.filter(
3655
+ (child) => child.tagName.toLowerCase() === currentTag
3656
+ );
3657
+ const index = siblings.indexOf(current) + 1;
3658
+ path.unshift(currentTag + ':nth-of-type(' + Math.max(index, 1) + ')');
3659
+ if (current.id) {
3660
+ break;
3661
+ }
3662
+ current = current.parentElement;
3663
+ }
3664
+
3665
+ if (path.length === 0) {
3666
+ return undefined;
3667
+ }
3668
+
3669
+ const structuralSelector = path.join(' > ');
3670
+ return isSelectorUniqueFor(candidate, structuralSelector) ? structuralSelector : undefined;
3671
+ };
3672
+
3673
+ return buildSelector(form);
3674
+ })(),
3353
3675
  }
3354
3676
  : null;
3355
3677
 
@@ -3497,7 +3819,7 @@ export async function collectDomTargets(page, options) {
3497
3819
  }
3498
3820
  const collected = [];
3499
3821
  const includeActivationAffordances = options?.includeActivationAffordances === true;
3500
- const walk = async (frame, framePath) => {
3822
+ const walk = async (frame, framePath, pageFormSelector) => {
3501
3823
  if (collected.length >= DOM_TARGET_COLLECTION_LIMIT) {
3502
3824
  return;
3503
3825
  }
@@ -3507,6 +3829,7 @@ export async function collectDomTargets(page, options) {
3507
3829
  pageSignature: topLevelPageSignature,
3508
3830
  framePath,
3509
3831
  frameUrl,
3832
+ pageFormSelector,
3510
3833
  }).catch(() => []);
3511
3834
  for (const target of targets) {
3512
3835
  if (collected.length >= DOM_TARGET_COLLECTION_LIMIT) {
@@ -3525,7 +3848,7 @@ export async function collectDomTargets(page, options) {
3525
3848
  if (!frameHost?.selector || !frameHost.userVisible) {
3526
3849
  continue;
3527
3850
  }
3528
- await walk(childFrame, [...(framePath ?? []), frameHost.selector]);
3851
+ await walk(childFrame, [...(framePath ?? []), frameHost.selector], frameHost.pageFormSelector ?? pageFormSelector);
3529
3852
  }
3530
3853
  };
3531
3854
  await walk(page.mainFrame());
@@ -1 +1 @@
1
- {"version":3,"file":"observe-persistence.d.ts","sourceRoot":"","sources":["../../src/commands/observe-persistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AASnD,OAAO,KAAK,EAAoB,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQhE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CA0F/B;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAC5C,OAAO,EAAE,gBAAgB,EAAE,GAC1B,IAAI,CAYN;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,OAAO,CAAC,EAAE;IACR,gBAAgB,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC;IACjE,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C,GACA;IACD,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAkEA;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,aAAa,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,GAC5D,IAAI,CAsBN;AAUD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAC5C,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACjD,cAAc,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAChD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,iBAAiB,EAAE,CAyDrB"}
1
+ {"version":3,"file":"observe-persistence.d.ts","sourceRoot":"","sources":["../../src/commands/observe-persistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AASnD,OAAO,KAAK,EAAoB,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQhE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CA4F/B;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAC5C,OAAO,EAAE,gBAAgB,EAAE,GAC1B,IAAI,CAYN;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,OAAO,CAAC,EAAE;IACR,gBAAgB,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC;IACjE,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C,GACA;IACD,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAkEA;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,aAAa,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,GAC5D,IAAI,CAsBN;AAUD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAC5C,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACjD,cAAc,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAChD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,iBAAiB,EAAE,CAyDrB"}
@@ -51,6 +51,7 @@ export function toDomDescriptor(pageRef, target, surfaceRefMap) {
51
51
  pageRef,
52
52
  framePath: target.framePath,
53
53
  frameUrl: target.frameUrl,
54
+ pageFormSelector: target.pageFormSelector,
54
55
  kind: target.kind,
55
56
  label: target.label ?? target.text ?? target.placeholder ?? target.title,
56
57
  displayLabel: target.displayLabel,
@@ -62,6 +63,7 @@ export function toDomDescriptor(pageRef, target, surfaceRefMap) {
62
63
  surfaceKind: target.surfaceKind,
63
64
  controlsSurfaceSelector: target.controlsSurfaceSelector,
64
65
  validation: target.validation,
66
+ selection: target.selection,
65
67
  locatorCandidates,
66
68
  semantics: target.role || target.label || target.states
67
69
  ? {
@@ -26,7 +26,7 @@ type ExpandWorkflowGraphTargetOptions = {
26
26
  selectedSurfaceIds?: ReadonlySet<string>;
27
27
  };
28
28
  export declare function expandWorkflowGraphTargets(allTargets: ReadonlyArray<DomObservedTarget>, selectedTargets: ReadonlyArray<DomObservedTarget>, options?: ExpandWorkflowGraphTargetOptions): DomObservedTarget[];
29
- export declare function compactTargets(targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability' | 'surfaceRef'>>): Array<{
29
+ export declare function compactTargets(targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'selection' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability' | 'surfaceRef'>>): Array<{
30
30
  ref: string;
31
31
  kind?: string;
32
32
  label?: string;
@@ -35,6 +35,7 @@ export declare function compactTargets(targets: ReadonlyArray<Pick<TargetDescrip
35
35
  inputName?: string;
36
36
  inputType?: string;
37
37
  autocomplete?: string;
38
+ selection?: TargetDescriptor['selection'];
38
39
  validation?: AgentFacingTargetValidationEvidence;
39
40
  context?: string;
40
41
  state?: Record<string, string | boolean | number>;
@@ -76,7 +77,7 @@ type BuildGroupedObserveScopesOptions = {
76
77
  pageRef: string;
77
78
  title?: string;
78
79
  scopes: ReadonlyArray<Pick<SurfaceDescriptor, 'ref' | 'kind' | 'label' | 'availability' | 'parentSurfaceRef' | 'childSurfaceRefs' | 'extractScopeLifetime'>>;
79
- targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability' | 'surfaceRef'>>;
80
+ targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'selection' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability' | 'surfaceRef'>>;
80
81
  };
81
82
  export declare function buildGroupedObserveScopes(options: BuildGroupedObserveScopesOptions): CompactObservedScope[];
82
83
  export declare function compactFillableForms(forms: ReadonlyArray<PersistedFillableForm>): Array<{
@@ -1 +1 @@
1
- {"version":3,"file":"observe-projection.d.ts","sourceRoot":"","sources":["../../src/commands/observe-projection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observe-projection.d.ts","sourceRoot":"","sources":["../../src/commands/observe-projection.ts"],"names":[],"mappings":"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"}
@@ -417,6 +417,7 @@ export function compactTargets(targets) {
417
417
  inputName: target.inputName,
418
418
  inputType: target.inputType,
419
419
  autocomplete: target.autocomplete,
420
+ selection: target.selection,
420
421
  validation: compactValidationEvidence(target.validation),
421
422
  context: summarizeContext(target.context),
422
423
  state: target.semantics?.states,
@@ -1,6 +1,8 @@
1
1
  import type { BrowseSession } from '../session.js';
2
2
  import { type TargetDescriptor } from '../runtime-state.js';
3
- export declare function persistProtectedFillableFormsForPage(session: BrowseSession, pageRef: string, pageUrl: string, targets: ReadonlyArray<TargetDescriptor>, observedAt: string): Promise<import("../secrets/types.js").PersistedFillableForm[]>;
3
+ export declare function persistProtectedFillableFormsForPage(session: BrowseSession, pageRef: string, pageUrl: string, targets: ReadonlyArray<TargetDescriptor>, observedAt: string, options?: {
4
+ previousPageUrl?: string;
5
+ }): Promise<import("../secrets/types.js").PersistedFillableForm[]>;
4
6
  export declare function markProtectedFillableFormsUnknownForPage(session: BrowseSession, pageRef: string): import("../secrets/types.js").PersistedFillableForm[];
5
7
  export declare function clearProtectedFillableFormsForPage(session: BrowseSession, pageRef: string): import("../secrets/types.js").PersistedFillableForm[];
6
8
  //# sourceMappingURL=observe-protected.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observe-protected.d.ts","sourceRoot":"","sources":["../../src/commands/observe-protected.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAgB9E,wBAAsB,oCAAoC,CACxD,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACxC,UAAU,EAAE,MAAM,kEAgBnB;AAED,wBAAgB,wCAAwC,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,yDAE/F;AAED,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,yDAEzF"}
1
+ {"version":3,"file":"observe-protected.d.ts","sourceRoot":"","sources":["../../src/commands/observe-protected.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAqC9E,wBAAsB,oCAAoC,CACxD,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACxC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,MAAM,CAAC;CACrB,kEAmBP;AAED,wBAAgB,wCAAwC,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,yDAE/F;AAED,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,yDAEzF"}
@@ -9,7 +9,26 @@ function tryResolveHost(pageUrl) {
9
9
  return null;
10
10
  }
11
11
  }
12
- export async function persistProtectedFillableFormsForPage(session, pageRef, pageUrl, targets, observedAt) {
12
+ function normalizeMeaningfulPageUrl(pageUrl) {
13
+ const trimmed = pageUrl?.trim();
14
+ if (!trimmed) {
15
+ return null;
16
+ }
17
+ try {
18
+ const url = new URL(trimmed);
19
+ url.hash = '';
20
+ return url.toString();
21
+ }
22
+ catch {
23
+ return trimmed;
24
+ }
25
+ }
26
+ function didMeaningfulPageUrlChange(previousPageUrl, pageUrl) {
27
+ const previous = normalizeMeaningfulPageUrl(previousPageUrl);
28
+ const current = normalizeMeaningfulPageUrl(pageUrl);
29
+ return previous !== null && current !== null && previous !== current;
30
+ }
31
+ export async function persistProtectedFillableFormsForPage(session, pageRef, pageUrl, targets, observedAt, options = {}) {
13
32
  const host = tryResolveHost(pageUrl);
14
33
  const catalog = host ? getSecretCatalog(session, host) : null;
15
34
  const matchedForms = await matchStoredSecretsToObservedTargets(pageRef, targets, catalog, {
@@ -17,6 +36,9 @@ export async function persistProtectedFillableFormsForPage(session, pageRef, pag
17
36
  session,
18
37
  });
19
38
  if (matchedForms.length === 0) {
39
+ if (didMeaningfulPageUrlChange(options.previousPageUrl, pageUrl)) {
40
+ return clearProtectedFillableFormsForPage(session, pageRef);
41
+ }
20
42
  return markFillableFormsUnknownForPage(session, pageRef);
21
43
  }
22
44
  return replaceFillableFormsForPage(session, pageRef, matchedForms, {
@@ -1 +1 @@
1
- {"version":3,"file":"observe-semantics.d.ts","sourceRoot":"","sources":["../../src/commands/observe-semantics.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAYjF;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CA6B7E;AAgBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAQ/E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAMnE;AA6OD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CA+BrB;AAqBD,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAuBrB;AAqGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,EAAE,CA0FjG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAsFrB"}
1
+ {"version":3,"file":"observe-semantics.d.ts","sourceRoot":"","sources":["../../src/commands/observe-semantics.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAYjF;AAgED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CA6B7E;AAgBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAQ/E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAMnE;AA6OD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CA+BrB;AAqBD,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAuBrB;AAqGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,EAAE,CAmHjG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAsFrB"}