@nuanu-ai/agentbrowse 0.2.43 → 0.2.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @nuanu-ai/agentbrowse
2
2
 
3
+ > **Building agent payments?**
4
+ >
5
+ > We’re building a system that helps AI agents complete payments safely.
6
+ >
7
+ > This package is currently published mainly because we’re still testing it
8
+ > ourselves, so if you’re reading this, you’re probably earlier than we
9
+ > expected.
10
+ >
11
+ > If you’re building a new agent system, or improving an existing one, we’d be
12
+ > glad to talk and can offer early access.
13
+ >
14
+ > Telegram: [@albertkai](https://t.me/albertkai)
15
+
3
16
  Browser automation CLI for AI agents.
4
17
 
5
18
  `agentbrowse` controls a CDP-reachable browser for external agents that need
@@ -1 +1 @@
1
- {"version":3,"file":"act.test-harness.d.ts","sourceRoot":"","sources":["../../src/commands/act.test-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AA6BvC,eAAO,MAAM,iCAAiC,EAAE,MAAgD,CAAC;AACjG,eAAO,MAAM,oBAAoB,EAAE,MAAmC,CAAC;AACvE,eAAO,MAAM,kBAAkB,EAAE,MAAiC,CAAC;AACnE,eAAO,MAAM,yBAAyB,EAAE,MAAwC,CAAC;AACjF,eAAO,MAAM,eAAe,EAAE,MAA8B,CAAC;AAC7D,eAAO,MAAM,iBAAiB,EAAE,MAAgC,CAAC;AACjE,eAAO,MAAM,cAAc,EAAE,MAA6B,CAAC;AAC3D,eAAO,MAAM,eAAe,EAAE,MAA8B,CAAC;AAC7D,eAAO,MAAM,oBAAoB,EAAE,MAAmC,CAAC;AAgCvE,eAAO,MAAQ,GAAG,+BAA6B,CAAC;AAEhD,wBAAgB,WAAW,IAAI,aAAa,CAW3C;AAED,wBAAgB,WAAW,CAAC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,GAAG,CA0JxE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,GAAG,GAAG,CAM7F;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAqB1C"}
1
+ {"version":3,"file":"act.test-harness.d.ts","sourceRoot":"","sources":["../../src/commands/act.test-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AA6BvC,eAAO,MAAM,iCAAiC,EAAE,MAAgD,CAAC;AACjG,eAAO,MAAM,oBAAoB,EAAE,MAAmC,CAAC;AACvE,eAAO,MAAM,kBAAkB,EAAE,MAAiC,CAAC;AACnE,eAAO,MAAM,yBAAyB,EAAE,MAAwC,CAAC;AACjF,eAAO,MAAM,eAAe,EAAE,MAA8B,CAAC;AAC7D,eAAO,MAAM,iBAAiB,EAAE,MAAgC,CAAC;AACjE,eAAO,MAAM,cAAc,EAAE,MAA6B,CAAC;AAC3D,eAAO,MAAM,eAAe,EAAE,MAA8B,CAAC;AAC7D,eAAO,MAAM,oBAAoB,EAAE,MAAmC,CAAC;AAgCvE,eAAO,MAAQ,GAAG,+BAA6B,CAAC;AAEhD,wBAAgB,WAAW,IAAI,aAAa,CAW3C;AAED,wBAAgB,WAAW,CAAC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,GAAG,CA2KxE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,GAAG,GAAG,CAM7F;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAqB1C"}
@@ -91,6 +91,21 @@ export function makeLocator(overrides = {}) {
91
91
  }
92
92
  return currentValue;
93
93
  };
94
+ const readSelectOptionValue = (value) => {
95
+ if (typeof value === 'string') {
96
+ return value;
97
+ }
98
+ if (Array.isArray(value)) {
99
+ return readSelectOptionValue(value[0]);
100
+ }
101
+ if (value && typeof value === 'object' && 'value' in value && typeof value.value === 'string') {
102
+ return value.value;
103
+ }
104
+ if (value && typeof value === 'object' && 'label' in value && typeof value.label === 'string') {
105
+ return value.label;
106
+ }
107
+ return '';
108
+ };
94
109
  const locator = {
95
110
  boundingBox: vi.fn(async () => null),
96
111
  click: vi.fn(async (...args) => {
@@ -153,18 +168,20 @@ export function makeLocator(overrides = {}) {
153
168
  currentValueInitialized = true;
154
169
  contextText = value;
155
170
  }),
156
- selectOption: vi.fn(async (value) => {
171
+ selectOption: vi.fn(async (...args) => {
157
172
  await ensureCurrentValue();
173
+ const [value] = args;
174
+ const nextValue = readSelectOptionValue(value);
158
175
  if (typeof selectOptionOverride === 'function') {
159
- const result = await selectOptionOverride(value);
160
- currentValue = value;
176
+ const result = await selectOptionOverride(...args);
177
+ currentValue = nextValue;
161
178
  currentValueInitialized = true;
162
- contextText = value;
179
+ contextText = nextValue;
163
180
  return result;
164
181
  }
165
- currentValue = value;
182
+ currentValue = nextValue;
166
183
  currentValueInitialized = true;
167
- contextText = value;
184
+ contextText = nextValue;
168
185
  }),
169
186
  press: vi.fn(async (value) => {
170
187
  await ensureCurrentValue();
@@ -1 +1 @@
1
- {"version":3,"file":"observe-inventory.d.ts","sourceRoot":"","sources":["../../src/commands/observe-inventory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observe-inventory.d.ts","sourceRoot":"","sources":["../../src/commands/observe-inventory.ts"],"names":[],"mappings":"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"}
@@ -2007,6 +2007,140 @@ async function collectDomTargetsFromDocument(context, options) {
2007
2007
  return role || surface.tagName.toLowerCase();
2008
2008
  };
2009
2009
 
2010
+ const labelledByTextOf = (element) => {
2011
+ if (!isHTMLElementNode(element)) {
2012
+ return undefined;
2013
+ }
2014
+
2015
+ const ariaLabelledby = element.getAttribute('aria-labelledby')?.trim();
2016
+ if (!ariaLabelledby) {
2017
+ return undefined;
2018
+ }
2019
+
2020
+ const labelledByText = normalizeDescriptorText(
2021
+ ariaLabelledby
2022
+ .split(/\s+/)
2023
+ .map((id) => textOf(document.getElementById(id)))
2024
+ .filter(Boolean)
2025
+ .join(' ')
2026
+ );
2027
+ return labelledByText || undefined;
2028
+ };
2029
+
2030
+ const headingLikeSelector = headingSelector + ', strong';
2031
+
2032
+ const descendantHeadingLabelOf = (element) => {
2033
+ if (!isHTMLElementNode(element)) {
2034
+ return undefined;
2035
+ }
2036
+
2037
+ const heading = element.querySelector(headingLikeSelector);
2038
+ if (!isHTMLElementNode(heading) || !isVisible(heading)) {
2039
+ return undefined;
2040
+ }
2041
+
2042
+ return normalizeDescriptorText(heading.innerText || heading.textContent || '') || undefined;
2043
+ };
2044
+
2045
+ const adjacentHeadingLabelOf = (surface) => {
2046
+ if (!isHTMLElementNode(surface)) {
2047
+ return undefined;
2048
+ }
2049
+
2050
+ const siblingHeadingLabelOf = (start, direction) => {
2051
+ let current = start;
2052
+ let steps = 0;
2053
+ while (current && steps < 3) {
2054
+ if (!isHTMLElementNode(current)) {
2055
+ current =
2056
+ direction === 'previous'
2057
+ ? current.previousElementSibling
2058
+ : current.nextElementSibling;
2059
+ steps += 1;
2060
+ continue;
2061
+ }
2062
+ if (!isVisible(current)) {
2063
+ current =
2064
+ direction === 'previous'
2065
+ ? current.previousElementSibling
2066
+ : current.nextElementSibling;
2067
+ steps += 1;
2068
+ continue;
2069
+ }
2070
+ if (current.matches?.(headingLikeSelector)) {
2071
+ return normalizeDescriptorText(current.innerText || current.textContent || '') || undefined;
2072
+ }
2073
+ return undefined;
2074
+ }
2075
+ return undefined;
2076
+ };
2077
+
2078
+ return (
2079
+ siblingHeadingLabelOf(surface.previousElementSibling, 'previous') ||
2080
+ siblingHeadingLabelOf(surface.nextElementSibling, 'next')
2081
+ );
2082
+ };
2083
+
2084
+ const isCollectionLikeSurfaceElement = (element) => {
2085
+ if (!isHTMLElementNode(element) || !isVisible(element)) {
2086
+ return false;
2087
+ }
2088
+
2089
+ const role = (element.getAttribute('role') || '').trim().toLowerCase();
2090
+ if (
2091
+ role === 'grid' ||
2092
+ role === 'listbox' ||
2093
+ role === 'menu' ||
2094
+ role === 'tabpanel' ||
2095
+ role === 'tablist'
2096
+ ) {
2097
+ return true;
2098
+ }
2099
+
2100
+ const className = (element.getAttribute('class') || '').toLowerCase();
2101
+ if (className.includes('calendar') || className.includes('datepicker')) {
2102
+ return true;
2103
+ }
2104
+
2105
+ const tag = element.tagName.toLowerCase();
2106
+ return (
2107
+ tag === 'table' ||
2108
+ tag === 'form' ||
2109
+ tag === 'fieldset' ||
2110
+ tag === 'ul' ||
2111
+ tag === 'ol'
2112
+ );
2113
+ };
2114
+
2115
+ const wrapperHeadingLabelOf = (surface) => {
2116
+ if (!isHTMLElementNode(surface)) {
2117
+ return undefined;
2118
+ }
2119
+
2120
+ const parent = composedParentElement(surface);
2121
+ if (!isHTMLElementNode(parent) || !isVisible(parent)) {
2122
+ return undefined;
2123
+ }
2124
+
2125
+ const headingLabel = Array.from(parent.children)
2126
+ .filter((child) => isHTMLElementNode(child) && isVisible(child))
2127
+ .find((child) => child.matches?.(headingLikeSelector));
2128
+ if (!isHTMLElementNode(headingLabel)) {
2129
+ return undefined;
2130
+ }
2131
+
2132
+ const directCollectionChildren = Array.from(parent.children).filter(
2133
+ (child) => isHTMLElementNode(child) && isCollectionLikeSurfaceElement(child)
2134
+ );
2135
+ if (directCollectionChildren.length !== 1 || directCollectionChildren[0] !== surface) {
2136
+ return undefined;
2137
+ }
2138
+
2139
+ return normalizeDescriptorText(
2140
+ headingLabel.innerText || headingLabel.textContent || ''
2141
+ ) || undefined;
2142
+ };
2143
+
2010
2144
  const surfaceFallbackLabelOf = (surface, surfaceKind) => {
2011
2145
  if (!isHTMLElementNode(surface)) {
2012
2146
  return undefined;
@@ -2030,20 +2164,20 @@ async function collectDomTargetsFromDocument(context, options) {
2030
2164
  }
2031
2165
 
2032
2166
  const directLabel = normalizeDescriptorText(
2033
- surface.getAttribute('aria-label') || surface.getAttribute('title') || ''
2167
+ surface.getAttribute('aria-label') ||
2168
+ surface.getAttribute('title') ||
2169
+ labelledByTextOf(surface) ||
2170
+ ''
2034
2171
  );
2035
2172
  if (directLabel) {
2036
2173
  return directLabel;
2037
2174
  }
2038
2175
 
2039
- const heading = surface.querySelector(
2040
- 'h1, h2, h3, h4, h5, h6, [role="heading"], legend, strong'
2176
+ return (
2177
+ descendantHeadingLabelOf(surface) ||
2178
+ adjacentHeadingLabelOf(surface) ||
2179
+ wrapperHeadingLabelOf(surface)
2041
2180
  );
2042
- if (!isHTMLElementNode(heading) || !isVisible(heading)) {
2043
- return undefined;
2044
- }
2045
-
2046
- return normalizeDescriptorText(heading.innerText || heading.textContent || '') || undefined;
2047
2181
  };
2048
2182
 
2049
2183
  const contextLabelOf = (element) => {
@@ -2056,26 +2190,14 @@ async function collectDomTargetsFromDocument(context, options) {
2056
2190
  return ariaLabel;
2057
2191
  }
2058
2192
 
2059
- const ariaLabelledby = element.getAttribute('aria-labelledby')?.trim();
2060
- if (ariaLabelledby) {
2061
- const labelledByText = normalizeDescriptorText(
2062
- ariaLabelledby
2063
- .split(/\s+/)
2064
- .map((id) => textOf(document.getElementById(id)))
2065
- .filter(Boolean)
2066
- .join(' ')
2067
- );
2068
- if (labelledByText) {
2069
- return labelledByText;
2070
- }
2193
+ const labelledByText = labelledByTextOf(element);
2194
+ if (labelledByText) {
2195
+ return labelledByText;
2071
2196
  }
2072
2197
 
2073
- const heading = element.querySelector(headingSelector);
2074
- if (isHTMLElementNode(heading) && heading !== element && !heading.contains(element)) {
2075
- const headingText = normalizeDescriptorText(heading.innerText || heading.textContent || '');
2076
- if (headingText) {
2077
- return headingText;
2078
- }
2198
+ const headingText = descendantHeadingLabelOf(element);
2199
+ if (headingText) {
2200
+ return headingText;
2079
2201
  }
2080
2202
 
2081
2203
  return undefined;
@@ -21,6 +21,10 @@ export type GoalObserveTargetCandidate = DomObservedTarget & {
21
21
  goalTargetKey: string;
22
22
  };
23
23
  export type GoalObserveInventoryCandidate = GoalObserveTargetCandidate | GoalObserveScopeCandidate;
24
+ type ExpandWorkflowGraphTargetOptions = {
25
+ selectedSurfaceIds?: ReadonlySet<string>;
26
+ };
27
+ export declare function expandWorkflowGraphTargets(allTargets: ReadonlyArray<DomObservedTarget>, selectedTargets: ReadonlyArray<DomObservedTarget>, options?: ExpandWorkflowGraphTargetOptions): DomObservedTarget[];
24
28
  export declare function compactTargets(targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability' | 'surfaceRef'>>): Array<{
25
29
  ref: string;
26
30
  kind?: string;
@@ -105,7 +109,7 @@ export declare function selectTargetsForGoalMatches(allTargets: ReadonlyArray<Do
105
109
  targets: DomObservedTarget[];
106
110
  selectedSurfaceIds: Set<string>;
107
111
  };
108
- export declare function buildExplicitScopeRefs(selectedSurfaceIds: ReadonlySet<string>, surfaceRefMap: ReadonlyMap<string, string>): Set<string>;
112
+ export declare function buildGoalProjectionScopeRefs(projectedTargets: ReadonlyArray<Pick<TargetDescriptor, 'surfaceRef'>>, selectedSurfaceIds: ReadonlySet<string>, surfaceRefMap: ReadonlyMap<string, string>): Set<string>;
109
113
  export declare function projectPersistedTargetsForGoal(domTargets: ReadonlyArray<DomObservedTarget>, persistedTargets: ReadonlyArray<TargetDescriptor>, selectedTargets: ReadonlyArray<DomObservedTarget>): TargetDescriptor[];
110
114
  export {};
111
115
  //# sourceMappingURL=observe-projection.d.ts.map
@@ -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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"}
@@ -1,9 +1,232 @@
1
- import { observedTargetKey } from './observe-semantics.js';
1
+ import { formGroupingKeyOf, isPrimaryFormControlTarget, observedTargetKey, } from './observe-semantics.js';
2
2
  import { buildSyntheticFormSurfaceId, summarizeContext } from './observe-surfaces.js';
3
+ const WORKFLOW_ROOT_KINDS = new Set([
4
+ 'dialog',
5
+ 'form',
6
+ 'tabpanel',
7
+ 'menu',
8
+ 'listbox',
9
+ 'popover',
10
+ 'dropdown',
11
+ 'datepicker',
12
+ 'card',
13
+ ]);
3
14
  function normalizeClusterText(value) {
4
15
  const normalized = value?.replace(/\s+/g, ' ').trim().toLowerCase();
5
16
  return normalized ? normalized : undefined;
6
17
  }
18
+ function normalizeWorkflowSurfaceSelector(value) {
19
+ const normalized = value?.trim();
20
+ return normalized ? normalized : undefined;
21
+ }
22
+ function workflowRootKeyOf(target) {
23
+ const contextNodes = [
24
+ target.context?.landmark,
25
+ target.context?.container,
26
+ target.context?.group,
27
+ target.context?.item,
28
+ ];
29
+ for (const node of contextNodes) {
30
+ const kind = normalizeClusterText(node?.kind);
31
+ if (!kind || !WORKFLOW_ROOT_KINDS.has(kind)) {
32
+ continue;
33
+ }
34
+ const label = normalizeClusterText(node?.label ?? node?.text);
35
+ return label ? `${kind}:${label}` : `${kind}:anonymous`;
36
+ }
37
+ const surfaceKind = normalizeClusterText(target.surfaceKind);
38
+ if (!surfaceKind || !WORKFLOW_ROOT_KINDS.has(surfaceKind)) {
39
+ return undefined;
40
+ }
41
+ const surfaceLabel = normalizeClusterText(target.surfaceLabel);
42
+ return surfaceLabel ? `${surfaceKind}:${surfaceLabel}` : `${surfaceKind}:anonymous`;
43
+ }
44
+ function isActiveControllerTarget(target) {
45
+ if (!normalizeWorkflowSurfaceSelector(target.controlsSurfaceSelector)) {
46
+ return false;
47
+ }
48
+ return target.states?.selected === true || target.states?.expanded === true;
49
+ }
50
+ function sortObservedTargets(targets) {
51
+ return [...targets].sort((left, right) => {
52
+ const leftOrdinal = left.ordinal ?? Number.MAX_SAFE_INTEGER;
53
+ const rightOrdinal = right.ordinal ?? Number.MAX_SAFE_INTEGER;
54
+ if (leftOrdinal !== rightOrdinal) {
55
+ return leftOrdinal - rightOrdinal;
56
+ }
57
+ return (left.label ?? '').localeCompare(right.label ?? '');
58
+ });
59
+ }
60
+ function selectedSurfaceSelectorsOf(selectedTargets) {
61
+ const selectors = new Set();
62
+ for (const target of selectedTargets) {
63
+ const selector = normalizeWorkflowSurfaceSelector(target.surfaceSelector);
64
+ if (selector) {
65
+ selectors.add(selector);
66
+ }
67
+ for (const candidate of target.surfaceSelectors ?? []) {
68
+ const normalized = normalizeWorkflowSurfaceSelector(candidate);
69
+ if (normalized) {
70
+ selectors.add(normalized);
71
+ }
72
+ }
73
+ }
74
+ return selectors;
75
+ }
76
+ function selectedSurfaceRefsOf(selectedTargets) {
77
+ return new Set(selectedTargets
78
+ .map((target) => target.surfaceRef?.trim())
79
+ .filter((value) => Boolean(value)));
80
+ }
81
+ function matchesSelectedSurfaceSeed(target, selectedSurfaceIds) {
82
+ if (selectedSurfaceIds.size === 0) {
83
+ return false;
84
+ }
85
+ const surfaceRef = target.surfaceRef?.trim();
86
+ if (surfaceRef && selectedSurfaceIds.has(surfaceRef)) {
87
+ return true;
88
+ }
89
+ const syntheticFormSurfaceId = buildSyntheticFormSurfaceId(target);
90
+ return syntheticFormSurfaceId ? selectedSurfaceIds.has(syntheticFormSurfaceId) : false;
91
+ }
92
+ function workflowClusterKeyOf(target) {
93
+ const formKey = formGroupingKeyOf(target);
94
+ if (formKey) {
95
+ return `form:${formKey}`;
96
+ }
97
+ const surfaceRef = target.surfaceRef?.trim();
98
+ if (surfaceRef) {
99
+ return `surface:${surfaceRef}`;
100
+ }
101
+ const surfaceSelector = normalizeWorkflowSurfaceSelector(target.surfaceSelector);
102
+ return surfaceSelector ? `selector:${surfaceSelector}` : undefined;
103
+ }
104
+ function matchesWorkflowCluster(target, clusterKey) {
105
+ return workflowClusterKeyOf(target) === clusterKey;
106
+ }
107
+ function isTerminalWorkflowActionTarget(target) {
108
+ const acceptancePolicy = (target.acceptancePolicy ?? '').trim().toLowerCase();
109
+ const inputType = (target.inputType ?? '').trim().toLowerCase();
110
+ return acceptancePolicy === 'submit' || inputType === 'submit';
111
+ }
112
+ function canJoinSelectedWorkflowRoot(target, selectedSurfaceRefs, selectedSurfaceSelectors) {
113
+ if (!isPrimaryFormControlTarget(target)) {
114
+ return false;
115
+ }
116
+ const surfaceRef = target.surfaceRef?.trim();
117
+ if (surfaceRef && selectedSurfaceRefs.has(surfaceRef)) {
118
+ return true;
119
+ }
120
+ const surfaceSelector = normalizeWorkflowSurfaceSelector(target.surfaceSelector);
121
+ if (surfaceSelector && selectedSurfaceSelectors.has(surfaceSelector)) {
122
+ return true;
123
+ }
124
+ const surfaceKind = normalizeClusterText(target.surfaceKind);
125
+ return surfaceKind === 'dialog' || surfaceKind === 'form' || (!surfaceRef && !surfaceSelector);
126
+ }
127
+ function shouldExpandAcrossWorkflowRoots(selectedPrimaryTargets, selectedSurfaceSelectors) {
128
+ if (selectedSurfaceSelectors.size > 0) {
129
+ return true;
130
+ }
131
+ return selectedPrimaryTargets.some((target) => Boolean(target.framePath?.length));
132
+ }
133
+ export function expandWorkflowGraphTargets(allTargets, selectedTargets, options = {}) {
134
+ const selectedSurfaceIds = options.selectedSurfaceIds ?? new Set();
135
+ if (selectedTargets.length === 0 && selectedSurfaceIds.size === 0) {
136
+ return [];
137
+ }
138
+ const expanded = new Map();
139
+ for (const target of selectedTargets) {
140
+ expanded.set(observedTargetKey(target), target);
141
+ }
142
+ for (const target of allTargets) {
143
+ const key = observedTargetKey(target);
144
+ if (expanded.has(key) || !matchesSelectedSurfaceSeed(target, selectedSurfaceIds)) {
145
+ continue;
146
+ }
147
+ expanded.set(key, target);
148
+ }
149
+ const seededTargets = [...expanded.values()];
150
+ const selectedSurfaceSelectors = selectedSurfaceSelectorsOf(seededTargets);
151
+ const selectedSurfaceRefs = selectedSurfaceRefsOf(seededTargets);
152
+ const selectedPrimaryTargets = seededTargets.filter(isPrimaryFormControlTarget);
153
+ const selectedClusterCounts = new Map();
154
+ for (const target of selectedPrimaryTargets) {
155
+ const clusterKey = workflowClusterKeyOf(target);
156
+ if (!clusterKey) {
157
+ continue;
158
+ }
159
+ selectedClusterCounts.set(clusterKey, (selectedClusterCounts.get(clusterKey) ?? 0) + 1);
160
+ }
161
+ for (const target of allTargets) {
162
+ const key = observedTargetKey(target);
163
+ if (expanded.has(key) || !isActiveControllerTarget(target)) {
164
+ continue;
165
+ }
166
+ const controlsSurfaceSelector = normalizeWorkflowSurfaceSelector(target.controlsSurfaceSelector);
167
+ if (!controlsSurfaceSelector || !selectedSurfaceSelectors.has(controlsSurfaceSelector)) {
168
+ continue;
169
+ }
170
+ expanded.set(key, target);
171
+ }
172
+ const expandableClusterKeys = new Set([...selectedClusterCounts.entries()]
173
+ .filter(([, count]) => count >= 2)
174
+ .map(([clusterKey]) => clusterKey));
175
+ for (const target of allTargets) {
176
+ const key = observedTargetKey(target);
177
+ if (expanded.has(key) || !isPrimaryFormControlTarget(target)) {
178
+ continue;
179
+ }
180
+ const clusterKey = workflowClusterKeyOf(target);
181
+ if (!clusterKey || !expandableClusterKeys.has(clusterKey) || !matchesWorkflowCluster(target, clusterKey)) {
182
+ continue;
183
+ }
184
+ expanded.set(key, target);
185
+ }
186
+ const expandedPrimaryTargets = [...expanded.values()].filter(isPrimaryFormControlTarget);
187
+ const selectedRootCounts = new Map();
188
+ for (const target of expandedPrimaryTargets) {
189
+ const workflowRootKey = workflowRootKeyOf(target);
190
+ if (!workflowRootKey) {
191
+ continue;
192
+ }
193
+ selectedRootCounts.set(workflowRootKey, (selectedRootCounts.get(workflowRootKey) ?? 0) + 1);
194
+ }
195
+ const selectedWorkflowRoots = new Set([...selectedRootCounts.entries()]
196
+ .filter(([, count]) => count >= 2)
197
+ .map(([workflowRootKey]) => workflowRootKey));
198
+ if (selectedWorkflowRoots.size === 0 ||
199
+ !shouldExpandAcrossWorkflowRoots(expandedPrimaryTargets, selectedSurfaceSelectors)) {
200
+ return sortObservedTargets([...expanded.values()]);
201
+ }
202
+ const rootClosureCandidates = [];
203
+ const rootTerminalCandidateCounts = new Map();
204
+ for (const target of allTargets) {
205
+ const key = observedTargetKey(target);
206
+ if (expanded.has(key)) {
207
+ continue;
208
+ }
209
+ const workflowRootKey = workflowRootKeyOf(target);
210
+ if (!workflowRootKey || !selectedWorkflowRoots.has(workflowRootKey)) {
211
+ continue;
212
+ }
213
+ if (!canJoinSelectedWorkflowRoot(target, selectedSurfaceRefs, selectedSurfaceSelectors)) {
214
+ continue;
215
+ }
216
+ rootClosureCandidates.push({ key, target, workflowRootKey });
217
+ if (isTerminalWorkflowActionTarget(target)) {
218
+ rootTerminalCandidateCounts.set(workflowRootKey, (rootTerminalCandidateCounts.get(workflowRootKey) ?? 0) + 1);
219
+ }
220
+ }
221
+ for (const candidate of rootClosureCandidates) {
222
+ if (isTerminalWorkflowActionTarget(candidate.target) &&
223
+ (rootTerminalCandidateCounts.get(candidate.workflowRootKey) ?? 0) > 1) {
224
+ continue;
225
+ }
226
+ expanded.set(candidate.key, candidate.target);
227
+ }
228
+ return sortObservedTargets([...expanded.values()]);
229
+ }
7
230
  function isActionLikeGoalTarget(target) {
8
231
  const actions = target.allowedActions ?? [];
9
232
  const kind = (target.kind ?? '').trim().toLowerCase();
@@ -315,26 +538,26 @@ export function selectTargetsForGoalMatches(allTargets, rerankedCandidates) {
315
538
  seenTargetKeys.add(observedKey);
316
539
  matchedTargets.push(matchedTarget);
317
540
  }
318
- const scopeTargets = allTargets.filter((target) => {
319
- const directMatch = typeof target.ordinal === 'number' && directTargetOrdinals.has(target.ordinal);
320
- const directKeyMatch = directTargetKeys.has(observedTargetKey(target));
321
- const syntheticFormSurfaceId = buildSyntheticFormSurfaceId(target);
322
- const scopeMatch = (target.surfaceRef ? selectedSurfaceIds.has(target.surfaceRef) : false) ||
323
- (syntheticFormSurfaceId ? selectedSurfaceIds.has(syntheticFormSurfaceId) : false);
324
- if (directMatch || directKeyMatch) {
325
- return false;
326
- }
327
- return scopeMatch;
328
- });
329
541
  return {
330
- targets: [...matchedTargets, ...scopeTargets],
542
+ targets: matchedTargets,
331
543
  selectedSurfaceIds,
332
544
  };
333
545
  }
334
- export function buildExplicitScopeRefs(selectedSurfaceIds, surfaceRefMap) {
335
- return new Set([...selectedSurfaceIds]
336
- .map((surfaceId) => surfaceRefMap.get(surfaceId))
337
- .filter((value) => typeof value === 'string' && value.length > 0));
546
+ export function buildGoalProjectionScopeRefs(projectedTargets, selectedSurfaceIds, surfaceRefMap) {
547
+ const preferredScopeRefs = new Set();
548
+ for (const surfaceId of selectedSurfaceIds) {
549
+ const scopeRef = surfaceRefMap.get(surfaceId);
550
+ if (scopeRef) {
551
+ preferredScopeRefs.add(scopeRef);
552
+ }
553
+ }
554
+ for (const target of projectedTargets) {
555
+ const surfaceRef = target.surfaceRef?.trim();
556
+ if (surfaceRef) {
557
+ preferredScopeRefs.add(surfaceRef);
558
+ }
559
+ }
560
+ return preferredScopeRefs;
338
561
  }
339
562
  export function projectPersistedTargetsForGoal(domTargets, persistedTargets, selectedTargets) {
340
563
  const persistedByKey = new Map();
@@ -3,8 +3,6 @@ export declare function normalizeSemanticDuplicateLabel(target: DomObservedTarge
3
3
  export declare function isPrimaryFormControlTarget(target: DomObservedTarget): boolean;
4
4
  export declare function formGroupingKeyOf(target: DomObservedTarget): string | undefined;
5
5
  export declare function observedTargetKey(target: DomObservedTarget): string;
6
- export declare function expandRerankedFormTargets(targets: ReadonlyArray<DomObservedTarget>, selectedTargets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
7
- export declare function expandCompanionSubmitTargets(targets: ReadonlyArray<DomObservedTarget>, selectedTargets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
8
6
  export declare function prioritizeGoalActionTargets(instruction: string, selectedTargets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
9
7
  export declare function compressSemanticallyDuplicateTargets(targets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
10
8
  export declare function annotateDomTargets(targets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
@@ -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;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CAyCrB;AAsDD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CAsFrB;AAkFD,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;AAkGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,EAAE,CAoFjG;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;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;AAkFD,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;AAkGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,EAAE,CAoFjG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAsFrB"}
@@ -59,151 +59,6 @@ export function observedTargetKey(target) {
59
59
  target.domSignature ??
60
60
  `${target.formSelector ?? 'no-form'}|${target.ordinal ?? 'no-ordinal'}|${target.label ?? ''}`);
61
61
  }
62
- export function expandRerankedFormTargets(targets, selectedTargets) {
63
- const selectedFormControlCounts = new Map();
64
- for (const target of selectedTargets) {
65
- const formKey = formGroupingKeyOf(target);
66
- if (!formKey || !isPrimaryFormControlTarget(target)) {
67
- continue;
68
- }
69
- selectedFormControlCounts.set(formKey, (selectedFormControlCounts.get(formKey) ?? 0) + 1);
70
- }
71
- const expandableFormKeys = new Set([...selectedFormControlCounts.entries()]
72
- .filter(([, count]) => count >= 2)
73
- .map(([formKey]) => formKey));
74
- if (expandableFormKeys.size === 0) {
75
- return [...selectedTargets];
76
- }
77
- const expanded = new Map();
78
- for (const target of selectedTargets) {
79
- expanded.set(observedTargetKey(target), target);
80
- }
81
- for (const target of targets) {
82
- const formKey = formGroupingKeyOf(target);
83
- if (!formKey || !expandableFormKeys.has(formKey) || !isPrimaryFormControlTarget(target)) {
84
- continue;
85
- }
86
- expanded.set(observedTargetKey(target), target);
87
- }
88
- return [...expanded.values()].sort((left, right) => {
89
- const leftOrdinal = left.ordinal ?? Number.MAX_SAFE_INTEGER;
90
- const rightOrdinal = right.ordinal ?? Number.MAX_SAFE_INTEGER;
91
- if (leftOrdinal !== rightOrdinal) {
92
- return leftOrdinal - rightOrdinal;
93
- }
94
- return (left.label ?? '').localeCompare(right.label ?? '');
95
- });
96
- }
97
- function isSubmitLikeTarget(target) {
98
- const acceptancePolicy = (target.acceptancePolicy ?? '').trim().toLowerCase();
99
- const inputType = (target.inputType ?? '').trim().toLowerCase();
100
- return acceptancePolicy === 'submit' || inputType === 'submit';
101
- }
102
- function selectedFormClusterKeyOf(target) {
103
- const formKey = formGroupingKeyOf(target);
104
- if (formKey) {
105
- return `form:${formKey}`;
106
- }
107
- const surfaceRef = target.surfaceRef?.trim();
108
- return surfaceRef ? `surface:${surfaceRef}` : undefined;
109
- }
110
- function matchesSelectedFormCluster(target, clusterKey) {
111
- if (!clusterKey) {
112
- return false;
113
- }
114
- if (clusterKey.startsWith('form:')) {
115
- return `form:${formGroupingKeyOf(target)}` === clusterKey;
116
- }
117
- if (!clusterKey.startsWith('surface:')) {
118
- return false;
119
- }
120
- return `surface:${target.surfaceRef?.trim() ?? ''}` === clusterKey;
121
- }
122
- function isStandaloneBottomSubmitInputTarget(target) {
123
- const inputType = (target.inputType ?? '').trim().toLowerCase();
124
- if (inputType !== 'submit') {
125
- return false;
126
- }
127
- if (target.framePath?.length) {
128
- return false;
129
- }
130
- if (target.surfaceRef?.trim() || formGroupingKeyOf(target)) {
131
- return false;
132
- }
133
- return target.context?.layout?.band === 'bottom';
134
- }
135
- export function expandCompanionSubmitTargets(targets, selectedTargets) {
136
- if (selectedTargets.some(isSubmitLikeTarget)) {
137
- return [...selectedTargets];
138
- }
139
- const primarySelectedTargets = selectedTargets.filter(isPrimaryFormControlTarget);
140
- if (primarySelectedTargets.length < 2) {
141
- return [...selectedTargets];
142
- }
143
- const clusterEntries = new Map();
144
- for (const target of primarySelectedTargets) {
145
- const clusterKey = selectedFormClusterKeyOf(target);
146
- if (!clusterKey) {
147
- continue;
148
- }
149
- const existing = clusterEntries.get(clusterKey) ?? {
150
- count: 0,
151
- priority: clusterKey.startsWith('form:') ? 2 : 1,
152
- inFrame: false,
153
- };
154
- existing.count += 1;
155
- existing.inFrame ||= Boolean(target.framePath?.length);
156
- clusterEntries.set(clusterKey, existing);
157
- }
158
- const dominantCluster = [...clusterEntries.entries()]
159
- .filter(([, entry]) => entry.count >= 2)
160
- .sort((left, right) => {
161
- const [, leftEntry] = left;
162
- const [, rightEntry] = right;
163
- if (leftEntry.count !== rightEntry.count) {
164
- return rightEntry.count - leftEntry.count;
165
- }
166
- if (leftEntry.priority !== rightEntry.priority) {
167
- return rightEntry.priority - leftEntry.priority;
168
- }
169
- return left[0].localeCompare(right[0]);
170
- })[0];
171
- if (!dominantCluster) {
172
- return [...selectedTargets];
173
- }
174
- const [dominantClusterKey, dominantClusterMeta] = dominantCluster;
175
- const expanded = new Map();
176
- for (const target of selectedTargets) {
177
- expanded.set(observedTargetKey(target), target);
178
- }
179
- const explicitCompanions = targets.filter((target) => {
180
- const key = observedTargetKey(target);
181
- if (expanded.has(key) || !isSubmitLikeTarget(target)) {
182
- return false;
183
- }
184
- return matchesSelectedFormCluster(target, dominantClusterKey);
185
- });
186
- for (const target of explicitCompanions) {
187
- expanded.set(observedTargetKey(target), target);
188
- }
189
- if (explicitCompanions.length === 0 && dominantClusterMeta.inFrame) {
190
- const fallbackCandidates = targets.filter((target) => {
191
- const key = observedTargetKey(target);
192
- return !expanded.has(key) && isStandaloneBottomSubmitInputTarget(target);
193
- });
194
- if (fallbackCandidates.length === 1) {
195
- expanded.set(observedTargetKey(fallbackCandidates[0]), fallbackCandidates[0]);
196
- }
197
- }
198
- return [...expanded.values()].sort((left, right) => {
199
- const leftOrdinal = left.ordinal ?? Number.MAX_SAFE_INTEGER;
200
- const rightOrdinal = right.ordinal ?? Number.MAX_SAFE_INTEGER;
201
- if (leftOrdinal !== rightOrdinal) {
202
- return leftOrdinal - rightOrdinal;
203
- }
204
- return (left.label ?? '').localeCompare(right.label ?? '');
205
- });
206
- }
207
62
  function parseNumericAmount(value) {
208
63
  const normalized = value.replace(/,/g, '.').trim();
209
64
  if (!/^\d+(?:\.\d+)?$/.test(normalized)) {
@@ -1 +1 @@
1
- {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/commands/observe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA4DnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,eAAO,MAAM,yBAAyB;;;;iBA4Uk6G,CAAC;gBAAwB,CAAC;;;;;CA5U75G,CAAC;AACtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGrC,CAAC;AAEF,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqUzF"}
1
+ {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/commands/observe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA2DnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,eAAO,MAAM,yBAAyB;;;;iBA6Uw6G,CAAC;gBAAwB,CAAC;;;;;CA7Un6G,CAAC;AACtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGrC,CAAC;AAEF,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsUzF"}
@@ -14,8 +14,8 @@ import { collectPageSignals } from './observe-signals.js';
14
14
  import { attachObservedTargetOwners, linkObservedSurfaceGraph, reconcileObservedTargetsForPage, persistObservedSurfacesForPage, toDomDescriptor, } from './observe-persistence.js';
15
15
  import { clearProtectedFillableFormsForPage, persistProtectedFillableFormsForPage, } from './observe-protected.js';
16
16
  import { classifyObservePageState, shouldSuppressFillableFormsForObserve, } from './observe-page-state.js';
17
- import { annotateDomTargets, compressSemanticallyDuplicateTargets, expandCompanionSubmitTargets, expandRerankedFormTargets, orderBySurfaceCompetition, prioritizeGoalActionTargets, } from './observe-semantics.js';
18
- import { buildGroupedObserveScopes, buildExplicitScopeRefs, buildGoalObserveInventoryCandidates, compactFillableForms, compactSignals, projectPersistedTargetsForGoal, selectTargetsForGoalMatches, } from './observe-projection.js';
17
+ import { annotateDomTargets, compressSemanticallyDuplicateTargets, orderBySurfaceCompetition, prioritizeGoalActionTargets, } from './observe-semantics.js';
18
+ import { buildGroupedObserveScopes, buildGoalProjectionScopeRefs, buildGoalObserveInventoryCandidates, compactFillableForms, compactSignals, expandWorkflowGraphTargets, projectPersistedTargetsForGoal, selectTargetsForGoalMatches, } from './observe-projection.js';
19
19
  import { collectSurfaceDescriptors, selectScopesForOutput } from './observe-surfaces.js';
20
20
  import { toStagehandDescriptor } from './observe-stagehand.js';
21
21
  import { rerankDomTargetsForGoal } from './semantic-observe.js';
@@ -126,7 +126,7 @@ export async function observe(session, instruction) {
126
126
  if (domTargets.length > 0) {
127
127
  const rerankedCandidates = await rerankDomTargetsForGoal(instruction, buildGoalObserveInventoryCandidates(domTargets, surfaceInputs), { session });
128
128
  const { targets: goalMatchedTargets, selectedSurfaceIds } = selectTargetsForGoalMatches(domTargets, rerankedCandidates);
129
- const selectedTargets = prioritizeGoalActionTargets(instruction, expandCompanionSubmitTargets(domTargets, expandRerankedFormTargets(domTargets, goalMatchedTargets)));
129
+ const selectedTargets = prioritizeGoalActionTargets(instruction, expandWorkflowGraphTargets(domTargets, goalMatchedTargets, { selectedSurfaceIds }));
130
130
  const persisted = persistObservedSurfacesForPage(session, pageRef, domTargets, {
131
131
  allSurfaceInputs: surfaceInputs,
132
132
  explicitSurfaceIds: selectedSurfaceIds,
@@ -141,8 +141,8 @@ export async function observe(session, instruction) {
141
141
  ? clearProtectedFillableFormsForPage(session, pageRef)
142
142
  : await persistProtectedFillableFormsForPage(session, pageRef, url, targets, new Date().toISOString());
143
143
  if (selectedTargets.length > 0 || selectedSurfaceIds.size > 0) {
144
- const explicitScopeRefs = buildExplicitScopeRefs(selectedSurfaceIds, surfaceRefMap);
145
144
  const projectedTargets = projectPersistedTargetsForGoal(domTargets, targets, selectedTargets);
145
+ const explicitScopeRefs = buildGoalProjectionScopeRefs(projectedTargets, selectedSurfaceIds, surfaceRefMap);
146
146
  saveSession(session);
147
147
  disconnectPlaywright(browser);
148
148
  browser = null;
@@ -1 +1 @@
1
- {"version":3,"file":"select-action-executor.d.ts","sourceRoot":"","sources":["../../src/commands/select-action-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEnG,KAAK,WAAW,GAAG,IAAI,GAAG,YAAY,GAAG,OAAO,CAAC;AAMjD,KAAK,mBAAmB,GAAG;IACzB,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,0BAA0B,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF,CAAC;AAoFF,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,mBAAmB,EAC5B,MAAM,CAAC,EAAE,qBAAqB,GAC7B,OAAO,CAAC,OAAO,CAAC,CA0BlB"}
1
+ {"version":3,"file":"select-action-executor.d.ts","sourceRoot":"","sources":["../../src/commands/select-action-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEnG,KAAK,WAAW,GAAG,IAAI,GAAG,YAAY,GAAG,OAAO,CAAC;AAajD,KAAK,mBAAmB,GAAG;IACzB,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,0BAA0B,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF,CAAC;AAgKF,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,mBAAmB,EAC5B,MAAM,CAAC,EAAE,qBAAqB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAsElB"}
@@ -2,6 +2,59 @@ import { runActionExecutionGuard } from './action-execution-guards.js';
2
2
  const OPTION_RESOLVE_TIMEOUT_MS = 250;
3
3
  const ASYNC_OPTION_WAIT_MS = 1_000;
4
4
  const OPTION_POLL_INTERVAL_MS = 100;
5
+ const LOCATOR_SELECT_TIMEOUT_MS = 1_500;
6
+ function normalizeNativeSelectComparable(value) {
7
+ return (value ?? '').replace(/\s+/g, ' ').trim();
8
+ }
9
+ function compactNativeSelectComparable(value) {
10
+ return normalizeNativeSelectComparable(value).replace(/\s+/g, '');
11
+ }
12
+ async function readNativeSelectState(locator, guards) {
13
+ await runActionExecutionGuard(guards, 'select.native-state');
14
+ return locator
15
+ .evaluate((element) => {
16
+ const selectElement = element instanceof HTMLSelectElement
17
+ ? element
18
+ : element instanceof HTMLLabelElement && element.control instanceof HTMLSelectElement
19
+ ? element.control
20
+ : null;
21
+ if (!selectElement) {
22
+ return null;
23
+ }
24
+ const selected = selectElement.options[selectElement.selectedIndex] ?? null;
25
+ return {
26
+ value: selectElement.value,
27
+ label: selected?.label ?? '',
28
+ text: selected?.text ?? selected?.textContent ?? '',
29
+ };
30
+ }, { mode: 'selected-state' })
31
+ .catch(() => null);
32
+ }
33
+ function nativeSelectStateMatchesRequest(requestedValue, state) {
34
+ if (!state) {
35
+ return false;
36
+ }
37
+ const requested = normalizeNativeSelectComparable(requestedValue);
38
+ const requestedCompact = compactNativeSelectComparable(requestedValue);
39
+ if (!requested && !requestedCompact) {
40
+ return false;
41
+ }
42
+ const candidates = [state.value, state.label, state.text];
43
+ return candidates.some((candidate) => {
44
+ const normalizedCandidate = normalizeNativeSelectComparable(candidate);
45
+ const compactCandidate = compactNativeSelectComparable(candidate);
46
+ return ((requested.length > 0 && normalizedCandidate === requested) ||
47
+ (requestedCompact.length > 0 && compactCandidate === requestedCompact));
48
+ });
49
+ }
50
+ async function acceptIfNativeSelectSettled(locator, requestedValue, attempts, guards, attemptLabel) {
51
+ const nativeSelectState = await readNativeSelectState(locator, guards);
52
+ if (!nativeSelectStateMatchesRequest(requestedValue, nativeSelectState)) {
53
+ return false;
54
+ }
55
+ attempts.push(attemptLabel);
56
+ return true;
57
+ }
5
58
  async function clickOptionFromRoot(root, value, attempts, options, guards) {
6
59
  const deadline = Date.now() + Math.max(0, options?.waitForMs ?? 0);
7
60
  while (true) {
@@ -64,18 +117,27 @@ async function pressSelectTriggerKey(locator, key, attempts) {
64
117
  export async function applySelectLikeAction(page, root, locator, value, attempts, helpers, guards) {
65
118
  attempts.push('locator.selectOption');
66
119
  try {
67
- await locator.selectOption(value);
120
+ await locator.selectOption(value, { timeout: LOCATOR_SELECT_TIMEOUT_MS });
68
121
  return false;
69
122
  }
70
123
  catch {
124
+ if (await acceptIfNativeSelectSettled(locator, value, attempts, guards, 'locator.selectOption.accepted-after-error')) {
125
+ return false;
126
+ }
71
127
  await runActionExecutionGuard(guards, 'select.after-error');
72
128
  await helpers.focusLocator(page, locator, attempts);
73
129
  if (await clickOptionFromRoot(root, value, attempts, undefined, guards)) {
74
130
  return true;
75
131
  }
132
+ if (await acceptIfNativeSelectSettled(locator, value, attempts, guards, 'locator.selectOption.accepted-after-fallback')) {
133
+ return false;
134
+ }
76
135
  if (await tryTypeToFilterSelectOption(root, locator, value, attempts, helpers, guards)) {
77
136
  return true;
78
137
  }
138
+ if (await acceptIfNativeSelectSettled(locator, value, attempts, guards, 'locator.selectOption.accepted-after-fallback')) {
139
+ return false;
140
+ }
79
141
  for (const key of ['Enter', 'Space', 'ArrowDown']) {
80
142
  await runActionExecutionGuard(guards, `select.press:${key.toLowerCase()}`);
81
143
  const pressed = await pressSelectTriggerKey(locator, key, attempts);
@@ -85,6 +147,9 @@ export async function applySelectLikeAction(page, root, locator, value, attempts
85
147
  if (await clickOptionFromRoot(root, value, attempts, undefined, guards)) {
86
148
  return true;
87
149
  }
150
+ if (await acceptIfNativeSelectSettled(locator, value, attempts, guards, 'locator.selectOption.accepted-after-fallback')) {
151
+ return false;
152
+ }
88
153
  }
89
154
  throw new Error('select_option_not_found');
90
155
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuanu-ai/agentbrowse",
3
- "version": "0.2.43",
3
+ "version": "0.2.45",
4
4
  "type": "module",
5
5
  "description": "Browser automation CLI for AI agents: control a CDP browser, observe UI surfaces, act on refs, extract data, capture screenshots, complete protected fills, and solve captchas",
6
6
  "keywords": [