@nuanu-ai/agentbrowse 0.2.12 → 0.2.14
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 +5 -0
- package/dist/agentpay-stagehand-llm.d.ts +16 -0
- package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
- package/dist/agentpay-stagehand-llm.js +35 -10
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +16 -15
- package/dist/commands/action-acceptance.d.ts +1 -0
- package/dist/commands/action-acceptance.d.ts.map +1 -1
- package/dist/commands/action-acceptance.js +77 -1
- package/dist/commands/extract-snapshot-sanitizer.d.ts +2 -0
- package/dist/commands/extract-snapshot-sanitizer.d.ts.map +1 -0
- package/dist/commands/extract-snapshot-sanitizer.js +65 -0
- package/dist/commands/extract-stagehand-executor.d.ts.map +1 -1
- package/dist/commands/extract-stagehand-executor.js +33 -3
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +29 -0
- package/dist/commands/launch.js +0 -7
- package/dist/commands/observe-inventory.d.ts.map +1 -1
- package/dist/commands/observe-inventory.js +43 -0
- package/dist/commands/observe-persistence.d.ts +1 -0
- package/dist/commands/observe-persistence.d.ts.map +1 -1
- package/dist/commands/observe-persistence.js +52 -1
- package/dist/commands/observe-projection.d.ts +28 -5
- package/dist/commands/observe-projection.d.ts.map +1 -1
- package/dist/commands/observe-projection.js +189 -9
- package/dist/commands/observe-semantics.d.ts.map +1 -1
- package/dist/commands/observe-semantics.js +13 -2
- package/dist/commands/observe-surfaces.d.ts +1 -0
- package/dist/commands/observe-surfaces.d.ts.map +1 -1
- package/dist/commands/observe-surfaces.js +65 -0
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +49 -19
- package/dist/commands/observe.test-harness.d.ts +1 -0
- package/dist/commands/observe.test-harness.d.ts.map +1 -1
- package/dist/commands/observe.test-harness.js +53 -16
- package/dist/commands/semantic-observe.d.ts +2 -0
- package/dist/commands/semantic-observe.d.ts.map +1 -1
- package/dist/commands/semantic-observe.js +4 -0
- package/dist/playwright-runtime.d.ts +3 -1
- package/dist/playwright-runtime.d.ts.map +1 -1
- package/dist/playwright-runtime.js +42 -2
- package/dist/runtime-state.d.ts +3 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +2 -0
- package/dist/secrets/fill-ordering.d.ts +1 -2
- package/dist/secrets/fill-ordering.d.ts.map +1 -1
- package/dist/secrets/fill-ordering.js +0 -3
- package/dist/secrets/form-matcher.d.ts.map +1 -1
- package/dist/secrets/form-matcher.js +0 -9
- package/dist/secrets/types.d.ts +0 -9
- package/dist/secrets/types.d.ts.map +1 -1
- package/dist/solver/browser-launcher.d.ts.map +1 -1
- package/dist/solver/browser-launcher.js +492 -55
- package/dist/solver/captcha-detector.d.ts.map +1 -1
- package/dist/solver/captcha-detector.js +187 -12
- package/dist/solver/captcha-runtime.d.ts.map +1 -1
- package/dist/solver/captcha-runtime.js +8 -0
- package/dist/solver/captcha-solver.d.ts +11 -1
- package/dist/solver/captcha-solver.d.ts.map +1 -1
- package/dist/solver/captcha-solver.js +11 -4
- package/dist/solver/turnstile-challenge.d.ts +3 -0
- package/dist/solver/turnstile-challenge.d.ts.map +1 -0
- package/dist/solver/turnstile-challenge.js +173 -0
- package/dist/solver/types.d.ts +10 -8
- package/dist/solver/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/secrets/request-guidance.d.ts +0 -24
- package/dist/secrets/request-guidance.d.ts.map +0 -1
- package/dist/secrets/request-guidance.js +0 -142
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ensureRuntimeState, markSurfaceLifecycle, markTargetLifecycle, replaceSurfacesForPage, setSurfaceAvailability, setTargetAvailability, } from '../runtime-state.js';
|
|
2
|
-
import { collectSurfaceDescriptors, pushUniqueLocatorCandidate, surfaceReplacementKey } from './observe-surfaces.js';
|
|
2
|
+
import { buildSyntheticFormSurfaceId, collectSurfaceDescriptors, pushUniqueLocatorCandidate, surfaceReplacementKey, } from './observe-surfaces.js';
|
|
3
3
|
export function toDomDescriptor(pageRef, target, surfaceRefMap) {
|
|
4
4
|
const locatorCandidates = [];
|
|
5
5
|
if (target.role && target.label) {
|
|
@@ -168,3 +168,54 @@ export function reconcileObservedTargetsForPage(session, pageRef, observedTarget
|
|
|
168
168
|
setTargetAvailability(session, target.ref, 'hidden', 'target-not-observed');
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
+
function pushUniqueRef(map, key, ref) {
|
|
172
|
+
const refs = map.get(key) ?? [];
|
|
173
|
+
if (!refs.includes(ref)) {
|
|
174
|
+
refs.push(ref);
|
|
175
|
+
map.set(key, refs);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export function linkObservedSurfaceGraph(session, pageRef, domTargets, persistedTargets, observedScopes, surfaceRefMap) {
|
|
179
|
+
const runtime = ensureRuntimeState(session);
|
|
180
|
+
const activeSurfaceRefs = new Set(observedScopes.map((scope) => scope.ref));
|
|
181
|
+
const targetRefsBySurface = new Map();
|
|
182
|
+
const parentBySurface = new Map();
|
|
183
|
+
const childRefsByParent = new Map();
|
|
184
|
+
for (const [index, persistedTarget] of persistedTargets.entries()) {
|
|
185
|
+
if (persistedTarget.pageRef !== pageRef) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (persistedTarget.surfaceRef) {
|
|
189
|
+
pushUniqueRef(targetRefsBySurface, persistedTarget.surfaceRef, persistedTarget.ref);
|
|
190
|
+
}
|
|
191
|
+
const domTarget = domTargets[index];
|
|
192
|
+
if (!domTarget) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const syntheticFormSurfaceId = buildSyntheticFormSurfaceId(domTarget);
|
|
196
|
+
const formSurfaceRef = syntheticFormSurfaceId
|
|
197
|
+
? surfaceRefMap.get(syntheticFormSurfaceId)
|
|
198
|
+
: undefined;
|
|
199
|
+
if (!formSurfaceRef || !persistedTarget.surfaceRef || persistedTarget.surfaceRef === formSurfaceRef) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
parentBySurface.set(persistedTarget.surfaceRef, formSurfaceRef);
|
|
203
|
+
pushUniqueRef(childRefsByParent, formSurfaceRef, persistedTarget.surfaceRef);
|
|
204
|
+
}
|
|
205
|
+
for (const surface of Object.values(runtime.surfaces)) {
|
|
206
|
+
if (surface.pageRef !== pageRef) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
runtime.surfaces[surface.ref] = {
|
|
210
|
+
...surface,
|
|
211
|
+
parentSurfaceRef: activeSurfaceRefs.has(surface.ref)
|
|
212
|
+
? parentBySurface.get(surface.ref)
|
|
213
|
+
: undefined,
|
|
214
|
+
childSurfaceRefs: activeSurfaceRefs.has(surface.ref)
|
|
215
|
+
? [...(childRefsByParent.get(surface.ref) ?? [])]
|
|
216
|
+
: [],
|
|
217
|
+
targetRefs: activeSurfaceRefs.has(surface.ref) ? [...(targetRefsBySurface.get(surface.ref) ?? [])] : [],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
return observedScopes.map((scope) => runtime.surfaces[scope.ref] ?? scope);
|
|
221
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SurfaceDescriptor, TargetDescriptor, TargetValidationEvidence } from '../runtime-state.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { PersistedFillableForm, ProtectedBindingValueHint } from '../secrets/types.js';
|
|
3
3
|
import type { DomObservedTarget, ObservedPageSignal } from './observe-inventory.js';
|
|
4
4
|
export type GoalObserveScopeCandidate = {
|
|
5
5
|
goalInventoryType: 'scope';
|
|
@@ -20,7 +20,7 @@ export type GoalObserveTargetCandidate = DomObservedTarget & {
|
|
|
20
20
|
goalTargetKey: string;
|
|
21
21
|
};
|
|
22
22
|
export type GoalObserveInventoryCandidate = GoalObserveTargetCandidate | GoalObserveScopeCandidate;
|
|
23
|
-
export declare function compactTargets(targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability'>>): Array<{
|
|
23
|
+
export declare function compactTargets(targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability' | 'surfaceRef'>>): Array<{
|
|
24
24
|
ref: string;
|
|
25
25
|
kind?: string;
|
|
26
26
|
label?: string;
|
|
@@ -36,23 +36,45 @@ export declare function compactTargets(targets: ReadonlyArray<Pick<TargetDescrip
|
|
|
36
36
|
capability?: TargetDescriptor['capability'];
|
|
37
37
|
availability?: string;
|
|
38
38
|
availabilityReason?: string;
|
|
39
|
+
surfaceRef?: string;
|
|
39
40
|
source?: 'dom' | 'stagehand' | 'aria-snapshot' | 'cdp-ax';
|
|
40
41
|
}>;
|
|
41
|
-
export
|
|
42
|
+
export type CompactObservedTarget = ReturnType<typeof compactTargets>[number];
|
|
43
|
+
export declare function compactScopes(scopes: ReadonlyArray<Pick<SurfaceDescriptor, 'ref' | 'kind' | 'label' | 'availability' | 'parentSurfaceRef' | 'childSurfaceRefs' | 'targetRefs'>>): Array<{
|
|
42
44
|
ref: string;
|
|
43
45
|
kind?: string;
|
|
44
46
|
label?: string;
|
|
45
47
|
capability: 'scope';
|
|
46
48
|
availability?: string;
|
|
47
49
|
availabilityReason?: string;
|
|
50
|
+
parentSurfaceRef?: string;
|
|
51
|
+
childSurfaceRefs?: string[];
|
|
52
|
+
targetRefs?: string[];
|
|
48
53
|
source: 'dom';
|
|
49
54
|
}>;
|
|
55
|
+
export type CompactObservedScope = {
|
|
56
|
+
ref: string;
|
|
57
|
+
kind?: string;
|
|
58
|
+
label?: string;
|
|
59
|
+
capability: 'scope';
|
|
60
|
+
availability?: string;
|
|
61
|
+
availabilityReason?: string;
|
|
62
|
+
parentSurfaceRef?: string;
|
|
63
|
+
childSurfaceRefs?: string[];
|
|
64
|
+
targets: CompactObservedTarget[];
|
|
65
|
+
source: 'dom' | 'stagehand' | 'aria-snapshot' | 'cdp-ax';
|
|
66
|
+
};
|
|
67
|
+
type BuildGroupedObserveScopesOptions = {
|
|
68
|
+
pageRef: string;
|
|
69
|
+
title?: string;
|
|
70
|
+
scopes: ReadonlyArray<Pick<SurfaceDescriptor, 'ref' | 'kind' | 'label' | 'availability' | 'parentSurfaceRef' | 'childSurfaceRefs'>>;
|
|
71
|
+
targets: ReadonlyArray<Pick<TargetDescriptor, 'ref' | 'kind' | 'label' | 'displayLabel' | 'placeholder' | 'inputName' | 'inputType' | 'autocomplete' | 'validation' | 'context' | 'semantics' | 'structure' | 'capability' | 'availability' | 'surfaceRef'>>;
|
|
72
|
+
};
|
|
73
|
+
export declare function buildGroupedObserveScopes(options: BuildGroupedObserveScopesOptions): CompactObservedScope[];
|
|
50
74
|
export declare function compactFillableForms(forms: ReadonlyArray<PersistedFillableForm>): Array<{
|
|
51
75
|
fillRef: string;
|
|
52
76
|
scopeRef?: string;
|
|
53
77
|
purpose: string;
|
|
54
|
-
recommendedTiming?: 'late';
|
|
55
|
-
guidance?: FillableFormGuidanceHint;
|
|
56
78
|
fields: Array<{
|
|
57
79
|
fieldKey: string;
|
|
58
80
|
targetRef: string;
|
|
@@ -82,4 +104,5 @@ export declare function selectTargetsForGoalMatches(allTargets: ReadonlyArray<Do
|
|
|
82
104
|
};
|
|
83
105
|
export declare function buildExplicitScopeRefs(selectedSurfaceIds: ReadonlySet<string>, surfaceRefMap: ReadonlyMap<string, string>): Set<string>;
|
|
84
106
|
export declare function projectPersistedTargetsForGoal(domTargets: ReadonlyArray<DomObservedTarget>, persistedTargets: ReadonlyArray<TargetDescriptor>, selectedTargets: ReadonlyArray<DomObservedTarget>): TargetDescriptor[];
|
|
107
|
+
export {};
|
|
85
108
|
//# 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":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"observe-projection.d.ts","sourceRoot":"","sources":["../../src/commands/observe-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,98 @@
|
|
|
1
1
|
import { observedTargetKey } from './observe-semantics.js';
|
|
2
|
-
import { summarizeContext } from './observe-surfaces.js';
|
|
2
|
+
import { buildSyntheticFormSurfaceId, summarizeContext } from './observe-surfaces.js';
|
|
3
|
+
function normalizeClusterText(value) {
|
|
4
|
+
const normalized = value?.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
5
|
+
return normalized ? normalized : undefined;
|
|
6
|
+
}
|
|
7
|
+
function isActionLikeGoalTarget(target) {
|
|
8
|
+
const actions = target.allowedActions ?? [];
|
|
9
|
+
const kind = (target.kind ?? '').trim().toLowerCase();
|
|
10
|
+
const role = (target.role ?? '').trim().toLowerCase();
|
|
11
|
+
const isValueControl = actions.includes('fill') || actions.includes('type') || actions.includes('select');
|
|
12
|
+
if (isValueControl) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return (actions.includes('click') ||
|
|
16
|
+
actions.includes('press') ||
|
|
17
|
+
kind === 'button' ||
|
|
18
|
+
role === 'button' ||
|
|
19
|
+
kind === 'link' ||
|
|
20
|
+
role === 'link');
|
|
21
|
+
}
|
|
22
|
+
function goalActionClusterKey(target) {
|
|
23
|
+
const itemKey = normalizeClusterText(target.context?.item?.label ?? target.context?.item?.text);
|
|
24
|
+
const groupKey = normalizeClusterText(target.context?.group?.label ?? target.context?.group?.text);
|
|
25
|
+
const containerKey = normalizeClusterText(target.context?.container?.label ?? target.context?.container?.text);
|
|
26
|
+
const parts = [
|
|
27
|
+
target.surfaceRef ? `surface:${target.surfaceRef}` : undefined,
|
|
28
|
+
itemKey ? `item:${itemKey}` : undefined,
|
|
29
|
+
groupKey ? `group:${groupKey}` : undefined,
|
|
30
|
+
containerKey ? `container:${containerKey}` : undefined,
|
|
31
|
+
].filter((value) => Boolean(value));
|
|
32
|
+
return parts.length > 0 ? parts.join('|') : undefined;
|
|
33
|
+
}
|
|
34
|
+
function escapeRegExp(value) {
|
|
35
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
36
|
+
}
|
|
37
|
+
function stripSiblingLabels(value, siblingLabels) {
|
|
38
|
+
if (!value) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
let sanitized = value;
|
|
42
|
+
for (const label of siblingLabels) {
|
|
43
|
+
if (!label) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
sanitized = sanitized.replace(new RegExp(escapeRegExp(label), 'gi'), ' ');
|
|
47
|
+
}
|
|
48
|
+
const collapsed = sanitized.replace(/\s+[—-]\s+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
49
|
+
return collapsed || undefined;
|
|
50
|
+
}
|
|
51
|
+
function sanitizeGoalTargetContext(target, siblingLabelsByCluster) {
|
|
52
|
+
if (!isActionLikeGoalTarget(target)) {
|
|
53
|
+
return target;
|
|
54
|
+
}
|
|
55
|
+
const clusterKey = goalActionClusterKey(target);
|
|
56
|
+
if (!clusterKey) {
|
|
57
|
+
return target;
|
|
58
|
+
}
|
|
59
|
+
const ownLabel = normalizeClusterText(target.label);
|
|
60
|
+
const siblingLabels = (siblingLabelsByCluster.get(clusterKey) ?? []).filter((label) => label !== ownLabel);
|
|
61
|
+
if (siblingLabels.length === 0 || !target.context) {
|
|
62
|
+
return target;
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
...target,
|
|
66
|
+
context: {
|
|
67
|
+
...target.context,
|
|
68
|
+
item: target.context.item
|
|
69
|
+
? {
|
|
70
|
+
...target.context.item,
|
|
71
|
+
text: stripSiblingLabels(target.context.item.text, siblingLabels),
|
|
72
|
+
}
|
|
73
|
+
: target.context.item,
|
|
74
|
+
group: target.context.group
|
|
75
|
+
? {
|
|
76
|
+
...target.context.group,
|
|
77
|
+
text: stripSiblingLabels(target.context.group.text, siblingLabels),
|
|
78
|
+
}
|
|
79
|
+
: target.context.group,
|
|
80
|
+
container: target.context.container
|
|
81
|
+
? {
|
|
82
|
+
...target.context.container,
|
|
83
|
+
text: stripSiblingLabels(target.context.container.text, siblingLabels),
|
|
84
|
+
}
|
|
85
|
+
: target.context.container,
|
|
86
|
+
landmark: target.context.landmark
|
|
87
|
+
? {
|
|
88
|
+
...target.context.landmark,
|
|
89
|
+
text: stripSiblingLabels(target.context.landmark.text, siblingLabels),
|
|
90
|
+
}
|
|
91
|
+
: target.context.landmark,
|
|
92
|
+
hintText: stripSiblingLabels(target.context.hintText, siblingLabels),
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
3
96
|
export function compactTargets(targets) {
|
|
4
97
|
return targets.map((target) => ({
|
|
5
98
|
ref: target.ref,
|
|
@@ -17,6 +110,7 @@ export function compactTargets(targets) {
|
|
|
17
110
|
capability: target.capability,
|
|
18
111
|
availability: target.availability?.state,
|
|
19
112
|
availabilityReason: target.availability?.reason,
|
|
113
|
+
surfaceRef: target.surfaceRef,
|
|
20
114
|
source: target.semantics?.source,
|
|
21
115
|
}));
|
|
22
116
|
}
|
|
@@ -28,16 +122,69 @@ export function compactScopes(scopes) {
|
|
|
28
122
|
capability: 'scope',
|
|
29
123
|
availability: scope.availability?.state,
|
|
30
124
|
availabilityReason: scope.availability?.reason,
|
|
125
|
+
parentSurfaceRef: scope.parentSurfaceRef,
|
|
126
|
+
childSurfaceRefs: scope.childSurfaceRefs ? [...scope.childSurfaceRefs] : [],
|
|
127
|
+
targetRefs: scope.targetRefs ? [...scope.targetRefs] : [],
|
|
31
128
|
source: 'dom',
|
|
32
129
|
}));
|
|
33
130
|
}
|
|
131
|
+
function compactScopeSource(targets) {
|
|
132
|
+
return targets.find((target) => typeof target.source === 'string')?.source ?? 'dom';
|
|
133
|
+
}
|
|
134
|
+
export function buildGroupedObserveScopes(options) {
|
|
135
|
+
const compactedTargets = compactTargets(options.targets);
|
|
136
|
+
const scopeRefs = new Set(options.scopes.map((scope) => scope.ref));
|
|
137
|
+
const compactedTargetsByScope = new Map();
|
|
138
|
+
const unscopedTargets = [];
|
|
139
|
+
for (const target of compactedTargets) {
|
|
140
|
+
if (target.surfaceRef && scopeRefs.has(target.surfaceRef)) {
|
|
141
|
+
const grouped = compactedTargetsByScope.get(target.surfaceRef) ?? [];
|
|
142
|
+
grouped.push(target);
|
|
143
|
+
compactedTargetsByScope.set(target.surfaceRef, grouped);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
unscopedTargets.push(target);
|
|
147
|
+
}
|
|
148
|
+
const groupedScopes = options.scopes.map((scope) => {
|
|
149
|
+
const scopeTargets = compactedTargetsByScope.get(scope.ref) ?? [];
|
|
150
|
+
const visibleChildSurfaceRefs = (scope.childSurfaceRefs ?? []).filter((ref) => scopeRefs.has(ref));
|
|
151
|
+
return {
|
|
152
|
+
ref: scope.ref,
|
|
153
|
+
kind: scope.kind,
|
|
154
|
+
label: scope.label,
|
|
155
|
+
capability: 'scope',
|
|
156
|
+
availability: scope.availability?.state,
|
|
157
|
+
availabilityReason: scope.availability?.reason,
|
|
158
|
+
parentSurfaceRef: scope.parentSurfaceRef && scopeRefs.has(scope.parentSurfaceRef)
|
|
159
|
+
? scope.parentSurfaceRef
|
|
160
|
+
: undefined,
|
|
161
|
+
childSurfaceRefs: visibleChildSurfaceRefs,
|
|
162
|
+
targets: scopeTargets,
|
|
163
|
+
source: compactScopeSource(scopeTargets),
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
if (unscopedTargets.length === 0) {
|
|
167
|
+
return groupedScopes;
|
|
168
|
+
}
|
|
169
|
+
return [
|
|
170
|
+
...groupedScopes,
|
|
171
|
+
{
|
|
172
|
+
ref: `page:${options.pageRef}`,
|
|
173
|
+
kind: 'page',
|
|
174
|
+
label: options.title ?? 'Page',
|
|
175
|
+
capability: 'scope',
|
|
176
|
+
availability: 'available',
|
|
177
|
+
childSurfaceRefs: [],
|
|
178
|
+
targets: unscopedTargets,
|
|
179
|
+
source: compactScopeSource(unscopedTargets),
|
|
180
|
+
},
|
|
181
|
+
];
|
|
182
|
+
}
|
|
34
183
|
export function compactFillableForms(forms) {
|
|
35
184
|
return forms.map((form) => ({
|
|
36
185
|
fillRef: form.fillRef,
|
|
37
186
|
scopeRef: form.scopeRef,
|
|
38
187
|
purpose: form.purpose,
|
|
39
|
-
recommendedTiming: form.recommendedTiming,
|
|
40
|
-
guidance: form.guidance,
|
|
41
188
|
fields: form.fields.map((field) => ({
|
|
42
189
|
fieldKey: field.fieldKey,
|
|
43
190
|
targetRef: field.targetRef,
|
|
@@ -64,11 +211,42 @@ export function compactSignals(signals) {
|
|
|
64
211
|
}));
|
|
65
212
|
}
|
|
66
213
|
export function buildGoalObserveInventoryCandidates(targets, surfaces) {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
214
|
+
const siblingLabelsByCluster = new Map();
|
|
215
|
+
for (const target of targets) {
|
|
216
|
+
if (!isActionLikeGoalTarget(target)) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const clusterKey = goalActionClusterKey(target);
|
|
220
|
+
const normalizedLabel = normalizeClusterText(target.label);
|
|
221
|
+
if (!clusterKey || !normalizedLabel) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const labels = siblingLabelsByCluster.get(clusterKey) ?? [];
|
|
225
|
+
if (!labels.includes(normalizedLabel)) {
|
|
226
|
+
labels.push(normalizedLabel);
|
|
227
|
+
siblingLabelsByCluster.set(clusterKey, labels);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const targetCandidates = targets.map((target) => {
|
|
231
|
+
const sanitized = sanitizeGoalTargetContext(target, siblingLabelsByCluster);
|
|
232
|
+
const syntheticFormSurfaceId = buildSyntheticFormSurfaceId(sanitized);
|
|
233
|
+
const surfaceRef = sanitized.surfaceRef ?? syntheticFormSurfaceId;
|
|
234
|
+
const surfaceKind = sanitized.surfaceKind ?? (syntheticFormSurfaceId ? 'form' : undefined);
|
|
235
|
+
const surfaceLabel = sanitized.surfaceLabel ??
|
|
236
|
+
(syntheticFormSurfaceId
|
|
237
|
+
? sanitized.context?.landmark?.label ?? sanitized.context?.group?.label ?? 'Form'
|
|
238
|
+
: undefined);
|
|
239
|
+
const surfacePriority = sanitized.surfacePriority ?? (surfaceKind === 'form' ? 70 : undefined);
|
|
240
|
+
return {
|
|
241
|
+
...sanitized,
|
|
242
|
+
surfaceRef,
|
|
243
|
+
surfaceKind,
|
|
244
|
+
surfaceLabel,
|
|
245
|
+
surfacePriority,
|
|
246
|
+
goalInventoryType: 'target',
|
|
247
|
+
goalTargetKey: observedTargetKey(target),
|
|
248
|
+
};
|
|
249
|
+
});
|
|
72
250
|
const scopeCandidates = surfaces.map((surface) => {
|
|
73
251
|
const linkedTargets = targets.filter((target) => target.surfaceRef === surface.surfaceId);
|
|
74
252
|
const primaryLinkedTarget = linkedTargets[0];
|
|
@@ -134,7 +312,9 @@ export function selectTargetsForGoalMatches(allTargets, rerankedCandidates) {
|
|
|
134
312
|
const scopeTargets = allTargets.filter((target) => {
|
|
135
313
|
const directMatch = typeof target.ordinal === 'number' && directTargetOrdinals.has(target.ordinal);
|
|
136
314
|
const directKeyMatch = directTargetKeys.has(observedTargetKey(target));
|
|
137
|
-
const
|
|
315
|
+
const syntheticFormSurfaceId = buildSyntheticFormSurfaceId(target);
|
|
316
|
+
const scopeMatch = (target.surfaceRef ? selectedSurfaceIds.has(target.surfaceRef) : false) ||
|
|
317
|
+
(syntheticFormSurfaceId ? selectedSurfaceIds.has(syntheticFormSurfaceId) : false);
|
|
138
318
|
if (directMatch || directKeyMatch) {
|
|
139
319
|
return false;
|
|
140
320
|
}
|
|
@@ -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;AAkFD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CA6BrB;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,
|
|
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;AAkFD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CA6BrB;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,CAiEjG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAsFrB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { inferAcceptancePolicyFromFacts, inferAllowedActionsFromFacts, inferAvailabilityFromFacts, inferControlFamilyFromFacts, } from '../control-semantics.js';
|
|
2
|
-
import { buildSurfaceRef } from './observe-surfaces.js';
|
|
2
|
+
import { buildSurfaceRef, buildSyntheticFormSurfaceId } from './observe-surfaces.js';
|
|
3
3
|
export function normalizeSemanticDuplicateLabel(target) {
|
|
4
4
|
return (target.displayLabel ??
|
|
5
5
|
target.label ??
|
|
@@ -299,9 +299,20 @@ export function annotateDomTargets(targets) {
|
|
|
299
299
|
const availability = inferAvailability(target);
|
|
300
300
|
const capability = inferCapability(target, allowedActions);
|
|
301
301
|
const acceptancePolicy = inferAcceptancePolicy(target, allowedActions);
|
|
302
|
-
const
|
|
302
|
+
const explicitSurfaceRef = buildSurfaceRef(target);
|
|
303
|
+
const syntheticFormSurfaceRef = explicitSurfaceRef === undefined ? buildSyntheticFormSurfaceId(target) : undefined;
|
|
304
|
+
const surfaceRef = explicitSurfaceRef ?? syntheticFormSurfaceRef;
|
|
305
|
+
const surfaceKind = target.surfaceKind ?? (syntheticFormSurfaceRef ? 'form' : undefined);
|
|
306
|
+
const surfaceLabel = target.surfaceLabel ??
|
|
307
|
+
(syntheticFormSurfaceRef
|
|
308
|
+
? target.context?.landmark?.label ?? target.context?.group?.label ?? 'Form'
|
|
309
|
+
: undefined);
|
|
310
|
+
const surfacePriority = target.surfacePriority ?? (surfaceKind === 'form' ? 70 : undefined);
|
|
303
311
|
return {
|
|
304
312
|
...target,
|
|
313
|
+
surfaceKind,
|
|
314
|
+
surfaceLabel,
|
|
315
|
+
surfacePriority,
|
|
305
316
|
capability,
|
|
306
317
|
availability,
|
|
307
318
|
allowedActions,
|
|
@@ -2,6 +2,7 @@ import type { LocatorCandidate, SurfaceDescriptor, TargetContext, TargetDescript
|
|
|
2
2
|
import type { DomObservedTarget } from './observe-inventory.js';
|
|
3
3
|
export declare function selectScopesForOutput(scopes: ReadonlyArray<SurfaceDescriptor>, targets: ReadonlyArray<Pick<TargetDescriptor, 'surfaceRef' | 'allowedActions' | 'acceptancePolicy'>>, preferredScopeRefs?: ReadonlySet<string>): SurfaceDescriptor[];
|
|
4
4
|
export declare function buildSurfaceRef(target: DomObservedTarget): string | undefined;
|
|
5
|
+
export declare function buildSyntheticFormSurfaceId(target: Pick<DomObservedTarget, 'pageSignature' | 'framePath' | 'frameUrl' | 'formSelector' | 'context'>): string | undefined;
|
|
5
6
|
export declare function surfaceReplacementKey(surface: Pick<SurfaceDescriptor, 'pageRef' | 'pageSignature' | 'framePath' | 'kind' | 'label'>): string;
|
|
6
7
|
export declare function summarizeContext(context: TargetContext | undefined): string | undefined;
|
|
7
8
|
export declare function pushUniqueLocatorCandidate(acc: LocatorCandidate[], candidate: LocatorCandidate | undefined): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe-surfaces.d.ts","sourceRoot":"","sources":["../../src/commands/observe-surfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"observe-surfaces.d.ts","sourceRoot":"","sources":["../../src/commands/observe-surfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAgBhE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACxC,OAAO,EAAE,aAAa,CACpB,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,CAC7E,EACD,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GACvC,iBAAiB,EAAE,CA+CrB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAa7E;AAyBD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC,GACvG,MAAM,GAAG,SAAS,CAiBpB;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,eAAe,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC,GAC7F,MAAM,CAMR;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CA4CvF;AAED,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,gBAAgB,EAAE,EACvB,SAAS,EAAE,gBAAgB,GAAG,SAAS,GACtC,IAAI,CAON;AAwDD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,oCAoE1C"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { locatorCandidateKey } from '../runtime-state.js';
|
|
2
2
|
const HIGH_SIGNAL_SCOPE_KINDS = new Set([
|
|
3
|
+
'form',
|
|
3
4
|
'dialog',
|
|
4
5
|
'listbox',
|
|
5
6
|
'menu',
|
|
@@ -8,6 +9,8 @@ const HIGH_SIGNAL_SCOPE_KINDS = new Set([
|
|
|
8
9
|
'popover',
|
|
9
10
|
'dropdown',
|
|
10
11
|
'datepicker',
|
|
12
|
+
'floating-panel',
|
|
13
|
+
'sticky-panel',
|
|
11
14
|
]);
|
|
12
15
|
export function selectScopesForOutput(scopes, targets, preferredScopeRefs) {
|
|
13
16
|
if (scopes.length === 0) {
|
|
@@ -63,6 +66,39 @@ export function buildSurfaceRef(target) {
|
|
|
63
66
|
target.surfaceLabel ?? '',
|
|
64
67
|
].join('|');
|
|
65
68
|
}
|
|
69
|
+
function normalizeSurfaceText(value) {
|
|
70
|
+
const normalized = value?.replace(/\s+/g, ' ').trim();
|
|
71
|
+
return normalized ? normalized : undefined;
|
|
72
|
+
}
|
|
73
|
+
function semanticFormContextLabel(target) {
|
|
74
|
+
for (const node of [
|
|
75
|
+
target.context?.landmark,
|
|
76
|
+
target.context?.container,
|
|
77
|
+
target.context?.group,
|
|
78
|
+
target.context?.item,
|
|
79
|
+
]) {
|
|
80
|
+
const kind = (node?.kind ?? '').trim().toLowerCase();
|
|
81
|
+
if (kind !== 'form') {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
return normalizeSurfaceText(node?.label ?? node?.text);
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
export function buildSyntheticFormSurfaceId(target) {
|
|
89
|
+
const pageKey = normalizeSurfaceText(target.pageSignature);
|
|
90
|
+
if (!pageKey) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const formKey = normalizeSurfaceText(target.formSelector) ??
|
|
94
|
+
semanticFormContextLabel(target)?.toLowerCase();
|
|
95
|
+
if (!formKey) {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
const frameKey = target.framePath?.join('>') ??
|
|
99
|
+
(normalizeSurfaceText(target.frameUrl) ? `url:${normalizeSurfaceText(target.frameUrl)}` : 'top');
|
|
100
|
+
return `${pageKey}|${frameKey}|form|${formKey}`;
|
|
101
|
+
}
|
|
66
102
|
export function surfaceReplacementKey(surface) {
|
|
67
103
|
const pageKey = surface.pageSignature ?? surface.pageRef;
|
|
68
104
|
const frameKey = surface.framePath?.join('>') ?? 'top';
|
|
@@ -191,5 +227,34 @@ export function collectSurfaceDescriptors(pageRef, targets) {
|
|
|
191
227
|
pageSignature: existing?.pageSignature ?? target.pageSignature,
|
|
192
228
|
});
|
|
193
229
|
}
|
|
230
|
+
for (const target of targets) {
|
|
231
|
+
const surfaceId = buildSyntheticFormSurfaceId(target);
|
|
232
|
+
if (!surfaceId) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const existing = descriptors.get(surfaceId);
|
|
236
|
+
const locatorCandidates = existing ? [...existing.locatorCandidates] : [];
|
|
237
|
+
const formSelector = target.formSelector?.trim();
|
|
238
|
+
if (formSelector) {
|
|
239
|
+
pushUniqueLocatorCandidate(locatorCandidates, {
|
|
240
|
+
strategy: formSelector.startsWith('xpath=') ? 'xpath' : 'css',
|
|
241
|
+
value: formSelector,
|
|
242
|
+
scope: 'root',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
descriptors.set(surfaceId, {
|
|
246
|
+
surfaceId,
|
|
247
|
+
pageRef,
|
|
248
|
+
framePath: existing?.framePath ?? target.framePath,
|
|
249
|
+
frameUrl: existing?.frameUrl ?? target.frameUrl,
|
|
250
|
+
kind: 'form',
|
|
251
|
+
label: existing?.label ?? semanticFormContextLabel(target) ?? 'Form',
|
|
252
|
+
lifecycle: 'live',
|
|
253
|
+
availability: { state: 'available' },
|
|
254
|
+
locatorCandidates,
|
|
255
|
+
createdAt: existing?.createdAt ?? Date.now(),
|
|
256
|
+
pageSignature: existing?.pageSignature ?? target.pageSignature,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
194
259
|
return [...descriptors.values()];
|
|
195
260
|
}
|
|
@@ -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;AAgDnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,eAAO,MAAM,yBAAyB;;;;
|
|
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;AAgDnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,eAAO,MAAM,yBAAyB;;;;iBAyR+wD,CAAC;gBAAwB,CAAC;;;;;iBAAirzE,CAAC;gBAAwB,CAAC;;;CAzRr92E,CAAC;AACtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGrC,CAAC;AAEF,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkRzF"}
|