@nuanu-ai/agentbrowse 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -8
- package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
- package/dist/agentpay-stagehand-llm.js +5 -1
- package/dist/commands/act.d.ts +6 -2
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +840 -55
- package/dist/commands/act.test-harness.d.ts +19 -0
- package/dist/commands/act.test-harness.d.ts.map +1 -0
- package/dist/commands/act.test-harness.js +245 -0
- package/dist/commands/action-acceptance.d.ts +90 -0
- package/dist/commands/action-acceptance.d.ts.map +1 -0
- package/dist/commands/action-acceptance.js +1411 -0
- package/dist/commands/action-artifacts.d.ts +33 -0
- package/dist/commands/action-artifacts.d.ts.map +1 -0
- package/dist/commands/action-artifacts.js +104 -0
- package/dist/commands/action-execution-guards.d.ts +5 -0
- package/dist/commands/action-execution-guards.d.ts.map +1 -0
- package/dist/commands/action-execution-guards.js +3 -0
- package/dist/commands/action-executor-helpers.d.ts +21 -0
- package/dist/commands/action-executor-helpers.d.ts.map +1 -0
- package/dist/commands/action-executor-helpers.js +242 -0
- package/dist/commands/action-executor.d.ts +12 -0
- package/dist/commands/action-executor.d.ts.map +1 -0
- package/dist/commands/action-executor.js +45 -0
- package/dist/commands/action-fallbacks.d.ts +6 -0
- package/dist/commands/action-fallbacks.d.ts.map +1 -0
- package/dist/commands/action-fallbacks.js +43 -0
- package/dist/commands/action-value-projection.d.ts +32 -0
- package/dist/commands/action-value-projection.d.ts.map +1 -0
- package/dist/commands/action-value-projection.js +151 -0
- package/dist/commands/browse-actions.d.ts +4 -0
- package/dist/commands/browse-actions.d.ts.map +1 -0
- package/dist/commands/browse-actions.js +4 -0
- package/dist/commands/captcha-solve.d.ts.map +1 -1
- package/dist/commands/captcha-solve.js +13 -3
- package/dist/commands/click-action-executor.d.ts +10 -0
- package/dist/commands/click-action-executor.d.ts.map +1 -0
- package/dist/commands/click-action-executor.js +68 -0
- package/dist/commands/create-intent.d.ts +6 -0
- package/dist/commands/create-intent.d.ts.map +1 -0
- package/dist/commands/create-intent.js +75 -0
- package/dist/commands/datepicker-action-executor.d.ts +12 -0
- package/dist/commands/datepicker-action-executor.d.ts.map +1 -0
- package/dist/commands/datepicker-action-executor.js +218 -0
- package/dist/commands/descriptor-validation.d.ts +27 -0
- package/dist/commands/descriptor-validation.d.ts.map +1 -0
- package/dist/commands/descriptor-validation.js +333 -0
- package/dist/commands/extract-scope-resolution.d.ts +20 -0
- package/dist/commands/extract-scope-resolution.d.ts.map +1 -0
- package/dist/commands/extract-scope-resolution.js +100 -0
- package/dist/commands/extract-stagehand-executor.d.ts +17 -0
- package/dist/commands/extract-stagehand-executor.d.ts.map +1 -0
- package/dist/commands/extract-stagehand-executor.js +18 -0
- package/dist/commands/extract.d.ts +3 -2
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +256 -39
- package/dist/commands/fill-secret.d.ts +7 -0
- package/dist/commands/fill-secret.d.ts.map +1 -0
- package/dist/commands/fill-secret.js +371 -0
- package/dist/commands/get-secrets-catalog.d.ts +6 -0
- package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
- package/dist/commands/get-secrets-catalog.js +23 -0
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +41 -7
- package/dist/commands/navigate.d.ts +2 -1
- package/dist/commands/navigate.d.ts.map +1 -1
- package/dist/commands/navigate.js +49 -12
- package/dist/commands/observe-inventory.d.ts +109 -0
- package/dist/commands/observe-inventory.d.ts.map +1 -0
- package/dist/commands/observe-inventory.js +2837 -0
- package/dist/commands/observe-persistence.d.ts +14 -0
- package/dist/commands/observe-persistence.d.ts.map +1 -0
- package/dist/commands/observe-persistence.js +170 -0
- package/dist/commands/observe-projection.d.ts +84 -0
- package/dist/commands/observe-projection.d.ts.map +1 -0
- package/dist/commands/observe-projection.js +140 -0
- package/dist/commands/observe-protected.d.ts +5 -0
- package/dist/commands/observe-protected.d.ts.map +1 -0
- package/dist/commands/observe-protected.js +18 -0
- package/dist/commands/observe-semantics.d.ts +10 -0
- package/dist/commands/observe-semantics.d.ts.map +1 -0
- package/dist/commands/observe-semantics.js +338 -0
- package/dist/commands/observe-stagehand.d.ts +48 -0
- package/dist/commands/observe-stagehand.d.ts.map +1 -0
- package/dist/commands/observe-stagehand.js +105 -0
- package/dist/commands/observe-surfaces.d.ts +9 -0
- package/dist/commands/observe-surfaces.d.ts.map +1 -0
- package/dist/commands/observe-surfaces.js +195 -0
- package/dist/commands/observe.d.ts +47 -1
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +173 -20
- package/dist/commands/observe.test-harness.d.ts +67 -0
- package/dist/commands/observe.test-harness.d.ts.map +1 -0
- package/dist/commands/observe.test-harness.js +107 -0
- package/dist/commands/poll-intent.d.ts +6 -0
- package/dist/commands/poll-intent.d.ts.map +1 -0
- package/dist/commands/poll-intent.js +57 -0
- package/dist/commands/screenshot.d.ts +2 -1
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/commands/screenshot.js +44 -12
- package/dist/commands/select-action-executor.d.ts +10 -0
- package/dist/commands/select-action-executor.d.ts.map +1 -0
- package/dist/commands/select-action-executor.js +91 -0
- package/dist/commands/semantic-observe.d.ts +24 -0
- package/dist/commands/semantic-observe.d.ts.map +1 -0
- package/dist/commands/semantic-observe.js +344 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +75 -2
- package/dist/commands/structured-grid-action-executor.d.ts +3 -0
- package/dist/commands/structured-grid-action-executor.d.ts.map +1 -0
- package/dist/commands/structured-grid-action-executor.js +4 -0
- package/dist/commands/target-resolution.d.ts +4 -0
- package/dist/commands/target-resolution.d.ts.map +1 -0
- package/dist/commands/target-resolution.js +33 -0
- package/dist/commands/text-input-action-executor.d.ts +5 -0
- package/dist/commands/text-input-action-executor.d.ts.map +1 -0
- package/dist/commands/text-input-action-executor.js +116 -0
- package/dist/commands/user-actionable.d.ts +4 -0
- package/dist/commands/user-actionable.d.ts.map +1 -0
- package/dist/commands/user-actionable.js +95 -0
- package/dist/control-semantics.d.ts +29 -0
- package/dist/control-semantics.d.ts.map +1 -0
- package/dist/control-semantics.js +299 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +95 -32
- package/dist/output.d.ts +14 -2
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +17 -29
- package/dist/playwright-runtime.d.ts +35 -0
- package/dist/playwright-runtime.d.ts.map +1 -0
- package/dist/playwright-runtime.js +224 -0
- package/dist/runtime-resolution.d.ts +9 -0
- package/dist/runtime-resolution.d.ts.map +1 -0
- package/dist/runtime-resolution.js +19 -0
- package/dist/runtime-state.d.ts +217 -0
- package/dist/runtime-state.d.ts.map +1 -0
- package/dist/runtime-state.js +629 -0
- package/dist/secrets/backend.d.ts +32 -0
- package/dist/secrets/backend.d.ts.map +1 -0
- package/dist/secrets/backend.js +169 -0
- package/dist/secrets/catalog-applicability.d.ts +5 -0
- package/dist/secrets/catalog-applicability.d.ts.map +1 -0
- package/dist/secrets/catalog-applicability.js +59 -0
- package/dist/secrets/catalog-sync.d.ts +14 -0
- package/dist/secrets/catalog-sync.d.ts.map +1 -0
- package/dist/secrets/catalog-sync.js +35 -0
- package/dist/secrets/field-policy.d.ts +3 -0
- package/dist/secrets/field-policy.d.ts.map +1 -0
- package/dist/secrets/field-policy.js +3 -0
- package/dist/secrets/fill-ordering.d.ts +11 -0
- package/dist/secrets/fill-ordering.d.ts.map +1 -0
- package/dist/secrets/fill-ordering.js +44 -0
- package/dist/secrets/form-matcher.d.ts +60 -0
- package/dist/secrets/form-matcher.d.ts.map +1 -0
- package/dist/secrets/form-matcher.js +596 -0
- package/dist/secrets/intent-output.d.ts +11 -0
- package/dist/secrets/intent-output.d.ts.map +1 -0
- package/dist/secrets/intent-output.js +64 -0
- package/dist/secrets/mock-agentpay-backend.d.ts +13 -0
- package/dist/secrets/mock-agentpay-backend.d.ts.map +1 -0
- package/dist/secrets/mock-agentpay-backend.js +87 -0
- package/dist/secrets/mock-agentpay-cabinet.d.ts +43 -0
- package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -0
- package/dist/secrets/mock-agentpay-cabinet.js +195 -0
- package/dist/secrets/protected-artifact-guard.d.ts +25 -0
- package/dist/secrets/protected-artifact-guard.d.ts.map +1 -0
- package/dist/secrets/protected-artifact-guard.js +26 -0
- package/dist/secrets/protected-bindings.d.ts +10 -0
- package/dist/secrets/protected-bindings.d.ts.map +1 -0
- package/dist/secrets/protected-bindings.js +17 -0
- package/dist/secrets/protected-field-values.d.ts +13 -0
- package/dist/secrets/protected-field-values.d.ts.map +1 -0
- package/dist/secrets/protected-field-values.js +100 -0
- package/dist/secrets/protected-fill.d.ts +47 -0
- package/dist/secrets/protected-fill.d.ts.map +1 -0
- package/dist/secrets/protected-fill.js +512 -0
- package/dist/secrets/types.d.ts +84 -0
- package/dist/secrets/types.d.ts.map +1 -0
- package/dist/secrets/types.js +27 -0
- package/dist/session.d.ts +22 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +74 -2
- package/dist/solver/browser-launcher.d.ts.map +1 -1
- package/dist/solver/browser-launcher.js +6 -3
- package/dist/stagehand-runtime.d.ts +4 -0
- package/dist/stagehand-runtime.d.ts.map +1 -0
- package/dist/stagehand-runtime.js +10 -0
- package/dist/stagehand.d.ts +0 -5
- package/dist/stagehand.d.ts.map +1 -1
- package/dist/stagehand.js +0 -6
- package/package.json +5 -2
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
import { getSurface, getTarget } from '../runtime-state.js';
|
|
2
|
+
import { createAcceptanceProbe, rankLocatorCandidates, waitForAcceptanceProbe, } from '../commands/action-acceptance.js';
|
|
3
|
+
import { buildLocator, resolveLocatorRoot } from '../commands/action-fallbacks.js';
|
|
4
|
+
import { applyActionWithFallbacks } from '../commands/action-executor.js';
|
|
5
|
+
import { normalizePageSignature, readLocatorDomSignature } from '../commands/descriptor-validation.js';
|
|
6
|
+
import { resolveSurfaceScopeRoot } from '../commands/target-resolution.js';
|
|
7
|
+
import { resolveProtectedFieldPolicy } from './field-policy.js';
|
|
8
|
+
import { protectedBindingKey } from './protected-bindings.js';
|
|
9
|
+
import { resolveAssistedProtectedFieldValues } from './protected-field-values.js';
|
|
10
|
+
import { sortProtectedBindingsForExecution } from './fill-ordering.js';
|
|
11
|
+
function targetUsesSurfaceAsPrimaryLocator(target, surface) {
|
|
12
|
+
const surfaceCandidateKeys = new Set(surface.locatorCandidates.map((candidate) => [candidate.strategy, candidate.name ?? '', candidate.value, candidate.attribute ?? '', candidate.scope ?? ''].join(':')));
|
|
13
|
+
return target.locatorCandidates.some((candidate) => surfaceCandidateKeys.has([candidate.strategy, candidate.name ?? '', candidate.value, candidate.attribute ?? '', candidate.scope ?? ''].join(':')));
|
|
14
|
+
}
|
|
15
|
+
function resolveLocatorRootForCandidate(baseRoot, defaultRoot, surfaceRoot, scope) {
|
|
16
|
+
if (scope === 'root') {
|
|
17
|
+
return baseRoot;
|
|
18
|
+
}
|
|
19
|
+
if (scope === 'surface') {
|
|
20
|
+
return surfaceRoot;
|
|
21
|
+
}
|
|
22
|
+
return defaultRoot;
|
|
23
|
+
}
|
|
24
|
+
async function prepareLocator(locator, action, strategy, attempts, options) {
|
|
25
|
+
const count = await locator.count().catch(() => 0);
|
|
26
|
+
if (count === 0) {
|
|
27
|
+
attempts.push(`resolve.skip:${strategy}:empty`);
|
|
28
|
+
return { locator: null };
|
|
29
|
+
}
|
|
30
|
+
if (count > 1) {
|
|
31
|
+
attempts.push(`resolve.skip:${strategy}:ambiguous:${count}`);
|
|
32
|
+
return { locator: null };
|
|
33
|
+
}
|
|
34
|
+
const resolvedLocator = locator.first();
|
|
35
|
+
const visible = await resolvedLocator.isVisible().catch(() => false);
|
|
36
|
+
if (!visible) {
|
|
37
|
+
attempts.push(`resolve.skip:${strategy}:hidden`);
|
|
38
|
+
return { locator: null };
|
|
39
|
+
}
|
|
40
|
+
const disabled = await resolvedLocator.isDisabled?.().catch(() => false);
|
|
41
|
+
if (disabled) {
|
|
42
|
+
attempts.push(`resolve.skip:${strategy}:disabled`);
|
|
43
|
+
return { locator: null, blockedReason: 'disabled' };
|
|
44
|
+
}
|
|
45
|
+
if (action === 'fill' || action === 'type') {
|
|
46
|
+
const editable = await resolvedLocator.isEditable().catch(() => false);
|
|
47
|
+
if (!editable) {
|
|
48
|
+
const descendants = resolvedLocator.locator('input:not([type="hidden"]), textarea, select, [contenteditable="true"]');
|
|
49
|
+
const descendantCount = await descendants.count().catch(() => 0);
|
|
50
|
+
const visibleEditableDescendants = [];
|
|
51
|
+
for (let index = 0; index < descendantCount; index += 1) {
|
|
52
|
+
const descendant = descendants.nth(index);
|
|
53
|
+
const descendantVisible = await descendant.isVisible().catch(() => false);
|
|
54
|
+
if (!descendantVisible) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const descendantEditable = await descendant.isEditable().catch(() => false);
|
|
58
|
+
if (!descendantEditable) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
visibleEditableDescendants.push(descendant);
|
|
62
|
+
}
|
|
63
|
+
if (visibleEditableDescendants.length === 1) {
|
|
64
|
+
attempts.push(`resolve.descendant-editable:${strategy}`);
|
|
65
|
+
return { locator: visibleEditableDescendants[0] ?? null };
|
|
66
|
+
}
|
|
67
|
+
if (visibleEditableDescendants.length > 1) {
|
|
68
|
+
attempts.push(`resolve.skip:${strategy}:descendant-ambiguous:${visibleEditableDescendants.length}`);
|
|
69
|
+
return { locator: null };
|
|
70
|
+
}
|
|
71
|
+
const readonly = await resolvedLocator
|
|
72
|
+
.getAttribute?.('readonly')
|
|
73
|
+
.then((value) => value !== null)
|
|
74
|
+
.catch(() => false);
|
|
75
|
+
if (readonly && !options?.allowReadonlyFallback) {
|
|
76
|
+
attempts.push(`resolve.skip:${strategy}:readonly`);
|
|
77
|
+
return { locator: null, blockedReason: 'readonly' };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { locator: resolvedLocator };
|
|
82
|
+
}
|
|
83
|
+
function actionForTarget(target) {
|
|
84
|
+
if (target.controlFamily === 'select') {
|
|
85
|
+
return 'select';
|
|
86
|
+
}
|
|
87
|
+
if (target.allowedActions.includes('fill')) {
|
|
88
|
+
return 'fill';
|
|
89
|
+
}
|
|
90
|
+
if (target.allowedActions.includes('type')) {
|
|
91
|
+
return 'type';
|
|
92
|
+
}
|
|
93
|
+
if (target.allowedActions.includes('select')) {
|
|
94
|
+
return 'select';
|
|
95
|
+
}
|
|
96
|
+
return 'fill';
|
|
97
|
+
}
|
|
98
|
+
function formatCardExpiry(month, year) {
|
|
99
|
+
const normalizedMonth = month.trim().padStart(2, '0');
|
|
100
|
+
const normalizedYear = year.trim().length > 2 ? year.trim().slice(-2) : year.trim().padStart(2, '0');
|
|
101
|
+
return `${normalizedMonth}/${normalizedYear}`;
|
|
102
|
+
}
|
|
103
|
+
function resolveBindingValue(fields, protectedValues, fieldPolicies, assistedValues) {
|
|
104
|
+
if (fields.length === 1) {
|
|
105
|
+
const field = fields[0];
|
|
106
|
+
const policy = resolveProtectedFieldPolicy(fieldPolicies, field.fieldKey);
|
|
107
|
+
if (policy === 'llm_assisted') {
|
|
108
|
+
const assistedValue = assistedValues.get(protectedBindingKey(field));
|
|
109
|
+
if (typeof assistedValue === 'string' && assistedValue.length > 0) {
|
|
110
|
+
return assistedValue;
|
|
111
|
+
}
|
|
112
|
+
throw new Error('assisted_value_resolution_failed');
|
|
113
|
+
}
|
|
114
|
+
if ((field.valueHint ?? 'direct') !== 'direct') {
|
|
115
|
+
throw new Error('deterministic_only_resolution_failed');
|
|
116
|
+
}
|
|
117
|
+
const value = protectedValues[field.fieldKey];
|
|
118
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
throw new Error('missing_protected_value');
|
|
122
|
+
}
|
|
123
|
+
const includesExpiry = fields.some((field) => field.fieldKey === 'exp_month') &&
|
|
124
|
+
fields.some((field) => field.fieldKey === 'exp_year') &&
|
|
125
|
+
fields.length === 2;
|
|
126
|
+
if (includesExpiry) {
|
|
127
|
+
const month = protectedValues.exp_month;
|
|
128
|
+
const year = protectedValues.exp_year;
|
|
129
|
+
if (typeof month === 'string' &&
|
|
130
|
+
month.length > 0 &&
|
|
131
|
+
typeof year === 'string' &&
|
|
132
|
+
year.length > 0) {
|
|
133
|
+
return formatCardExpiry(month, year);
|
|
134
|
+
}
|
|
135
|
+
throw new Error('missing_protected_value');
|
|
136
|
+
}
|
|
137
|
+
throw new Error('unsupported_protected_field_group');
|
|
138
|
+
}
|
|
139
|
+
function flattenFilledFields(fieldKeys, targetRef) {
|
|
140
|
+
return fieldKeys.map((fieldKey) => ({
|
|
141
|
+
fieldKey,
|
|
142
|
+
targetRef,
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
function buildProtectedValidationDetails(validationText) {
|
|
146
|
+
return validationText ? { validationTextRedacted: true } : {};
|
|
147
|
+
}
|
|
148
|
+
function shouldIgnoreNativeInvalidForTarget(target) {
|
|
149
|
+
return Array.isArray(target.framePath) && target.framePath.length > 0;
|
|
150
|
+
}
|
|
151
|
+
async function readValidationState(locator) {
|
|
152
|
+
const payload = await locator
|
|
153
|
+
.evaluate((element) => {
|
|
154
|
+
if (!(element instanceof HTMLElement)) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
const maybeControl = element instanceof HTMLInputElement ||
|
|
158
|
+
element instanceof HTMLTextAreaElement ||
|
|
159
|
+
element instanceof HTMLSelectElement
|
|
160
|
+
? element
|
|
161
|
+
: null;
|
|
162
|
+
const validationMessage = maybeControl?.validationMessage?.trim() ?? '';
|
|
163
|
+
const describedByIds = (element.getAttribute('aria-describedby') ?? '')
|
|
164
|
+
.split(/\s+/)
|
|
165
|
+
.map((value) => value.trim())
|
|
166
|
+
.filter(Boolean);
|
|
167
|
+
const describedByText = describedByIds
|
|
168
|
+
.map((id) => element.ownerDocument?.getElementById(id)?.textContent?.trim() ?? '')
|
|
169
|
+
.filter(Boolean)
|
|
170
|
+
.join(' ');
|
|
171
|
+
const ariaInvalid = element.getAttribute('aria-invalid') === 'true';
|
|
172
|
+
const candidate = validationMessage || describedByText || '';
|
|
173
|
+
return {
|
|
174
|
+
validationText: candidate || undefined,
|
|
175
|
+
ariaInvalid,
|
|
176
|
+
invalid: ariaInvalid ||
|
|
177
|
+
Boolean(maybeControl &&
|
|
178
|
+
typeof maybeControl.checkValidity === 'function' &&
|
|
179
|
+
maybeControl.checkValidity() === false),
|
|
180
|
+
};
|
|
181
|
+
})
|
|
182
|
+
.catch(() => null);
|
|
183
|
+
if (!payload) {
|
|
184
|
+
return {
|
|
185
|
+
invalid: false,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
invalid: payload.invalid,
|
|
190
|
+
validationText: payload.validationText ||
|
|
191
|
+
(payload.ariaInvalid ? 'Field rejected by client-side validation.' : undefined),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function groupBindingsByTarget(fillableForm, session) {
|
|
195
|
+
const grouped = new Map();
|
|
196
|
+
for (const field of fillableForm.fields) {
|
|
197
|
+
const target = getTarget(session, field.targetRef);
|
|
198
|
+
if (!target) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
const existing = grouped.get(field.targetRef);
|
|
202
|
+
if (existing) {
|
|
203
|
+
existing.fields.push(field);
|
|
204
|
+
existing.fieldKeys.push(field.fieldKey);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
grouped.set(field.targetRef, {
|
|
208
|
+
targetRef: field.targetRef,
|
|
209
|
+
fields: [field],
|
|
210
|
+
fieldKeys: [field.fieldKey],
|
|
211
|
+
target,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return sortProtectedBindingsForExecution(fillableForm.purpose, [...grouped.values()]);
|
|
215
|
+
}
|
|
216
|
+
async function prepareBindings(session, page, fillableForm) {
|
|
217
|
+
const groupedBindings = groupBindingsByTarget(fillableForm, session);
|
|
218
|
+
if (!groupedBindings) {
|
|
219
|
+
const firstField = fillableForm.fields[0];
|
|
220
|
+
return {
|
|
221
|
+
kind: 'binding_stale',
|
|
222
|
+
targetRef: firstField?.targetRef ?? 'unknown',
|
|
223
|
+
fieldKeys: firstField ? [firstField.fieldKey] : [],
|
|
224
|
+
reason: 'target_missing',
|
|
225
|
+
attempts: [],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const preparedBindings = [];
|
|
229
|
+
for (const binding of groupedBindings) {
|
|
230
|
+
const attempts = [];
|
|
231
|
+
const { target } = binding;
|
|
232
|
+
if (target.lifecycle !== 'live') {
|
|
233
|
+
return {
|
|
234
|
+
kind: 'binding_stale',
|
|
235
|
+
targetRef: binding.targetRef,
|
|
236
|
+
fieldKeys: [...binding.fieldKeys],
|
|
237
|
+
reason: 'target_not_live',
|
|
238
|
+
attempts,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
if (target.pageSignature && normalizePageSignature(page.url()) !== target.pageSignature) {
|
|
242
|
+
attempts.push('stale.page-signature:before-fill');
|
|
243
|
+
return {
|
|
244
|
+
kind: 'binding_stale',
|
|
245
|
+
targetRef: binding.targetRef,
|
|
246
|
+
fieldKeys: [...binding.fieldKeys],
|
|
247
|
+
reason: 'page_signature_mismatch',
|
|
248
|
+
attempts,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const surface = target.surfaceRef ? getSurface(session, target.surfaceRef) : null;
|
|
252
|
+
const baseRoot = resolveLocatorRoot(page, target.framePath ?? surface?.framePath);
|
|
253
|
+
let locatorRoot = baseRoot;
|
|
254
|
+
let surfaceRoot = null;
|
|
255
|
+
if (surface) {
|
|
256
|
+
surfaceRoot = await resolveSurfaceScopeRoot(page, surface, attempts).catch(() => null);
|
|
257
|
+
if (surfaceRoot && !targetUsesSurfaceAsPrimaryLocator(target, surface)) {
|
|
258
|
+
locatorRoot = surfaceRoot;
|
|
259
|
+
}
|
|
260
|
+
else if (!surfaceRoot) {
|
|
261
|
+
attempts.push('surface.resolve.fallback:page');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
let resolvedLocator = null;
|
|
265
|
+
let sawDomSignatureMismatch = false;
|
|
266
|
+
let sawBlockedTarget = false;
|
|
267
|
+
const action = actionForTarget(target);
|
|
268
|
+
for (const candidate of rankLocatorCandidates(target.locatorCandidates, action)) {
|
|
269
|
+
const candidateRoot = resolveLocatorRootForCandidate(baseRoot, locatorRoot, surfaceRoot, candidate.scope);
|
|
270
|
+
if (!candidateRoot) {
|
|
271
|
+
attempts.push(`resolve.skip:${candidate.strategy}:surface-unavailable`);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
const locator = buildLocator(candidateRoot, candidate);
|
|
275
|
+
if (!locator) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const prepared = await prepareLocator(locator, action, candidate.strategy, attempts, {
|
|
279
|
+
allowReadonlyFallback: action === 'fill' && target.controlFamily === 'datepicker',
|
|
280
|
+
});
|
|
281
|
+
if (prepared.blockedReason === 'disabled' || prepared.blockedReason === 'readonly') {
|
|
282
|
+
sawBlockedTarget = true;
|
|
283
|
+
}
|
|
284
|
+
if (!prepared.locator) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (target.domSignature) {
|
|
288
|
+
const liveSignature = await readLocatorDomSignature(prepared.locator).catch(() => null);
|
|
289
|
+
if (liveSignature && liveSignature !== target.domSignature) {
|
|
290
|
+
sawDomSignatureMismatch = true;
|
|
291
|
+
attempts.push(`domSignature.mismatch:${candidate.strategy}`);
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
resolvedLocator = prepared.locator;
|
|
296
|
+
attempts.push(`resolve:${candidate.strategy}`);
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
if (!resolvedLocator) {
|
|
300
|
+
return {
|
|
301
|
+
kind: 'binding_stale',
|
|
302
|
+
targetRef: binding.targetRef,
|
|
303
|
+
fieldKeys: [...binding.fieldKeys],
|
|
304
|
+
reason: sawDomSignatureMismatch
|
|
305
|
+
? 'dom_signature_mismatch'
|
|
306
|
+
: sawBlockedTarget
|
|
307
|
+
? 'target_blocked'
|
|
308
|
+
: 'locator_resolution_failed',
|
|
309
|
+
attempts,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
preparedBindings.push({
|
|
313
|
+
targetRef: binding.targetRef,
|
|
314
|
+
fields: [...binding.fields],
|
|
315
|
+
fieldKeys: [...binding.fieldKeys],
|
|
316
|
+
action,
|
|
317
|
+
target,
|
|
318
|
+
root: locatorRoot,
|
|
319
|
+
locator: resolvedLocator,
|
|
320
|
+
attempts,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
return preparedBindings;
|
|
324
|
+
}
|
|
325
|
+
async function assertBindingStillValid(page, binding, stage) {
|
|
326
|
+
if (binding.target.pageSignature &&
|
|
327
|
+
normalizePageSignature(page.url()) !== binding.target.pageSignature) {
|
|
328
|
+
throw new Error(`binding_stale:page_signature_mismatch:${stage}`);
|
|
329
|
+
}
|
|
330
|
+
const liveCount = await binding.locator.count().catch(() => 0);
|
|
331
|
+
if (liveCount === 0) {
|
|
332
|
+
throw new Error(`binding_stale:locator_resolution_failed:${stage}`);
|
|
333
|
+
}
|
|
334
|
+
if (binding.target.domSignature) {
|
|
335
|
+
const liveSignature = await readLocatorDomSignature(binding.locator).catch(() => null);
|
|
336
|
+
if (liveSignature && liveSignature !== binding.target.domSignature) {
|
|
337
|
+
throw new Error(`binding_stale:dom_signature_mismatch:${stage}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function staleReasonFromError(error) {
|
|
342
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
343
|
+
if (message.includes('page_signature_mismatch')) {
|
|
344
|
+
return 'page_signature_mismatch';
|
|
345
|
+
}
|
|
346
|
+
if (message.includes('dom_signature_mismatch')) {
|
|
347
|
+
return 'dom_signature_mismatch';
|
|
348
|
+
}
|
|
349
|
+
if (message.includes('locator_resolution_failed')) {
|
|
350
|
+
return 'locator_resolution_failed';
|
|
351
|
+
}
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
export async function executeProtectedFill(params) {
|
|
355
|
+
const preparedBindings = await prepareBindings(params.session, params.page, params.fillableForm);
|
|
356
|
+
if (!Array.isArray(preparedBindings)) {
|
|
357
|
+
return preparedBindings;
|
|
358
|
+
}
|
|
359
|
+
let assistedValues;
|
|
360
|
+
try {
|
|
361
|
+
assistedValues = await resolveAssistedProtectedFieldValues({
|
|
362
|
+
page: params.page,
|
|
363
|
+
bindings: preparedBindings.map((binding) => ({
|
|
364
|
+
binding: binding.fields[0],
|
|
365
|
+
target: binding.target,
|
|
366
|
+
})),
|
|
367
|
+
protectedValues: params.protectedValues,
|
|
368
|
+
fieldPolicies: params.fieldPolicies,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
return {
|
|
373
|
+
kind: 'unexpected_error',
|
|
374
|
+
reason: 'assisted_value_resolution_failed',
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
const filledFields = [];
|
|
378
|
+
for (const binding of preparedBindings) {
|
|
379
|
+
let actionValue;
|
|
380
|
+
let acceptanceProbe = null;
|
|
381
|
+
let acceptanceResult = null;
|
|
382
|
+
try {
|
|
383
|
+
actionValue = resolveBindingValue(binding.fields, params.protectedValues, params.fieldPolicies, assistedValues);
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
387
|
+
if (message === 'missing_protected_value') {
|
|
388
|
+
return {
|
|
389
|
+
kind: 'unexpected_error',
|
|
390
|
+
reason: 'missing_protected_value',
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
if (message === 'deterministic_only_resolution_failed') {
|
|
394
|
+
return {
|
|
395
|
+
kind: 'unexpected_error',
|
|
396
|
+
reason: 'deterministic_only_resolution_failed',
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
if (message === 'assisted_value_resolution_failed') {
|
|
400
|
+
return {
|
|
401
|
+
kind: 'unexpected_error',
|
|
402
|
+
reason: 'assisted_value_resolution_failed',
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
return {
|
|
406
|
+
kind: 'unexpected_error',
|
|
407
|
+
reason: 'unsupported_protected_field_group',
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
acceptanceProbe = await createAcceptanceProbe({
|
|
412
|
+
session: params.session,
|
|
413
|
+
page: params.page,
|
|
414
|
+
target: binding.target,
|
|
415
|
+
action: binding.action,
|
|
416
|
+
actionValue,
|
|
417
|
+
locator: binding.locator,
|
|
418
|
+
beforePageObservation: null,
|
|
419
|
+
});
|
|
420
|
+
await applyActionWithFallbacks(params.page, binding.root, binding.locator, binding.action, actionValue, binding.attempts, binding.target.controlFamily, {
|
|
421
|
+
guards: {
|
|
422
|
+
assertStillValid: async (stage) => {
|
|
423
|
+
await assertBindingStillValid(params.page, binding, stage);
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
if (acceptanceProbe) {
|
|
428
|
+
acceptanceResult = await waitForAcceptanceProbe(acceptanceProbe);
|
|
429
|
+
const acceptance = acceptanceResult;
|
|
430
|
+
if (!acceptance.accepted) {
|
|
431
|
+
const validationState = await readValidationState(acceptanceProbe.readLocator);
|
|
432
|
+
return {
|
|
433
|
+
kind: 'validation_failed',
|
|
434
|
+
filledFields,
|
|
435
|
+
fieldErrors: binding.fieldKeys.map((fieldKey) => ({
|
|
436
|
+
fieldKey,
|
|
437
|
+
targetRef: binding.targetRef,
|
|
438
|
+
reason: validationState.validationText
|
|
439
|
+
? 'client_validation_rejected'
|
|
440
|
+
: 'value_not_applied',
|
|
441
|
+
...buildProtectedValidationDetails(validationState.validationText),
|
|
442
|
+
})),
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
const validationState = await readValidationState(acceptanceProbe.readLocator);
|
|
446
|
+
if (validationState.invalid && !shouldIgnoreNativeInvalidForTarget(binding.target)) {
|
|
447
|
+
return {
|
|
448
|
+
kind: 'validation_failed',
|
|
449
|
+
filledFields,
|
|
450
|
+
fieldErrors: binding.fieldKeys.map((fieldKey) => ({
|
|
451
|
+
fieldKey,
|
|
452
|
+
targetRef: binding.targetRef,
|
|
453
|
+
reason: 'client_validation_rejected',
|
|
454
|
+
...buildProtectedValidationDetails(validationState.validationText),
|
|
455
|
+
})),
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
filledFields.push(...flattenFilledFields(binding.fieldKeys, binding.targetRef));
|
|
460
|
+
}
|
|
461
|
+
catch (error) {
|
|
462
|
+
if (acceptanceProbe) {
|
|
463
|
+
acceptanceResult =
|
|
464
|
+
acceptanceResult ?? (await waitForAcceptanceProbe(acceptanceProbe).catch(() => null));
|
|
465
|
+
if (acceptanceResult?.accepted) {
|
|
466
|
+
const validationState = await readValidationState(acceptanceProbe.readLocator);
|
|
467
|
+
if (validationState.invalid && !shouldIgnoreNativeInvalidForTarget(binding.target)) {
|
|
468
|
+
return {
|
|
469
|
+
kind: 'validation_failed',
|
|
470
|
+
filledFields,
|
|
471
|
+
fieldErrors: binding.fieldKeys.map((fieldKey) => ({
|
|
472
|
+
fieldKey,
|
|
473
|
+
targetRef: binding.targetRef,
|
|
474
|
+
reason: 'client_validation_rejected',
|
|
475
|
+
...buildProtectedValidationDetails(validationState.validationText),
|
|
476
|
+
})),
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
filledFields.push(...flattenFilledFields(binding.fieldKeys, binding.targetRef));
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const staleReason = staleReasonFromError(error);
|
|
484
|
+
if (staleReason) {
|
|
485
|
+
return {
|
|
486
|
+
kind: 'binding_stale',
|
|
487
|
+
targetRef: binding.targetRef,
|
|
488
|
+
fieldKeys: [...binding.fieldKeys],
|
|
489
|
+
reason: staleReason,
|
|
490
|
+
attempts: [...binding.attempts],
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
kind: 'unexpected_error',
|
|
495
|
+
reason: 'action_failed',
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
kind: 'success',
|
|
501
|
+
filledFields,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
export const __testProtectedFill = {
|
|
505
|
+
actionForTarget,
|
|
506
|
+
formatCardExpiry,
|
|
507
|
+
resolveBindingValue: (fieldKeys, protectedValues) => resolveBindingValue(fieldKeys.map((fieldKey) => ({
|
|
508
|
+
fieldKey,
|
|
509
|
+
targetRef: 't_test',
|
|
510
|
+
valueHint: 'direct',
|
|
511
|
+
})), protectedValues, undefined, new Map()),
|
|
512
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export declare const LOGIN_FIELD_KEYS: readonly ["username", "password"];
|
|
2
|
+
export declare const IDENTITY_FIELD_KEYS: readonly ["full_name", "document_number", "date_of_birth", "nationality", "issue_date", "expiry_date", "issuing_country"];
|
|
3
|
+
export declare const PAYMENT_CARD_FIELD_KEYS: readonly ["cardholder", "pan", "exp_month", "exp_year", "cvv"];
|
|
4
|
+
export type StoredSecretKind = 'login' | 'identity' | 'payment_card';
|
|
5
|
+
export declare const STORED_SECRET_FIELD_KEYS_BY_KIND: {
|
|
6
|
+
readonly login: readonly ["username", "password"];
|
|
7
|
+
readonly identity: readonly ["full_name", "document_number", "date_of_birth", "nationality", "issue_date", "expiry_date", "issuing_country"];
|
|
8
|
+
readonly payment_card: readonly ["cardholder", "pan", "exp_month", "exp_year", "cvv"];
|
|
9
|
+
};
|
|
10
|
+
export type LoginFieldKey = (typeof LOGIN_FIELD_KEYS)[number];
|
|
11
|
+
export type IdentityFieldKey = (typeof IDENTITY_FIELD_KEYS)[number];
|
|
12
|
+
export type PaymentCardFieldKey = (typeof PAYMENT_CARD_FIELD_KEYS)[number];
|
|
13
|
+
export type StoredSecretFieldKey = LoginFieldKey | IdentityFieldKey | PaymentCardFieldKey;
|
|
14
|
+
export type StoredSecretScope = 'site' | 'global';
|
|
15
|
+
export type ProtectedFieldPolicy = 'deterministic_only' | 'llm_assisted';
|
|
16
|
+
export declare const PROTECTED_BINDING_VALUE_HINTS: readonly ["direct", "full_name.given", "full_name.family"];
|
|
17
|
+
export type ProtectedBindingValueHint = (typeof PROTECTED_BINDING_VALUE_HINTS)[number];
|
|
18
|
+
export type StoredSecretApplicabilityTarget = 'host' | 'site' | 'global';
|
|
19
|
+
export interface StoredSecretApplicability {
|
|
20
|
+
target: StoredSecretApplicabilityTarget;
|
|
21
|
+
value?: string;
|
|
22
|
+
}
|
|
23
|
+
export type StoredSecretFieldPolicies = Partial<Record<StoredSecretFieldKey, ProtectedFieldPolicy>>;
|
|
24
|
+
export interface StoredSecretMetadata {
|
|
25
|
+
storedSecretRef: string;
|
|
26
|
+
kind: StoredSecretKind;
|
|
27
|
+
scope: StoredSecretScope;
|
|
28
|
+
displayName: string;
|
|
29
|
+
fieldKeys: StoredSecretFieldKey[];
|
|
30
|
+
fieldPolicies?: StoredSecretFieldPolicies;
|
|
31
|
+
intentRequired: boolean;
|
|
32
|
+
applicability: StoredSecretApplicability;
|
|
33
|
+
preferredForMerchantKeys?: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface SecretCatalogSnapshot {
|
|
36
|
+
source: 'mock' | 'agentpay_api';
|
|
37
|
+
host: string;
|
|
38
|
+
syncedAt: string;
|
|
39
|
+
storedSecrets: StoredSecretMetadata[];
|
|
40
|
+
}
|
|
41
|
+
export interface FillableFormFieldBinding {
|
|
42
|
+
fieldKey: StoredSecretFieldKey;
|
|
43
|
+
targetRef: string;
|
|
44
|
+
label?: string;
|
|
45
|
+
required?: boolean;
|
|
46
|
+
valueHint?: ProtectedBindingValueHint;
|
|
47
|
+
}
|
|
48
|
+
export interface FillableFormStoredSecretCandidate {
|
|
49
|
+
storedSecretRef: string;
|
|
50
|
+
kind: StoredSecretKind;
|
|
51
|
+
scope: StoredSecretScope;
|
|
52
|
+
displayName: string;
|
|
53
|
+
matchConfidence: 'high' | 'medium' | 'low';
|
|
54
|
+
intentRequired: boolean;
|
|
55
|
+
fieldKeys?: StoredSecretFieldKey[];
|
|
56
|
+
fieldPolicies?: StoredSecretFieldPolicies;
|
|
57
|
+
}
|
|
58
|
+
export type FillableFormRecommendedTiming = 'late';
|
|
59
|
+
export interface PersistedFillableForm {
|
|
60
|
+
fillRef: string;
|
|
61
|
+
pageRef: string;
|
|
62
|
+
scopeRef?: string;
|
|
63
|
+
purpose: string;
|
|
64
|
+
recommendedTiming?: FillableFormRecommendedTiming;
|
|
65
|
+
fields: FillableFormFieldBinding[];
|
|
66
|
+
storedSecretCandidates: FillableFormStoredSecretCandidate[];
|
|
67
|
+
observedAt: string;
|
|
68
|
+
}
|
|
69
|
+
export type SecretIntentStatus = 'pending' | 'checking' | 'notify' | 'confirmation' | 'approved' | 'denied' | 'timed_out' | 'completed';
|
|
70
|
+
export interface SecretIntentSnapshot {
|
|
71
|
+
intentId: string;
|
|
72
|
+
fillRef: string;
|
|
73
|
+
storedSecretRef: string;
|
|
74
|
+
status: SecretIntentStatus;
|
|
75
|
+
approvalChannel?: 'agentpay-cabinet';
|
|
76
|
+
host?: string;
|
|
77
|
+
pageRef?: string;
|
|
78
|
+
scopeRef?: string;
|
|
79
|
+
createdAt: string;
|
|
80
|
+
expiresAt?: string;
|
|
81
|
+
approvedAt?: string;
|
|
82
|
+
completedAt?: string;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/secrets/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const LOGIN_FIELD_KEYS = ['username', 'password'];
|
|
2
|
+
export const IDENTITY_FIELD_KEYS = [
|
|
3
|
+
'full_name',
|
|
4
|
+
'document_number',
|
|
5
|
+
'date_of_birth',
|
|
6
|
+
'nationality',
|
|
7
|
+
'issue_date',
|
|
8
|
+
'expiry_date',
|
|
9
|
+
'issuing_country',
|
|
10
|
+
];
|
|
11
|
+
export const PAYMENT_CARD_FIELD_KEYS = [
|
|
12
|
+
'cardholder',
|
|
13
|
+
'pan',
|
|
14
|
+
'exp_month',
|
|
15
|
+
'exp_year',
|
|
16
|
+
'cvv',
|
|
17
|
+
];
|
|
18
|
+
export const STORED_SECRET_FIELD_KEYS_BY_KIND = {
|
|
19
|
+
login: LOGIN_FIELD_KEYS,
|
|
20
|
+
identity: IDENTITY_FIELD_KEYS,
|
|
21
|
+
payment_card: PAYMENT_CARD_FIELD_KEYS,
|
|
22
|
+
};
|
|
23
|
+
export const PROTECTED_BINDING_VALUE_HINTS = [
|
|
24
|
+
'direct',
|
|
25
|
+
'full_name.given',
|
|
26
|
+
'full_name.family',
|
|
27
|
+
];
|
package/dist/session.d.ts
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
* Session persistence for agentbrowse.
|
|
3
3
|
* Stores CDP URL + Chrome PID in ~/.agentpay/browse-session.json
|
|
4
4
|
*/
|
|
5
|
+
import type { BrowseRuntimeState } from './runtime-state.js';
|
|
6
|
+
import type { StoredSecretFieldKey } from './secrets/types.js';
|
|
7
|
+
export interface CachedTransientSecretEntry {
|
|
8
|
+
intentId: string;
|
|
9
|
+
fillRef: string;
|
|
10
|
+
storedSecretRef: string;
|
|
11
|
+
cachedAt: string;
|
|
12
|
+
approvedAt?: string;
|
|
13
|
+
expiresAt?: string;
|
|
14
|
+
values: Partial<Record<StoredSecretFieldKey, string>>;
|
|
15
|
+
}
|
|
5
16
|
export interface BrowseSession {
|
|
6
17
|
cdpUrl: string;
|
|
7
18
|
pid: number;
|
|
@@ -11,7 +22,18 @@ export interface BrowseSession {
|
|
|
11
22
|
capabilities?: {
|
|
12
23
|
captchaSolve?: boolean;
|
|
13
24
|
};
|
|
25
|
+
runtime?: BrowseRuntimeState;
|
|
26
|
+
transientSecretCache?: Record<string, CachedTransientSecretEntry>;
|
|
14
27
|
}
|
|
28
|
+
export declare function cleanupTransientSecretCache(session: BrowseSession, options?: {
|
|
29
|
+
now?: string;
|
|
30
|
+
}): boolean;
|
|
31
|
+
export declare function cacheTransientSecret(session: BrowseSession, entry: CachedTransientSecretEntry): CachedTransientSecretEntry;
|
|
32
|
+
export declare function getCachedTransientSecret(session: BrowseSession, intentId: string, options?: {
|
|
33
|
+
now?: string;
|
|
34
|
+
}): CachedTransientSecretEntry | null;
|
|
35
|
+
export declare function deleteCachedTransientSecret(session: BrowseSession, intentId: string): boolean;
|
|
36
|
+
export declare function serializeSession(session: BrowseSession): string;
|
|
15
37
|
export declare function saveSession(session: BrowseSession): void;
|
|
16
38
|
export declare function loadSession(): BrowseSession | null;
|
|
17
39
|
export declare function getSessionPort(session: BrowseSession | null): number;
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAK/D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE;QACb,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;CACnE;AAyBD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAqBT;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,0BAA0B,GAChC,0BAA0B,CAQ5B;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,0BAA0B,GAAG,IAAI,CAMnC;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAW7F;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAW/D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAGxD;AAED,wBAAgB,WAAW,IAAI,aAAa,GAAG,IAAI,CAclD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM,CAapE;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAE3E;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAO9D"}
|