@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.
Files changed (191) hide show
  1. package/README.md +36 -8
  2. package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
  3. package/dist/agentpay-stagehand-llm.js +5 -1
  4. package/dist/commands/act.d.ts +6 -2
  5. package/dist/commands/act.d.ts.map +1 -1
  6. package/dist/commands/act.js +840 -55
  7. package/dist/commands/act.test-harness.d.ts +19 -0
  8. package/dist/commands/act.test-harness.d.ts.map +1 -0
  9. package/dist/commands/act.test-harness.js +245 -0
  10. package/dist/commands/action-acceptance.d.ts +90 -0
  11. package/dist/commands/action-acceptance.d.ts.map +1 -0
  12. package/dist/commands/action-acceptance.js +1411 -0
  13. package/dist/commands/action-artifacts.d.ts +33 -0
  14. package/dist/commands/action-artifacts.d.ts.map +1 -0
  15. package/dist/commands/action-artifacts.js +104 -0
  16. package/dist/commands/action-execution-guards.d.ts +5 -0
  17. package/dist/commands/action-execution-guards.d.ts.map +1 -0
  18. package/dist/commands/action-execution-guards.js +3 -0
  19. package/dist/commands/action-executor-helpers.d.ts +21 -0
  20. package/dist/commands/action-executor-helpers.d.ts.map +1 -0
  21. package/dist/commands/action-executor-helpers.js +242 -0
  22. package/dist/commands/action-executor.d.ts +12 -0
  23. package/dist/commands/action-executor.d.ts.map +1 -0
  24. package/dist/commands/action-executor.js +45 -0
  25. package/dist/commands/action-fallbacks.d.ts +6 -0
  26. package/dist/commands/action-fallbacks.d.ts.map +1 -0
  27. package/dist/commands/action-fallbacks.js +43 -0
  28. package/dist/commands/action-value-projection.d.ts +32 -0
  29. package/dist/commands/action-value-projection.d.ts.map +1 -0
  30. package/dist/commands/action-value-projection.js +151 -0
  31. package/dist/commands/browse-actions.d.ts +4 -0
  32. package/dist/commands/browse-actions.d.ts.map +1 -0
  33. package/dist/commands/browse-actions.js +4 -0
  34. package/dist/commands/captcha-solve.d.ts.map +1 -1
  35. package/dist/commands/captcha-solve.js +13 -3
  36. package/dist/commands/click-action-executor.d.ts +10 -0
  37. package/dist/commands/click-action-executor.d.ts.map +1 -0
  38. package/dist/commands/click-action-executor.js +68 -0
  39. package/dist/commands/create-intent.d.ts +6 -0
  40. package/dist/commands/create-intent.d.ts.map +1 -0
  41. package/dist/commands/create-intent.js +75 -0
  42. package/dist/commands/datepicker-action-executor.d.ts +12 -0
  43. package/dist/commands/datepicker-action-executor.d.ts.map +1 -0
  44. package/dist/commands/datepicker-action-executor.js +218 -0
  45. package/dist/commands/descriptor-validation.d.ts +27 -0
  46. package/dist/commands/descriptor-validation.d.ts.map +1 -0
  47. package/dist/commands/descriptor-validation.js +333 -0
  48. package/dist/commands/extract-scope-resolution.d.ts +20 -0
  49. package/dist/commands/extract-scope-resolution.d.ts.map +1 -0
  50. package/dist/commands/extract-scope-resolution.js +100 -0
  51. package/dist/commands/extract-stagehand-executor.d.ts +17 -0
  52. package/dist/commands/extract-stagehand-executor.d.ts.map +1 -0
  53. package/dist/commands/extract-stagehand-executor.js +18 -0
  54. package/dist/commands/extract.d.ts +3 -2
  55. package/dist/commands/extract.d.ts.map +1 -1
  56. package/dist/commands/extract.js +256 -39
  57. package/dist/commands/fill-secret.d.ts +7 -0
  58. package/dist/commands/fill-secret.d.ts.map +1 -0
  59. package/dist/commands/fill-secret.js +371 -0
  60. package/dist/commands/get-secrets-catalog.d.ts +6 -0
  61. package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
  62. package/dist/commands/get-secrets-catalog.js +23 -0
  63. package/dist/commands/launch.d.ts.map +1 -1
  64. package/dist/commands/launch.js +41 -7
  65. package/dist/commands/navigate.d.ts +2 -1
  66. package/dist/commands/navigate.d.ts.map +1 -1
  67. package/dist/commands/navigate.js +49 -12
  68. package/dist/commands/observe-inventory.d.ts +109 -0
  69. package/dist/commands/observe-inventory.d.ts.map +1 -0
  70. package/dist/commands/observe-inventory.js +2837 -0
  71. package/dist/commands/observe-persistence.d.ts +14 -0
  72. package/dist/commands/observe-persistence.d.ts.map +1 -0
  73. package/dist/commands/observe-persistence.js +170 -0
  74. package/dist/commands/observe-projection.d.ts +84 -0
  75. package/dist/commands/observe-projection.d.ts.map +1 -0
  76. package/dist/commands/observe-projection.js +140 -0
  77. package/dist/commands/observe-protected.d.ts +5 -0
  78. package/dist/commands/observe-protected.d.ts.map +1 -0
  79. package/dist/commands/observe-protected.js +18 -0
  80. package/dist/commands/observe-semantics.d.ts +10 -0
  81. package/dist/commands/observe-semantics.d.ts.map +1 -0
  82. package/dist/commands/observe-semantics.js +338 -0
  83. package/dist/commands/observe-stagehand.d.ts +48 -0
  84. package/dist/commands/observe-stagehand.d.ts.map +1 -0
  85. package/dist/commands/observe-stagehand.js +105 -0
  86. package/dist/commands/observe-surfaces.d.ts +9 -0
  87. package/dist/commands/observe-surfaces.d.ts.map +1 -0
  88. package/dist/commands/observe-surfaces.js +195 -0
  89. package/dist/commands/observe.d.ts +47 -1
  90. package/dist/commands/observe.d.ts.map +1 -1
  91. package/dist/commands/observe.js +173 -20
  92. package/dist/commands/observe.test-harness.d.ts +67 -0
  93. package/dist/commands/observe.test-harness.d.ts.map +1 -0
  94. package/dist/commands/observe.test-harness.js +107 -0
  95. package/dist/commands/poll-intent.d.ts +6 -0
  96. package/dist/commands/poll-intent.d.ts.map +1 -0
  97. package/dist/commands/poll-intent.js +57 -0
  98. package/dist/commands/screenshot.d.ts +2 -1
  99. package/dist/commands/screenshot.d.ts.map +1 -1
  100. package/dist/commands/screenshot.js +44 -12
  101. package/dist/commands/select-action-executor.d.ts +10 -0
  102. package/dist/commands/select-action-executor.d.ts.map +1 -0
  103. package/dist/commands/select-action-executor.js +91 -0
  104. package/dist/commands/semantic-observe.d.ts +24 -0
  105. package/dist/commands/semantic-observe.d.ts.map +1 -0
  106. package/dist/commands/semantic-observe.js +344 -0
  107. package/dist/commands/status.d.ts.map +1 -1
  108. package/dist/commands/status.js +75 -2
  109. package/dist/commands/structured-grid-action-executor.d.ts +3 -0
  110. package/dist/commands/structured-grid-action-executor.d.ts.map +1 -0
  111. package/dist/commands/structured-grid-action-executor.js +4 -0
  112. package/dist/commands/target-resolution.d.ts +4 -0
  113. package/dist/commands/target-resolution.d.ts.map +1 -0
  114. package/dist/commands/target-resolution.js +33 -0
  115. package/dist/commands/text-input-action-executor.d.ts +5 -0
  116. package/dist/commands/text-input-action-executor.d.ts.map +1 -0
  117. package/dist/commands/text-input-action-executor.js +116 -0
  118. package/dist/commands/user-actionable.d.ts +4 -0
  119. package/dist/commands/user-actionable.d.ts.map +1 -0
  120. package/dist/commands/user-actionable.js +95 -0
  121. package/dist/control-semantics.d.ts +29 -0
  122. package/dist/control-semantics.d.ts.map +1 -0
  123. package/dist/control-semantics.js +299 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +95 -32
  126. package/dist/output.d.ts +14 -2
  127. package/dist/output.d.ts.map +1 -1
  128. package/dist/output.js +17 -29
  129. package/dist/playwright-runtime.d.ts +35 -0
  130. package/dist/playwright-runtime.d.ts.map +1 -0
  131. package/dist/playwright-runtime.js +224 -0
  132. package/dist/runtime-resolution.d.ts +9 -0
  133. package/dist/runtime-resolution.d.ts.map +1 -0
  134. package/dist/runtime-resolution.js +19 -0
  135. package/dist/runtime-state.d.ts +217 -0
  136. package/dist/runtime-state.d.ts.map +1 -0
  137. package/dist/runtime-state.js +629 -0
  138. package/dist/secrets/backend.d.ts +32 -0
  139. package/dist/secrets/backend.d.ts.map +1 -0
  140. package/dist/secrets/backend.js +169 -0
  141. package/dist/secrets/catalog-applicability.d.ts +5 -0
  142. package/dist/secrets/catalog-applicability.d.ts.map +1 -0
  143. package/dist/secrets/catalog-applicability.js +59 -0
  144. package/dist/secrets/catalog-sync.d.ts +14 -0
  145. package/dist/secrets/catalog-sync.d.ts.map +1 -0
  146. package/dist/secrets/catalog-sync.js +35 -0
  147. package/dist/secrets/field-policy.d.ts +3 -0
  148. package/dist/secrets/field-policy.d.ts.map +1 -0
  149. package/dist/secrets/field-policy.js +3 -0
  150. package/dist/secrets/fill-ordering.d.ts +11 -0
  151. package/dist/secrets/fill-ordering.d.ts.map +1 -0
  152. package/dist/secrets/fill-ordering.js +44 -0
  153. package/dist/secrets/form-matcher.d.ts +60 -0
  154. package/dist/secrets/form-matcher.d.ts.map +1 -0
  155. package/dist/secrets/form-matcher.js +596 -0
  156. package/dist/secrets/intent-output.d.ts +11 -0
  157. package/dist/secrets/intent-output.d.ts.map +1 -0
  158. package/dist/secrets/intent-output.js +64 -0
  159. package/dist/secrets/mock-agentpay-backend.d.ts +13 -0
  160. package/dist/secrets/mock-agentpay-backend.d.ts.map +1 -0
  161. package/dist/secrets/mock-agentpay-backend.js +87 -0
  162. package/dist/secrets/mock-agentpay-cabinet.d.ts +43 -0
  163. package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -0
  164. package/dist/secrets/mock-agentpay-cabinet.js +195 -0
  165. package/dist/secrets/protected-artifact-guard.d.ts +25 -0
  166. package/dist/secrets/protected-artifact-guard.d.ts.map +1 -0
  167. package/dist/secrets/protected-artifact-guard.js +26 -0
  168. package/dist/secrets/protected-bindings.d.ts +10 -0
  169. package/dist/secrets/protected-bindings.d.ts.map +1 -0
  170. package/dist/secrets/protected-bindings.js +17 -0
  171. package/dist/secrets/protected-field-values.d.ts +13 -0
  172. package/dist/secrets/protected-field-values.d.ts.map +1 -0
  173. package/dist/secrets/protected-field-values.js +100 -0
  174. package/dist/secrets/protected-fill.d.ts +47 -0
  175. package/dist/secrets/protected-fill.d.ts.map +1 -0
  176. package/dist/secrets/protected-fill.js +512 -0
  177. package/dist/secrets/types.d.ts +84 -0
  178. package/dist/secrets/types.d.ts.map +1 -0
  179. package/dist/secrets/types.js +27 -0
  180. package/dist/session.d.ts +22 -0
  181. package/dist/session.d.ts.map +1 -1
  182. package/dist/session.js +74 -2
  183. package/dist/solver/browser-launcher.d.ts.map +1 -1
  184. package/dist/solver/browser-launcher.js +6 -3
  185. package/dist/stagehand-runtime.d.ts +4 -0
  186. package/dist/stagehand-runtime.d.ts.map +1 -0
  187. package/dist/stagehand-runtime.js +10 -0
  188. package/dist/stagehand.d.ts +0 -5
  189. package/dist/stagehand.d.ts.map +1 -1
  190. package/dist/stagehand.js +0 -6
  191. package/package.json +5 -2
@@ -0,0 +1,299 @@
1
+ const DATE_LIKE_LABEL_RE = /(?:\b\d{1,2}\b|январ|феврал|март|апрел|ма[йя]|июн|июл|август|сентябр|октябр|ноябр|декабр|january|february|march|april|may|june|july|august|september|october|november|december|date|дата|calendar|datepicker|календар)/i;
2
+ const SUBMIT_LABEL_RE = /(?:buy|book|continue|search|find|open|submit|next|pay|купить|забронировать|продолжить|найти|открыть|оплатить)/i;
3
+ const PREREQUISITE_HINT_RE = /(?:choose|select|pick|set|enter|fill|complete)\b.*\b(?:first|before)\b|(?:first|before)\b.*\b(?:choose|select|pick|set|enter|fill|complete)\b|(?:сначала|сперва)\b.*\b(?:выберите|заполните|укажите|введите|завершите)\b|\b(?:выберите|заполните|укажите|введите|завершите)\b.*\b(?:сначала|сперва)\b|required first|available after|unlock/i;
4
+ const PHONE_FIELD_RE = /\b(phone|mobile|telephone|tel)\b/i;
5
+ const CARD_NUMBER_FIELD_RE = /\b(card.?number|cc.?number|cardnumber|pan|cc-number)\b/i;
6
+ const CARD_EXPIRY_FIELD_RE = /\b(exp(?:iry|iration)(?: date)?|cc-exp|valid\s+thru|valid\s+through|mm\s*\/\s*yy(?:yy)?)\b/i;
7
+ const CARD_CVC_FIELD_RE = /\b(cvc|cvv|cc-csc|security code|card cvc)\b/i;
8
+ const DATE_VALUE_MASK_RE = /(?:^|\b)(?:dd|d|дд|д)\s*[./-]\s*(?:mm|m|мм|м)\s*[./-]\s*(?:yyyy|yyy|yy|y|гггг|гг|г)(?:\b|$)/i;
9
+ const NON_CARD_DATE_FIELD_RE = /\b(?:birth|dob|date|issued|expires|expiry|expiration|expir)\b|(?:дата|рожд|срок)/i;
10
+ function normalizeText(value) {
11
+ return (value ?? '').trim().toLowerCase();
12
+ }
13
+ function primaryLabel(facts) {
14
+ return facts.label ?? facts.displayLabel ?? facts.text ?? facts.placeholder ?? '';
15
+ }
16
+ function valueTypeHintBlob(facts) {
17
+ return [
18
+ facts.label,
19
+ facts.displayLabel,
20
+ facts.text,
21
+ facts.placeholder,
22
+ facts.inputName,
23
+ facts.autocomplete,
24
+ ]
25
+ .filter((value) => Boolean(value))
26
+ .join(' ')
27
+ .trim();
28
+ }
29
+ export function inferComparableValueTypeFromFacts(facts) {
30
+ const inputType = normalizeText(facts.inputType);
31
+ const autocomplete = normalizeText(facts.autocomplete);
32
+ const hintBlob = valueTypeHintBlob(facts);
33
+ if (inputType === 'tel' ||
34
+ autocomplete.includes('tel') ||
35
+ PHONE_FIELD_RE.test(hintBlob)) {
36
+ return 'phone';
37
+ }
38
+ if (autocomplete.includes('cc-number') || CARD_NUMBER_FIELD_RE.test(hintBlob)) {
39
+ return 'card-number';
40
+ }
41
+ const cardExpiryLike = autocomplete.includes('cc-exp') ||
42
+ (inputType !== 'date' &&
43
+ CARD_EXPIRY_FIELD_RE.test(hintBlob) &&
44
+ (autocomplete.startsWith('cc-') ||
45
+ /\b(card|credit|debit)\b/i.test(hintBlob) ||
46
+ /\bmm\s*\/\s*yy(?:yy)?\b/i.test(hintBlob)));
47
+ if (cardExpiryLike) {
48
+ return 'expiry';
49
+ }
50
+ if (autocomplete.includes('cc-csc') || CARD_CVC_FIELD_RE.test(hintBlob)) {
51
+ return 'cvc';
52
+ }
53
+ const nonCardDateLike = inputType === 'date' ||
54
+ DATE_VALUE_MASK_RE.test(hintBlob) ||
55
+ (NON_CARD_DATE_FIELD_RE.test(hintBlob) &&
56
+ !autocomplete.startsWith('cc-') &&
57
+ !/\b(card|credit|debit|cvc|cvv|security code)\b/i.test(hintBlob));
58
+ if (nonCardDateLike) {
59
+ return 'date';
60
+ }
61
+ return undefined;
62
+ }
63
+ function isPopupBackedTextEntry(facts) {
64
+ const kind = normalizeText(facts.kind);
65
+ const role = normalizeText(facts.role);
66
+ const surfaceKind = normalizeText(facts.surfaceKind);
67
+ if ((kind === 'input' || kind === 'textarea' || role === 'textbox') &&
68
+ (Boolean(facts.controlsSurfaceSelector) ||
69
+ surfaceKind === 'listbox' ||
70
+ surfaceKind === 'menu' ||
71
+ facts.states?.expanded !== undefined)) {
72
+ return true;
73
+ }
74
+ return false;
75
+ }
76
+ function isSelectLikePopupOwner(facts) {
77
+ const kind = normalizeText(facts.kind);
78
+ const role = normalizeText(facts.role);
79
+ if (kind === 'select' || kind === 'combobox' || role === 'combobox') {
80
+ return true;
81
+ }
82
+ return isPopupBackedTextEntry(facts) && facts.states?.readonly === true;
83
+ }
84
+ function isButtonLikeInputFacts(facts) {
85
+ return (normalizeText(facts.kind) === 'input' &&
86
+ ['button', 'submit', 'reset'].includes(normalizeText(facts.inputType)));
87
+ }
88
+ export function isLikelyDateLikeLabel(value) {
89
+ const trimmed = (value ?? '').trim();
90
+ if (!trimmed) {
91
+ return false;
92
+ }
93
+ if (/^\+?\d{1,4}$/.test(trimmed)) {
94
+ return false;
95
+ }
96
+ if (/\+\d{1,4}\b/.test(trimmed)) {
97
+ return false;
98
+ }
99
+ return DATE_LIKE_LABEL_RE.test(trimmed);
100
+ }
101
+ export function inferAllowedActionsFromFacts(facts) {
102
+ const kind = normalizeText(facts.kind);
103
+ const role = normalizeText(facts.role);
104
+ const interactionHint = normalizeText(facts.interactionHint);
105
+ const legacyMethod = normalizeText(facts.legacyMethod);
106
+ const selectLikePopupOwner = isSelectLikePopupOwner(facts);
107
+ const buttonLikeInput = isButtonLikeInputFacts(facts);
108
+ const actions = new Set();
109
+ if (selectLikePopupOwner) {
110
+ actions.add('click');
111
+ actions.add('select');
112
+ actions.add('press');
113
+ if (facts.surfaceKind === 'datepicker' || isLikelyDateLikeLabel(primaryLabel(facts))) {
114
+ actions.add('fill');
115
+ }
116
+ if (kind === 'combobox' || role === 'combobox') {
117
+ actions.add('fill');
118
+ actions.add('type');
119
+ }
120
+ }
121
+ else if (!buttonLikeInput && (kind === 'input' || kind === 'textarea' || role === 'textbox')) {
122
+ actions.add('click');
123
+ actions.add('fill');
124
+ actions.add('type');
125
+ actions.add('press');
126
+ }
127
+ if (!selectLikePopupOwner && (kind === 'select' || kind === 'combobox' || role === 'combobox')) {
128
+ actions.add('click');
129
+ actions.add('select');
130
+ actions.add('press');
131
+ if (kind === 'combobox' || role === 'combobox') {
132
+ actions.add('fill');
133
+ actions.add('type');
134
+ }
135
+ }
136
+ if (kind === 'option' || role === 'option' || role === 'menuitem') {
137
+ actions.add('click');
138
+ }
139
+ if (role === 'gridcell' || facts.structure?.family === 'structured-grid') {
140
+ actions.add('click');
141
+ actions.add('press');
142
+ }
143
+ if (kind === 'button' || kind === 'link' || role === 'button' || role === 'link') {
144
+ actions.add('click');
145
+ actions.add('press');
146
+ }
147
+ if (interactionHint === 'click') {
148
+ actions.add('click');
149
+ actions.add('press');
150
+ }
151
+ if (legacyMethod === 'click') {
152
+ actions.add('click');
153
+ actions.add('press');
154
+ }
155
+ if (legacyMethod === 'fill') {
156
+ actions.add('click');
157
+ actions.add('fill');
158
+ actions.add('type');
159
+ actions.add('press');
160
+ }
161
+ if (legacyMethod === 'type') {
162
+ actions.add('click');
163
+ actions.add('type');
164
+ actions.add('press');
165
+ }
166
+ if (legacyMethod === 'select') {
167
+ actions.add('click');
168
+ actions.add('select');
169
+ actions.add('press');
170
+ }
171
+ if (legacyMethod === 'press') {
172
+ actions.add('press');
173
+ }
174
+ return [...actions];
175
+ }
176
+ export function inferAvailabilityFromFacts(states, contextHint, options = {}) {
177
+ if (states?.occupied === true) {
178
+ return { state: 'gated', reason: 'occupied' };
179
+ }
180
+ const blocked = states?.disabled === true ||
181
+ states?.ariaDisabled === true ||
182
+ states?.readonly === true ||
183
+ states?.selectable === false;
184
+ if (blocked && PREREQUISITE_HINT_RE.test(contextHint ?? '')) {
185
+ return { state: 'gated', reason: 'prerequisite' };
186
+ }
187
+ if (states?.selectable === false) {
188
+ return { state: 'gated', reason: 'not-selectable' };
189
+ }
190
+ if (states?.disabled === true || states?.ariaDisabled === true) {
191
+ return { state: 'gated', reason: 'disabled' };
192
+ }
193
+ if (states?.readonly === true) {
194
+ if (options.readonlyInteractive) {
195
+ return { state: 'available' };
196
+ }
197
+ return { state: 'gated', reason: 'readonly' };
198
+ }
199
+ return { state: 'available' };
200
+ }
201
+ export function inferControlFamilyFromFacts(facts, allowedActions) {
202
+ const kind = normalizeText(facts.kind);
203
+ const role = normalizeText(facts.role);
204
+ const legacyMethod = normalizeText(facts.legacyMethod);
205
+ const label = primaryLabel(facts);
206
+ const dateLike = isLikelyDateLikeLabel(label) || facts.surfaceKind === 'datepicker';
207
+ const comparableValueType = inferComparableValueTypeFromFacts(facts);
208
+ if (facts.structure?.family === 'structured-grid') {
209
+ return 'structured-grid';
210
+ }
211
+ if (comparableValueType === 'expiry') {
212
+ return 'text-input';
213
+ }
214
+ if (dateLike &&
215
+ (kind === 'input' ||
216
+ kind === 'textarea' ||
217
+ kind === 'select' ||
218
+ kind === 'combobox' ||
219
+ role === 'textbox' ||
220
+ role === 'combobox' ||
221
+ kind === 'option' ||
222
+ role === 'option' ||
223
+ role === 'menuitem' ||
224
+ allowedActions.includes('select') ||
225
+ legacyMethod === 'select')) {
226
+ return 'datepicker';
227
+ }
228
+ if (isSelectLikePopupOwner(facts) ||
229
+ kind === 'option' ||
230
+ role === 'option' ||
231
+ role === 'menuitem' ||
232
+ allowedActions.includes('select') ||
233
+ legacyMethod === 'select') {
234
+ return 'select';
235
+ }
236
+ if (isButtonLikeInputFacts(facts)) {
237
+ return 'trigger';
238
+ }
239
+ if (kind === 'input' ||
240
+ kind === 'textarea' ||
241
+ role === 'textbox' ||
242
+ allowedActions.includes('fill') ||
243
+ allowedActions.includes('type') ||
244
+ legacyMethod === 'fill' ||
245
+ legacyMethod === 'type') {
246
+ return 'text-input';
247
+ }
248
+ if (kind === 'button' ||
249
+ kind === 'link' ||
250
+ role === 'button' ||
251
+ role === 'link' ||
252
+ allowedActions.includes('click') ||
253
+ allowedActions.includes('press') ||
254
+ legacyMethod === 'click' ||
255
+ legacyMethod === 'press') {
256
+ return 'trigger';
257
+ }
258
+ return undefined;
259
+ }
260
+ export function inferAcceptancePolicyFromFacts(facts, allowedActions) {
261
+ const legacyMethod = normalizeText(facts.legacyMethod);
262
+ const label = primaryLabel(facts);
263
+ const states = facts.states;
264
+ const kind = normalizeText(facts.kind);
265
+ const role = normalizeText(facts.role);
266
+ const controlFamily = inferControlFamilyFromFacts(facts, allowedActions);
267
+ if (facts.structure?.family === 'structured-grid') {
268
+ return facts.structure.variant === 'date-cell' ? 'date-selection' : 'selection';
269
+ }
270
+ if (states?.checked !== undefined ||
271
+ states?.selected !== undefined ||
272
+ states?.pressed !== undefined) {
273
+ return 'toggle';
274
+ }
275
+ if (controlFamily === 'text-input') {
276
+ return 'value-change';
277
+ }
278
+ if (states?.expanded !== undefined) {
279
+ return 'disclosure';
280
+ }
281
+ if (controlFamily === 'datepicker') {
282
+ return 'date-selection';
283
+ }
284
+ if (controlFamily === 'select') {
285
+ return 'selection';
286
+ }
287
+ if (role === 'link' || kind === 'link') {
288
+ return 'navigation';
289
+ }
290
+ if (!legacyMethod && SUBMIT_LABEL_RE.test(label)) {
291
+ return 'submit';
292
+ }
293
+ if (controlFamily === 'trigger' ||
294
+ legacyMethod === 'click' ||
295
+ legacyMethod === 'press') {
296
+ return 'generic-click';
297
+ }
298
+ return undefined;
299
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA8KA,iBAAe,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGhE;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAWzF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAqNA,iBAAe,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJhE;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAWzF"}
package/dist/index.js CHANGED
@@ -14,9 +14,15 @@ Commands:
14
14
  launch [url] [options] Launch browser, optionally navigate to URL
15
15
  solve-captcha [--timeout <s>] Wait for captcha and solve it on current page
16
16
  navigate <url> Navigate current tab to URL
17
- act "<instruction>" Perform an action (click, type, scroll...)
18
- extract "<instruction>" Extract data from the page
19
- observe ["<instruction>"] Discover available actions/elements
17
+ get-secrets-catalog [url] Refresh stored-secret metadata for a URL or current page
18
+ create-intent <fillRef> <storedSecretRef>
19
+ Create or reuse an intent for one stored secret fill
20
+ poll-intent <intentId> Poll stored-secret intent status
21
+ fill-secret <fillRef> <intentId>
22
+ Fill protected fields from the one-time delivered secret payload
23
+ act <targetRef> <action> [value] Perform action on a previously observed target
24
+ extract '<schema-json>' [scopeRef] Extract structured data from the page or a stored scope
25
+ observe ["<goal>"] Discover available targets/elements
20
26
  screenshot [--path <file>] Capture a screenshot
21
27
  status Check browser state
22
28
  close Close browser and clean up
@@ -26,8 +32,7 @@ Options:
26
32
  --full Launch browser in full-size window
27
33
  --profile <name> Solver profile name for launch (default: "default")
28
34
  --headless Launch browser in headless mode
29
- --schema '<json>' Schema for extract (e.g. '{"price":"number"}')
30
- --variables '<json>' Variables for act (sensitive, not sent to LLM)
35
+ --no-headless Explicit alias for visible browser mode
31
36
  --path <file> Output path for screenshot
32
37
  --timeout <seconds> Timeout for solve-captcha command (default: 90)
33
38
  --help Show this help message
@@ -39,6 +44,10 @@ Environment:
39
44
  const KNOWN_COMMANDS = new Set([
40
45
  'launch',
41
46
  'navigate',
47
+ 'get-secrets-catalog',
48
+ 'create-intent',
49
+ 'poll-intent',
50
+ 'fill-secret',
42
51
  'solve-captcha',
43
52
  'act',
44
53
  'extract',
@@ -82,6 +91,21 @@ function getPositional(args, valueFlags = []) {
82
91
  }
83
92
  return undefined;
84
93
  }
94
+ function getPositionals(args, valueFlags = []) {
95
+ const valueFlagSet = new Set(valueFlags);
96
+ const values = [];
97
+ for (let i = 0; i < args.length; i++) {
98
+ const arg = args[i];
99
+ if (arg.startsWith('--')) {
100
+ if (valueFlagSet.has(arg)) {
101
+ i += 1;
102
+ }
103
+ continue;
104
+ }
105
+ values.push(arg);
106
+ }
107
+ return values;
108
+ }
85
109
  function parseLaunchArgs(args) {
86
110
  let url;
87
111
  let compact = true;
@@ -93,6 +117,10 @@ function parseLaunchArgs(args) {
93
117
  headless = true;
94
118
  continue;
95
119
  }
120
+ if (arg === '--no-headless') {
121
+ headless = false;
122
+ continue;
123
+ }
96
124
  if (arg === '--compact') {
97
125
  compact = true;
98
126
  continue;
@@ -128,15 +156,19 @@ function parseCaptchaTimeout(args) {
128
156
  }
129
157
  return timeout;
130
158
  }
131
- /** Require an active browser session, return CDP URL. */
132
- function requireSession() {
159
+ /** Require an active browser session. */
160
+ function requireSessionRecord() {
133
161
  const session = loadSession();
134
162
  if (session)
135
- return session.cdpUrl;
163
+ return session;
136
164
  // Fallback: try CDP on port 9222 directly
137
165
  // (Chrome may have been launched by agentpay-cli or externally)
138
- // Caller will handle connection errors.
139
- return 'ws://localhost:9222';
166
+ // Caller will handle connection errors. Runtime state starts empty.
167
+ return {
168
+ cdpUrl: 'ws://localhost:9222',
169
+ pid: process.pid,
170
+ launchedAt: new Date().toISOString(),
171
+ };
140
172
  }
141
173
  async function main(argv = process.argv) {
142
174
  const parsed = getCommand(argv);
@@ -168,7 +200,42 @@ async function main(argv = process.argv) {
168
200
  if (!url)
169
201
  outputError(`Usage: ${browseCommand('navigate', '<url>')}`);
170
202
  const { navigate } = await import('./commands/navigate.js');
171
- await navigate(requireSession(), url);
203
+ await navigate(requireSessionRecord(), url);
204
+ break;
205
+ }
206
+ case 'get-secrets-catalog': {
207
+ const url = getPositional(args);
208
+ const { getSecretsCatalog } = await import('./commands/get-secrets-catalog.js');
209
+ await getSecretsCatalog(requireSessionRecord(), url);
210
+ break;
211
+ }
212
+ case 'create-intent': {
213
+ const positionals = getPositionals(args);
214
+ const [fillRef, storedSecretRef] = positionals;
215
+ if (!fillRef || !storedSecretRef) {
216
+ outputError(`Usage: ${browseCommand('create-intent', '<fillRef>', '<storedSecretRef>')}`);
217
+ }
218
+ const { createIntent } = await import('./commands/create-intent.js');
219
+ await createIntent(requireSessionRecord(), fillRef, storedSecretRef);
220
+ break;
221
+ }
222
+ case 'poll-intent': {
223
+ const intentId = getPositional(args);
224
+ if (!intentId) {
225
+ outputError(`Usage: ${browseCommand('poll-intent', '<intentId>')}`);
226
+ }
227
+ const { pollIntent } = await import('./commands/poll-intent.js');
228
+ await pollIntent(requireSessionRecord(), intentId);
229
+ break;
230
+ }
231
+ case 'fill-secret': {
232
+ const positionals = getPositionals(args);
233
+ const [fillRef, intentId] = positionals;
234
+ if (!fillRef || !intentId) {
235
+ outputError(`Usage: ${browseCommand('fill-secret', '<fillRef>', '<intentId>')}`);
236
+ }
237
+ const { fillSecret } = await import('./commands/fill-secret.js');
238
+ await fillSecret(requireSessionRecord(), fillRef, intentId);
172
239
  break;
173
240
  }
174
241
  case 'solve-captcha': {
@@ -178,36 +245,32 @@ async function main(argv = process.argv) {
178
245
  break;
179
246
  }
180
247
  case 'act': {
181
- const instruction = getPositional(args, ['--variables']);
182
- if (!instruction)
183
- outputError(`Usage: ${browseCommand('act', '"<instruction>"')}`);
184
- let variables;
185
- const varsJson = getFlag(args, '--variables');
186
- if (varsJson) {
187
- try {
188
- variables = JSON.parse(varsJson);
189
- }
190
- catch {
191
- outputError('Invalid --variables JSON');
192
- }
248
+ const positionals = getPositionals(args);
249
+ const [targetRef, action, ...valueParts] = positionals;
250
+ if (!targetRef || !action) {
251
+ outputError(`Usage: ${browseCommand('act', '<targetRef>', '<action>', '[value]')}`);
252
+ }
253
+ const { act, isBrowseAction } = await import('./commands/act.js');
254
+ if (!isBrowseAction(action)) {
255
+ outputError(`Unsupported act action: ${action}. Expected one of: click, fill, type, select, press.`);
193
256
  }
194
- const { act } = await import('./commands/act.js');
195
- await act(requireSession(), instruction, variables);
257
+ await act(requireSessionRecord(), targetRef, action, valueParts.length > 0 ? valueParts.join(' ') : undefined);
196
258
  break;
197
259
  }
198
260
  case 'extract': {
199
- const instruction = getPositional(args, ['--schema']);
200
- if (!instruction)
201
- outputError(`Usage: ${browseCommand('extract', '"<instruction>"')}`);
202
- const schemaJson = getFlag(args, '--schema');
261
+ const positionals = getPositionals(args);
262
+ const [schemaJson, scopeRef] = positionals;
263
+ if (!schemaJson) {
264
+ outputError(`Usage: ${browseCommand('extract', "'<schema-json>'", '[scopeRef]')}`);
265
+ }
203
266
  const { extract } = await import('./commands/extract.js');
204
- await extract(requireSession(), instruction, schemaJson);
267
+ await extract(requireSessionRecord(), schemaJson, scopeRef);
205
268
  break;
206
269
  }
207
270
  case 'observe': {
208
271
  const instruction = getPositional(args);
209
272
  const { observe } = await import('./commands/observe.js');
210
- await observe(requireSession(), instruction);
273
+ await observe(requireSessionRecord(), instruction);
211
274
  break;
212
275
  }
213
276
  case 'screenshot': {
@@ -217,7 +280,7 @@ async function main(argv = process.argv) {
217
280
  }
218
281
  const filePath = getFlag(args, '--path');
219
282
  const { screenshot } = await import('./commands/screenshot.js');
220
- await screenshot(requireSession(), filePath);
283
+ await screenshot(requireSessionRecord(), filePath);
221
284
  break;
222
285
  }
223
286
  case 'status': {
package/dist/output.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Structured output helpers.
3
- * Human-readable text to stdout/stderr.
3
+ * Machine-readable JSON to stdout.
4
4
  */
5
5
  export interface BrowseResult {
6
6
  success: boolean;
@@ -9,8 +9,20 @@ export interface BrowseResult {
9
9
  title?: string;
10
10
  [key: string]: unknown;
11
11
  }
12
- /** Write result to stdout and exit. Errors go to stderr with exit 1. */
12
+ export interface BrowseContractFailure extends Omit<BrowseResult, 'success'> {
13
+ error: string;
14
+ outcomeType: string;
15
+ message: string;
16
+ reason: string;
17
+ }
18
+ /** Write final structured result to stdout and exit. */
13
19
  export declare function outputJSON(result: BrowseResult): never;
20
+ /** Write structured failure result to stdout and exit 1. */
21
+ export declare function outputFailure(result: Omit<BrowseResult, 'success'> & {
22
+ error: string;
23
+ }): never;
24
+ /** Write a normalized contract failure result to stderr and exit 1. */
25
+ export declare function outputContractFailure(result: BrowseContractFailure): never;
14
26
  /** Write error to stderr and exit 1. */
15
27
  export declare function outputError(error: string): never;
16
28
  /** Write a progress/info message to stderr. */
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AASD,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,KAAK,CAsBtD;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAEhD;AAED,+CAA+C;AAC/C,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,6CAA6C;AAC7C,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAG5C"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,KAAK,CAMtD;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAE9F;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,KAAK,CAE1E;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAEhD;AAED,+CAA+C;AAC/C,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,6CAA6C;AAC7C,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAG5C"}
package/dist/output.js CHANGED
@@ -1,38 +1,26 @@
1
1
  import { browseCommandName } from './command-name.js';
2
- /** Format a value for display. Objects/arrays → indented JSON, rest → string. */
3
- function formatValue(value) {
4
- if (value === null || value === undefined)
5
- return '';
6
- if (typeof value === 'object')
7
- return JSON.stringify(value, null, 2);
8
- return String(value);
2
+ function serializeResult(result) {
3
+ return `${JSON.stringify(result, null, 2)}\n`;
9
4
  }
10
- /** Write result to stdout and exit. Errors go to stderr with exit 1. */
5
+ /** Write final structured result to stdout and exit. */
11
6
  export function outputJSON(result) {
12
- if (!result.success) {
13
- process.stderr.write(`${result.error ?? 'Unknown error'}\n`);
14
- process.exit(1);
15
- }
16
- const { success: _, ...rest } = result;
17
- const entries = Object.entries(rest).filter(([, v]) => v !== undefined);
18
- if (entries.length === 0) {
19
- process.exit(0);
20
- }
21
- const maxKey = Math.max(...entries.map(([k]) => k.length));
22
- for (const [key, value] of entries) {
23
- const formatted = formatValue(value);
24
- if (typeof value === 'object' && value !== null) {
25
- process.stdout.write(`${key}:\n${formatted}\n`);
26
- }
27
- else {
28
- process.stdout.write(`${key.padEnd(maxKey)} ${formatted}\n`);
29
- }
30
- }
31
- process.exit(0);
7
+ const normalizedResult = result.success
8
+ ? result
9
+ : { ...result, error: result.error ?? 'Unknown error' };
10
+ process.stdout.write(serializeResult(normalizedResult));
11
+ process.exit(result.success ? 0 : 1);
12
+ }
13
+ /** Write structured failure result to stdout and exit 1. */
14
+ export function outputFailure(result) {
15
+ outputJSON({ success: false, ...result });
16
+ }
17
+ /** Write a normalized contract failure result to stderr and exit 1. */
18
+ export function outputContractFailure(result) {
19
+ outputFailure(result);
32
20
  }
33
21
  /** Write error to stderr and exit 1. */
34
22
  export function outputError(error) {
35
- outputJSON({ success: false, error });
23
+ outputFailure({ error });
36
24
  }
37
25
  /** Write a progress/info message to stderr. */
38
26
  export function info(message) {
@@ -0,0 +1,35 @@
1
+ import { type Browser, type Page } from 'playwright-core';
2
+ import type { BrowseSession } from './session.js';
3
+ export declare function connectPlaywright(cdpUrl: string): Promise<Browser>;
4
+ export declare function disconnectPlaywright(browser: Browser): void;
5
+ export declare function listPages(browser: Browser): Page[];
6
+ type LaunchPageMetadata = {
7
+ page: Page | null;
8
+ url: string;
9
+ title: string;
10
+ targetId?: string;
11
+ };
12
+ export declare function readLaunchPageMetadata(browser: Browser, options?: {
13
+ requestedUrl?: string;
14
+ fallbackUrl?: string;
15
+ fallbackTitle?: string;
16
+ timeoutMs?: number;
17
+ }): Promise<LaunchPageMetadata>;
18
+ export declare function syncLaunchPage(session: BrowseSession, browser: Browser, options?: {
19
+ requestedUrl?: string;
20
+ fallbackUrl?: string;
21
+ fallbackTitle?: string;
22
+ timeoutMs?: number;
23
+ }): Promise<{
24
+ url: string;
25
+ title: string;
26
+ targetId?: string;
27
+ }>;
28
+ export declare function resolvePageByRef(browser: Browser, session: BrowseSession, pageRef: string): Promise<Page>;
29
+ export declare function syncSessionPage(session: BrowseSession, pageRef: string, page: Page): Promise<{
30
+ url: string;
31
+ title: string;
32
+ targetId?: string;
33
+ }>;
34
+ export {};
35
+ //# sourceMappingURL=playwright-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright-runtime.d.ts","sourceRoot":"","sources":["../src/playwright-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAExE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAO3D;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE,CAElD;AAmCD,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAmFF,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,kBAAkB,CAAC,CAgD7B;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgC5D;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CA8Cf;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,GACT,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAW5D"}