@nuanu-ai/agentbrowse 0.2.47 → 0.2.49

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 (198) hide show
  1. package/README.md +81 -10
  2. package/dist/agentpay-gateway.d.ts +9 -0
  3. package/dist/agentpay-gateway.d.ts.map +1 -1
  4. package/dist/agentpay-gateway.js +31 -1
  5. package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
  6. package/dist/agentpay-stagehand-llm.js +9 -1
  7. package/dist/command-api-tracing.d.ts +19 -0
  8. package/dist/command-api-tracing.d.ts.map +1 -0
  9. package/dist/command-api-tracing.js +137 -0
  10. package/dist/commands/act.d.ts.map +1 -1
  11. package/dist/commands/act.js +822 -670
  12. package/dist/commands/act.test-harness.d.ts +6 -0
  13. package/dist/commands/act.test-harness.d.ts.map +1 -1
  14. package/dist/commands/act.test-harness.js +44 -1
  15. package/dist/commands/action-acceptance.d.ts.map +1 -1
  16. package/dist/commands/action-acceptance.js +115 -0
  17. package/dist/commands/captcha-solve.d.ts.map +1 -1
  18. package/dist/commands/captcha-solve.js +83 -16
  19. package/dist/commands/click-action-executor.d.ts +0 -1
  20. package/dist/commands/click-action-executor.d.ts.map +1 -1
  21. package/dist/commands/click-action-executor.js +31 -77
  22. package/dist/commands/close.d.ts +3 -3
  23. package/dist/commands/close.d.ts.map +1 -1
  24. package/dist/commands/close.js +178 -0
  25. package/dist/commands/descriptor-validation.d.ts.map +1 -1
  26. package/dist/commands/descriptor-validation.js +75 -57
  27. package/dist/commands/end-session.d.ts +25 -0
  28. package/dist/commands/end-session.d.ts.map +1 -0
  29. package/dist/commands/end-session.js +161 -0
  30. package/dist/commands/extract-stagehand-executor.js +1 -1
  31. package/dist/commands/extract.d.ts.map +1 -1
  32. package/dist/commands/extract.js +339 -202
  33. package/dist/commands/fill-secret.d.ts +3 -3
  34. package/dist/commands/fill-secret.d.ts.map +1 -1
  35. package/dist/commands/fill-secret.js +419 -234
  36. package/dist/commands/get-secrets-catalog.d.ts.map +1 -1
  37. package/dist/commands/get-secrets-catalog.js +66 -5
  38. package/dist/commands/init.d.ts.map +1 -1
  39. package/dist/commands/init.js +6 -3
  40. package/dist/commands/interaction-kernel.d.ts +46 -0
  41. package/dist/commands/interaction-kernel.d.ts.map +1 -0
  42. package/dist/commands/interaction-kernel.js +215 -0
  43. package/dist/commands/launch.d.ts +1 -3
  44. package/dist/commands/launch.d.ts.map +1 -1
  45. package/dist/commands/launch.js +115 -27
  46. package/dist/commands/navigate.d.ts.map +1 -1
  47. package/dist/commands/navigate.js +188 -45
  48. package/dist/commands/observe-accessibility.d.ts.map +1 -1
  49. package/dist/commands/observe-accessibility.js +46 -39
  50. package/dist/commands/observe-dom-label-contract.d.ts.map +1 -1
  51. package/dist/commands/observe-dom-label-contract.js +5 -0
  52. package/dist/commands/observe-inventory.d.ts +13 -0
  53. package/dist/commands/observe-inventory.d.ts.map +1 -1
  54. package/dist/commands/observe-inventory.js +320 -65
  55. package/dist/commands/observe-persistence.d.ts.map +1 -1
  56. package/dist/commands/observe-persistence.js +3 -0
  57. package/dist/commands/observe-projection.d.ts +1 -0
  58. package/dist/commands/observe-projection.d.ts.map +1 -1
  59. package/dist/commands/observe-projection.js +7 -2
  60. package/dist/commands/observe-protected.d.ts +1 -0
  61. package/dist/commands/observe-protected.d.ts.map +1 -1
  62. package/dist/commands/observe-protected.js +9 -4
  63. package/dist/commands/observe-semantics.d.ts.map +1 -1
  64. package/dist/commands/observe-semantics.js +5 -2
  65. package/dist/commands/observe-stagehand.d.ts +1 -0
  66. package/dist/commands/observe-stagehand.d.ts.map +1 -1
  67. package/dist/commands/observe-stagehand.js +2 -0
  68. package/dist/commands/observe.d.ts +2 -0
  69. package/dist/commands/observe.d.ts.map +1 -1
  70. package/dist/commands/observe.js +387 -203
  71. package/dist/commands/observe.test-harness.d.ts +8 -0
  72. package/dist/commands/observe.test-harness.d.ts.map +1 -1
  73. package/dist/commands/observe.test-harness.js +48 -1
  74. package/dist/commands/poll-secret.d.ts +6 -0
  75. package/dist/commands/poll-secret.d.ts.map +1 -0
  76. package/dist/commands/poll-secret.js +159 -0
  77. package/dist/commands/request-secret.d.ts +6 -0
  78. package/dist/commands/request-secret.d.ts.map +1 -0
  79. package/dist/commands/request-secret.js +284 -0
  80. package/dist/commands/screenshot.d.ts.map +1 -1
  81. package/dist/commands/screenshot.js +172 -7
  82. package/dist/commands/select-action-executor.d.ts.map +1 -1
  83. package/dist/commands/semantic-observe.d.ts +4 -0
  84. package/dist/commands/semantic-observe.d.ts.map +1 -1
  85. package/dist/commands/semantic-observe.js +388 -17
  86. package/dist/commands/start-session.d.ts +31 -0
  87. package/dist/commands/start-session.d.ts.map +1 -0
  88. package/dist/commands/start-session.js +347 -0
  89. package/dist/commands/status.d.ts +2 -1
  90. package/dist/commands/status.d.ts.map +1 -1
  91. package/dist/commands/status.js +166 -144
  92. package/dist/control-semantics.d.ts +1 -0
  93. package/dist/control-semantics.d.ts.map +1 -1
  94. package/dist/control-semantics.js +51 -9
  95. package/dist/generated/build-config.d.ts +2 -0
  96. package/dist/generated/build-config.d.ts.map +1 -0
  97. package/dist/generated/build-config.js +2 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +163 -63
  100. package/dist/otel-exporter.d.ts +58 -0
  101. package/dist/otel-exporter.d.ts.map +1 -0
  102. package/dist/otel-exporter.js +263 -0
  103. package/dist/otel-projector.d.ts +75 -0
  104. package/dist/otel-projector.d.ts.map +1 -0
  105. package/dist/otel-projector.js +409 -0
  106. package/dist/owned-browser.d.ts +1 -1
  107. package/dist/owned-browser.d.ts.map +1 -1
  108. package/dist/owned-browser.js +13 -1
  109. package/dist/owned-process.d.ts +2 -0
  110. package/dist/owned-process.d.ts.map +1 -1
  111. package/dist/owned-process.js +7 -3
  112. package/dist/playwright-runtime.d.ts +1 -1
  113. package/dist/playwright-runtime.d.ts.map +1 -1
  114. package/dist/playwright-runtime.js +8 -8
  115. package/dist/run-observability.d.ts +25 -0
  116. package/dist/run-observability.d.ts.map +1 -0
  117. package/dist/run-observability.js +115 -0
  118. package/dist/run-store.d.ts +274 -0
  119. package/dist/run-store.d.ts.map +1 -0
  120. package/dist/run-store.js +631 -0
  121. package/dist/runtime-metrics.d.ts +27 -0
  122. package/dist/runtime-metrics.d.ts.map +1 -0
  123. package/dist/runtime-metrics.js +66 -0
  124. package/dist/runtime-page-state.d.ts +11 -0
  125. package/dist/runtime-page-state.d.ts.map +1 -0
  126. package/dist/runtime-page-state.js +62 -0
  127. package/dist/runtime-protected-state.d.ts +16 -0
  128. package/dist/runtime-protected-state.d.ts.map +1 -0
  129. package/dist/runtime-protected-state.js +157 -0
  130. package/dist/runtime-state.d.ts +10 -44
  131. package/dist/runtime-state.d.ts.map +1 -1
  132. package/dist/runtime-state.js +57 -222
  133. package/dist/secrets/backend.d.ts +65 -16
  134. package/dist/secrets/backend.d.ts.map +1 -1
  135. package/dist/secrets/backend.js +135 -95
  136. package/dist/secrets/catalog-sync.d.ts.map +1 -1
  137. package/dist/secrets/catalog-sync.js +4 -1
  138. package/dist/secrets/form-matcher.d.ts +5 -5
  139. package/dist/secrets/form-matcher.d.ts.map +1 -1
  140. package/dist/secrets/form-matcher.js +292 -164
  141. package/dist/secrets/intent-output.d.ts +6 -10
  142. package/dist/secrets/intent-output.d.ts.map +1 -1
  143. package/dist/secrets/intent-output.js +4 -58
  144. package/dist/secrets/mock-agentpay-cabinet.d.ts +38 -27
  145. package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -1
  146. package/dist/secrets/mock-agentpay-cabinet.js +177 -111
  147. package/dist/secrets/protected-artifact-guard.d.ts +2 -2
  148. package/dist/secrets/protected-artifact-guard.d.ts.map +1 -1
  149. package/dist/secrets/protected-artifact-guard.js +2 -2
  150. package/dist/secrets/protected-bindings.d.ts +1 -1
  151. package/dist/secrets/protected-bindings.d.ts.map +1 -1
  152. package/dist/secrets/protected-bindings.js +6 -0
  153. package/dist/secrets/protected-field-semantics.d.ts +9 -0
  154. package/dist/secrets/protected-field-semantics.d.ts.map +1 -0
  155. package/dist/secrets/protected-field-semantics.js +154 -0
  156. package/dist/secrets/protected-field-values.d.ts.map +1 -1
  157. package/dist/secrets/protected-field-values.js +3 -3
  158. package/dist/secrets/protected-fill.d.ts +1 -1
  159. package/dist/secrets/protected-fill.d.ts.map +1 -1
  160. package/dist/secrets/protected-fill.js +45 -149
  161. package/dist/secrets/protected-value-adapters.d.ts +2 -1
  162. package/dist/secrets/protected-value-adapters.d.ts.map +1 -1
  163. package/dist/secrets/protected-value-adapters.js +80 -1
  164. package/dist/secrets/request-output.d.ts +11 -0
  165. package/dist/secrets/request-output.d.ts.map +1 -0
  166. package/dist/secrets/request-output.js +75 -0
  167. package/dist/secrets/types.d.ts +15 -9
  168. package/dist/secrets/types.d.ts.map +1 -1
  169. package/dist/secrets/types.js +3 -0
  170. package/dist/session-event-exporter.d.ts +36 -0
  171. package/dist/session-event-exporter.d.ts.map +1 -0
  172. package/dist/session-event-exporter.js +428 -0
  173. package/dist/session.d.ts +16 -7
  174. package/dist/session.d.ts.map +1 -1
  175. package/dist/session.js +150 -23
  176. package/dist/sessions-backend.d.ts +354 -0
  177. package/dist/sessions-backend.d.ts.map +1 -0
  178. package/dist/sessions-backend.js +126 -0
  179. package/dist/solver/browser-launcher.d.ts +1 -1
  180. package/dist/solver/browser-launcher.d.ts.map +1 -1
  181. package/dist/solver/browser-launcher.js +39 -13
  182. package/dist/solver/captcha-solver.d.ts.map +1 -1
  183. package/dist/solver/captcha-solver.js +8 -1
  184. package/dist/solver/config.d.ts +0 -1
  185. package/dist/solver/config.d.ts.map +1 -1
  186. package/dist/solver/config.js +0 -22
  187. package/dist/solver/types.d.ts +1 -0
  188. package/dist/solver/types.d.ts.map +1 -1
  189. package/dist/workflow-session-completion.d.ts +33 -0
  190. package/dist/workflow-session-completion.d.ts.map +1 -0
  191. package/dist/workflow-session-completion.js +156 -0
  192. package/package.json +11 -1
  193. package/dist/commands/create-intent.d.ts +0 -6
  194. package/dist/commands/create-intent.d.ts.map +0 -1
  195. package/dist/commands/create-intent.js +0 -75
  196. package/dist/commands/poll-intent.d.ts +0 -6
  197. package/dist/commands/poll-intent.d.ts.map +0 -1
  198. package/dist/commands/poll-intent.js +0 -57
@@ -1,23 +1,10 @@
1
1
  /**
2
2
  * browse status — Check browser state (alive, current URL, title).
3
3
  */
4
- import { loadSession, isSessionAlive, getSessionPort, supportsCaptchaSolve } from '../session.js';
5
- import { outputJSON } from '../output.js';
6
- function normalizeComparableUrl(url) {
7
- const raw = url?.trim();
8
- if (!raw) {
9
- return null;
10
- }
11
- try {
12
- const parsed = new URL(raw);
13
- parsed.hash = '';
14
- parsed.search = '';
15
- return `${parsed.origin}${parsed.pathname}`;
16
- }
17
- catch {
18
- return raw;
19
- }
20
- }
4
+ import { getSessionPort, loadSession, supportsCaptchaSolve } from '../session.js';
5
+ import { connectPlaywright, disconnectPlaywright, resolveCurrentPageContext, } from '../playwright-runtime.js';
6
+ import { finishRunStep, startRunStep } from '../run-store.js';
7
+ import { appendCommandLifecycleEventBestEffort, captureStepSnapshotBestEffort, } from '../run-observability.js';
21
8
  function tryResolveHost(url) {
22
9
  if (!url) {
23
10
  return undefined;
@@ -29,6 +16,17 @@ function tryResolveHost(url) {
29
16
  return undefined;
30
17
  }
31
18
  }
19
+ function buildRuntimeSummary(session) {
20
+ return session?.runtime
21
+ ? {
22
+ currentPageRef: session.runtime.currentPageRef,
23
+ pageCount: Object.keys(session.runtime.pages).length,
24
+ surfaceCount: Object.keys(session.runtime.surfaces ?? {}).length,
25
+ targetCount: Object.keys(session.runtime.targets).length,
26
+ metrics: session.runtime.metrics,
27
+ }
28
+ : undefined;
29
+ }
32
30
  function buildProtectedStatusPayload(params) {
33
31
  return {
34
32
  success: true,
@@ -40,167 +38,191 @@ function buildProtectedStatusPayload(params) {
40
38
  runtime: params.runtimeSummary,
41
39
  ...(params.currentPageMismatch ? { currentPageMismatch: params.currentPageMismatch } : {}),
42
40
  protectedExposureActive: true,
43
- pageRef: params.protectedExposure.pageRef,
41
+ pageRef: params.pageRef,
44
42
  url: params.pageUrl ?? 'unknown',
45
43
  title: params.pageTitle ?? 'unknown',
46
44
  ...(tryResolveHost(params.pageUrl) ? { host: tryResolveHost(params.pageUrl) } : {}),
47
45
  fillRef: params.protectedExposure.fillRef,
48
- intentId: params.protectedExposure.intentId,
46
+ requestId: params.protectedExposure.requestId,
49
47
  activatedAt: params.protectedExposure.activatedAt,
50
48
  exposureReason: params.protectedExposure.reason,
51
49
  message: 'Protected values may still be visible on the current page.',
52
50
  reason: 'AgentBrowse is treating the current page as sensitive because a protected fill was executed and values may still be visible.',
53
51
  };
54
52
  }
55
- function matchesStoredPage(page, livePage) {
56
- const storedUrl = normalizeComparableUrl(page?.url);
57
- const currentUrl = normalizeComparableUrl(livePage.url);
58
- if (!storedUrl || !currentUrl || storedUrl !== currentUrl) {
53
+ async function readCanonicalStatus(session) {
54
+ let browser = null;
55
+ try {
56
+ browser = await connectPlaywright(session.cdpUrl);
57
+ const resolved = await resolveCurrentPageContext(browser, session);
58
+ const persisted = session.runtime?.currentPageRef;
59
+ const title = (await resolved.page
60
+ .title()
61
+ .catch(() => session.runtime?.pages[resolved.pageRef]?.title ?? '')) ||
62
+ session.runtime?.pages[resolved.pageRef]?.title ||
63
+ 'unknown';
64
+ const url = resolved.page.url() || session.runtime?.pages[resolved.pageRef]?.url || 'unknown';
65
+ return {
66
+ pageRef: resolved.pageRef,
67
+ url,
68
+ title,
69
+ ...(persisted && (persisted !== resolved.pageRef || resolved.recoveredVia)
70
+ ? {
71
+ currentPageMismatch: {
72
+ persistedPageRef: persisted,
73
+ ...(persisted !== resolved.pageRef ? { livePageRef: resolved.pageRef } : {}),
74
+ ...(resolved.recoveredVia ? { recoveredVia: resolved.recoveredVia } : {}),
75
+ },
76
+ }
77
+ : {}),
78
+ };
79
+ }
80
+ catch {
59
81
  return null;
60
82
  }
61
- if (page?.title && livePage.title && page.title === livePage.title) {
62
- return 'url-title-match';
83
+ finally {
84
+ if (browser) {
85
+ await disconnectPlaywright(browser);
86
+ }
63
87
  }
64
- return 'url-match';
65
88
  }
66
- function resolveCurrentPageMismatch(session, livePage) {
67
- const runtime = session?.runtime;
68
- if (!runtime || !livePage) {
69
- return undefined;
70
- }
71
- const persistedPageRef = runtime.currentPageRef;
72
- const currentPage = runtime.pages[persistedPageRef];
73
- if (!currentPage) {
74
- return {
75
- persistedPageRef,
76
- };
77
- }
78
- if (matchesStoredPage(currentPage, livePage)) {
89
+ async function readFallbackLiveStatus(port) {
90
+ const res = await fetch(`http://localhost:${port}/json/version`);
91
+ if (!res.ok) {
79
92
  return undefined;
80
93
  }
81
- const openerPageRef = currentPage.openerPageRef;
82
- if (openerPageRef && matchesStoredPage(runtime.pages[openerPageRef], livePage)) {
83
- return {
84
- persistedPageRef,
85
- livePageRef: openerPageRef,
86
- recoveredVia: 'opener',
87
- };
94
+ const listRes = await fetch(`http://localhost:${port}/json/list`);
95
+ const targets = (await listRes.json());
96
+ return targets.find((target) => target.type === 'page' && !target.url.startsWith('devtools://'));
97
+ }
98
+ async function finishStatusStepBestEffort(session, runId, stepId, result) {
99
+ if (!runId || !stepId) {
100
+ return;
88
101
  }
89
- const exactMatches = Object.values(runtime.pages).filter((page) => {
90
- if (page.pageRef === persistedPageRef || page.pageRef === openerPageRef) {
91
- return false;
92
- }
93
- return matchesStoredPage(page, livePage) === 'url-title-match';
102
+ const step = {
103
+ runId,
104
+ stepId,
105
+ command: 'status',
106
+ };
107
+ captureStepSnapshotBestEffort({
108
+ session: session ?? {
109
+ cdpUrl: '',
110
+ pid: 0,
111
+ launchedAt: new Date(0).toISOString(),
112
+ },
113
+ step,
114
+ phase: 'point-in-time',
115
+ pageRef: typeof result.pageRef === 'string' ? result.pageRef : session?.runtime?.currentPageRef,
116
+ url: typeof result.url === 'string' ? result.url : undefined,
117
+ title: typeof result.title === 'string' ? result.title : undefined,
94
118
  });
95
- if (exactMatches.length === 1) {
96
- return {
97
- persistedPageRef,
98
- livePageRef: exactMatches[0].pageRef,
99
- recoveredVia: 'url-title-match',
100
- };
101
- }
102
- const urlOnlyMatches = Object.values(runtime.pages).filter((page) => {
103
- if (page.pageRef === persistedPageRef || page.pageRef === openerPageRef) {
104
- return false;
105
- }
106
- return matchesStoredPage(page, livePage) === 'url-match';
119
+ appendCommandLifecycleEventBestEffort({
120
+ step,
121
+ phase: result.success ? 'completed' : 'failed',
122
+ attributes: {
123
+ alive: result.alive === true,
124
+ ...(typeof result.outcomeType === 'string' ? { outcomeType: result.outcomeType } : {}),
125
+ ...(typeof result.pageRef === 'string' ? { pageRef: result.pageRef } : {}),
126
+ },
107
127
  });
108
- if (urlOnlyMatches.length === 1) {
109
- return {
110
- persistedPageRef,
111
- livePageRef: urlOnlyMatches[0].pageRef,
112
- recoveredVia: 'url-match',
113
- };
128
+ try {
129
+ finishRunStep({
130
+ runId,
131
+ stepId,
132
+ success: result.success,
133
+ ...(typeof result.outcomeType === 'string'
134
+ ? { outcomeType: result.outcomeType }
135
+ : { outcomeType: result.alive === true ? 'browser_alive' : 'browser_not_running' }),
136
+ ...(typeof result.message === 'string' ? { message: result.message } : {}),
137
+ ...(typeof result.reason === 'string' ? { reason: result.reason } : {}),
138
+ });
139
+ }
140
+ catch {
141
+ // Best effort only.
114
142
  }
115
- return {
116
- persistedPageRef,
117
- };
118
143
  }
119
144
  export async function status() {
120
145
  const session = loadSession();
121
146
  const port = getSessionPort(session);
122
- const runtimeSummary = session?.runtime
123
- ? {
124
- currentPageRef: session.runtime.currentPageRef,
125
- pageCount: Object.keys(session.runtime.pages).length,
126
- surfaceCount: Object.keys(session.runtime.surfaces ?? {}).length,
127
- targetCount: Object.keys(session.runtime.targets).length,
128
- metrics: session.runtime.metrics,
129
- }
130
- : undefined;
131
- if (!session || !isSessionAlive(session)) {
132
- // Try CDP endpoint directly — Chrome may have been launched externally
133
- try {
134
- const res = await fetch(`http://localhost:${port}/json/version`);
135
- if (res.ok) {
136
- // Chrome is running but no session file — get page info via CDP
137
- const listRes = await fetch(`http://localhost:${port}/json/list`);
138
- const targets = (await listRes.json());
139
- const page = targets.find((t) => t.type === 'page' && !t.url.startsWith('devtools://'));
140
- const currentPageMismatch = resolveCurrentPageMismatch(session, page);
141
- const effectivePageRef = currentPageMismatch?.livePageRef ?? session?.runtime?.currentPageRef;
142
- const protectedExposure = effectivePageRef
143
- ? session?.runtime?.protectedExposureByPage?.[effectivePageRef]
144
- : undefined;
145
- if (protectedExposure) {
146
- outputJSON(buildProtectedStatusPayload({
147
- runtimeSummary,
148
- pageUrl: page?.url,
149
- pageTitle: page?.title,
150
- currentPageMismatch,
151
- protectedExposure,
152
- }));
153
- return;
154
- }
155
- outputJSON({
156
- success: true,
157
- alive: true,
158
- url: page?.url ?? 'unknown',
159
- title: page?.title ?? 'unknown',
160
- runtime: runtimeSummary,
161
- ...(currentPageMismatch ? { currentPageMismatch } : {}),
147
+ const runtimeSummary = buildRuntimeSummary(session);
148
+ const statusStep = session?.activeRunId
149
+ ? startRunStep({
150
+ runId: session.activeRunId,
151
+ command: 'status',
152
+ input: {
153
+ hasSession: session !== null,
154
+ hasRuntime: Boolean(session?.runtime),
155
+ },
156
+ })
157
+ : null;
158
+ appendCommandLifecycleEventBestEffort({
159
+ step: statusStep,
160
+ phase: 'started',
161
+ attributes: {
162
+ hasSession: session !== null,
163
+ hasRuntime: Boolean(session?.runtime),
164
+ },
165
+ });
166
+ if (session) {
167
+ const canonical = await readCanonicalStatus(session);
168
+ if (canonical) {
169
+ const protectedExposure = session.runtime?.protectedExposureByPage?.[canonical.pageRef];
170
+ if (protectedExposure) {
171
+ const result = buildProtectedStatusPayload({
172
+ runtimeSummary,
173
+ pageRef: canonical.pageRef,
174
+ pageUrl: canonical.url,
175
+ pageTitle: canonical.title,
176
+ captchaSolveCapable: supportsCaptchaSolve(session),
177
+ currentPageMismatch: canonical.currentPageMismatch,
178
+ protectedExposure,
162
179
  });
163
- return;
180
+ await finishStatusStepBestEffort(session, session.activeRunId, statusStep?.stepId, result);
181
+ return result;
164
182
  }
183
+ const result = {
184
+ success: true,
185
+ alive: true,
186
+ captchaSolveCapable: supportsCaptchaSolve(session),
187
+ pageRef: canonical.pageRef,
188
+ url: canonical.url,
189
+ title: canonical.title,
190
+ runtime: runtimeSummary,
191
+ ...(canonical.currentPageMismatch
192
+ ? { currentPageMismatch: canonical.currentPageMismatch }
193
+ : {}),
194
+ };
195
+ await finishStatusStepBestEffort(session, session.activeRunId, statusStep?.stepId, result);
196
+ return result;
165
197
  }
166
- catch {
167
- // Chrome not running
168
- }
169
- return outputJSON({ success: true, alive: false });
170
198
  }
171
- // Session exists and PID is alive — get page info via CDP
172
199
  try {
173
- const listRes = await fetch(`http://localhost:${port}/json/list`);
174
- const targets = (await listRes.json());
175
- const page = targets.find((t) => t.type === 'page' && !t.url.startsWith('devtools://'));
176
- const currentPageMismatch = resolveCurrentPageMismatch(session, page);
177
- const effectivePageRef = currentPageMismatch?.livePageRef ?? session.runtime?.currentPageRef;
178
- const protectedExposure = effectivePageRef
179
- ? session.runtime?.protectedExposureByPage?.[effectivePageRef]
180
- : undefined;
181
- if (protectedExposure) {
182
- outputJSON(buildProtectedStatusPayload({
183
- runtimeSummary,
184
- pageUrl: page?.url,
185
- pageTitle: page?.title,
186
- captchaSolveCapable: supportsCaptchaSolve(session),
187
- currentPageMismatch,
188
- protectedExposure,
189
- }));
190
- return;
200
+ const page = await readFallbackLiveStatus(port);
201
+ if (!page) {
202
+ const result = { success: true, alive: false, runtime: runtimeSummary };
203
+ await finishStatusStepBestEffort(session, session?.activeRunId, statusStep?.stepId, result);
204
+ return result;
191
205
  }
192
- outputJSON({
206
+ const result = {
193
207
  success: true,
194
208
  alive: true,
195
- captchaSolveCapable: supportsCaptchaSolve(session),
196
- url: page?.url ?? 'unknown',
197
- title: page?.title ?? 'unknown',
209
+ ...(session ? { captchaSolveCapable: supportsCaptchaSolve(session) } : {}),
210
+ url: page.url ?? 'unknown',
211
+ title: page.title ?? 'unknown',
212
+ ...(session?.runtime ? { currentPageUnresolved: true } : {}),
198
213
  runtime: runtimeSummary,
199
- ...(currentPageMismatch ? { currentPageMismatch } : {}),
200
- });
201
- return;
214
+ };
215
+ await finishStatusStepBestEffort(session, session?.activeRunId, statusStep?.stepId, result);
216
+ return result;
202
217
  }
203
218
  catch {
204
- return outputJSON({ success: true, alive: false, runtime: runtimeSummary });
219
+ const result = {
220
+ success: true,
221
+ alive: false,
222
+ ...(session?.runtime ? { currentPageUnresolved: true } : {}),
223
+ runtime: runtimeSummary,
224
+ };
225
+ await finishStatusStepBestEffort(session, session?.activeRunId, statusStep?.stepId, result);
226
+ return result;
205
227
  }
206
228
  }
@@ -11,6 +11,7 @@ export type TargetSemanticsFacts = {
11
11
  inputName?: string;
12
12
  inputType?: string;
13
13
  autocomplete?: string;
14
+ ariaAutocomplete?: string;
14
15
  surfaceKind?: string;
15
16
  controlsSurfaceSelector?: string;
16
17
  states?: TargetStateFacts;
@@ -1 +1 @@
1
- {"version":3,"file":"control-semantics.d.ts","sourceRoot":"","sources":["../src/control-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAwCtF,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,oBAAoB,GAC1B,mBAAmB,GAAG,SAAS,CAuCjC;AAwID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAYxE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,oBAAoB,GAAG,mBAAmB,EAAE,CAoG/F;AAED,wBAAgB,0BAA0B,CACxC,MAAM,CAAC,EAAE,gBAAgB,EACzB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B,GACL,uBAAuB,CAyBzB;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,mBAAmB,GAAG,SAAS,CA0EjC;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,sBAAsB,GAAG,SAAS,CA6CpC"}
1
+ {"version":3,"file":"control-semantics.d.ts","sourceRoot":"","sources":["../src/control-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAwCtF,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,oBAAoB,GAC1B,mBAAmB,GAAG,SAAS,CAuCjC;AA6LD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAYxE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,oBAAoB,GAAG,mBAAmB,EAAE,CA4G/F;AAED,wBAAgB,0BAA0B,CACxC,MAAM,CAAC,EAAE,gBAAgB,EACzB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B,GACL,uBAAuB,CAyBzB;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,mBAAmB,GAAG,SAAS,CA0EjC;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,sBAAsB,GAAG,SAAS,CA6CpC"}
@@ -71,10 +71,32 @@ function isPopupBackedTextEntry(facts) {
71
71
  }
72
72
  return false;
73
73
  }
74
- function isSelectLikePopupOwner(facts) {
74
+ function isPopupBackedComboboxFacts(facts) {
75
75
  const kind = normalizeText(facts.kind);
76
76
  const role = normalizeText(facts.role);
77
- if (kind === 'select' || kind === 'combobox' || role === 'combobox') {
77
+ const surfaceKind = normalizeText(facts.surfaceKind);
78
+ if (kind !== 'combobox' && role !== 'combobox') {
79
+ return false;
80
+ }
81
+ return (Boolean(facts.controlsSurfaceSelector) ||
82
+ surfaceKind === 'listbox' ||
83
+ surfaceKind === 'menu' ||
84
+ surfaceKind === 'floating-panel' ||
85
+ facts.states?.expanded !== undefined);
86
+ }
87
+ function isSearchableComboboxFacts(facts) {
88
+ const ariaAutocomplete = normalizeText(facts.ariaAutocomplete);
89
+ if (!isPopupBackedComboboxFacts(facts)) {
90
+ return false;
91
+ }
92
+ return (ariaAutocomplete === 'list' || ariaAutocomplete === 'both' || ariaAutocomplete === 'inline');
93
+ }
94
+ function isSelectLikePopupOwner(facts) {
95
+ const kind = normalizeText(facts.kind);
96
+ if (kind === 'select') {
97
+ return true;
98
+ }
99
+ if (isPopupBackedComboboxFacts(facts)) {
78
100
  return true;
79
101
  }
80
102
  return isPopupBackedTextEntry(facts) && facts.states?.readonly === true;
@@ -84,6 +106,9 @@ function isButtonLikeInputFacts(facts) {
84
106
  ['button', 'submit', 'reset'].includes(normalizeText(facts.inputType)));
85
107
  }
86
108
  function isSelectionItemLikeFacts(facts) {
109
+ return isPopupSelectionListitemFacts(facts) || isLegacySelectionItemLikeFacts(facts);
110
+ }
111
+ function isLegacySelectionItemLikeFacts(facts) {
87
112
  const kind = normalizeText(facts.kind);
88
113
  const role = normalizeText(facts.role);
89
114
  return (kind === 'option' ||
@@ -91,6 +116,18 @@ function isSelectionItemLikeFacts(facts) {
91
116
  role === 'menuitem' ||
92
117
  facts.structure?.family === 'structured-grid');
93
118
  }
119
+ function isPopupSelectionListitemFacts(facts) {
120
+ const kind = normalizeText(facts.kind);
121
+ const role = normalizeText(facts.role);
122
+ const surfaceKind = normalizeText(facts.surfaceKind);
123
+ return ((kind === 'listitem' || role === 'listitem') &&
124
+ (surfaceKind === 'floating-panel' ||
125
+ surfaceKind === 'listbox' ||
126
+ surfaceKind === 'menu' ||
127
+ facts.states?.selected === true ||
128
+ facts.states?.current === true ||
129
+ facts.states?.selectable === true));
130
+ }
94
131
  function isBinaryToggleControlFacts(facts) {
95
132
  const kind = normalizeText(facts.kind);
96
133
  const role = normalizeText(facts.role);
@@ -186,29 +223,34 @@ export function inferAllowedActionsFromFacts(facts) {
186
223
  if (facts.surfaceKind === 'datepicker' || isLikelyDateLikeLabel(primaryLabel(facts))) {
187
224
  actions.add('fill');
188
225
  }
189
- if (kind === 'combobox' || role === 'combobox') {
226
+ if ((kind === 'combobox' || role === 'combobox') && isSearchableComboboxFacts(facts)) {
190
227
  actions.add('fill');
191
228
  actions.add('type');
192
229
  }
193
230
  }
194
- else if (!buttonLikeInput && (kind === 'input' || kind === 'textarea' || role === 'textbox')) {
231
+ else if (!buttonLikeInput &&
232
+ (kind === 'input' ||
233
+ kind === 'textarea' ||
234
+ role === 'textbox' ||
235
+ ((kind === 'combobox' || role === 'combobox') && !isPopupBackedComboboxFacts(facts)))) {
195
236
  actions.add('click');
196
237
  actions.add('fill');
197
238
  actions.add('type');
198
239
  actions.add('press');
199
240
  }
200
- if (!selectLikePopupOwner && (kind === 'select' || kind === 'combobox' || role === 'combobox')) {
241
+ if (!selectLikePopupOwner && kind === 'select') {
201
242
  actions.add('click');
202
243
  actions.add('select');
203
244
  actions.add('press');
204
- if (kind === 'combobox' || role === 'combobox') {
205
- actions.add('fill');
206
- actions.add('type');
207
- }
208
245
  }
209
246
  if (kind === 'option' || role === 'option' || role === 'menuitem') {
210
247
  actions.add('click');
211
248
  }
249
+ if (isPopupSelectionListitemFacts(facts)) {
250
+ actions.add('click');
251
+ actions.add('press');
252
+ actions.add('select');
253
+ }
212
254
  if (checkedToggle) {
213
255
  actions.add('click');
214
256
  actions.add('press');
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_AGENTPAY_API_URL = "https://agents-api.mercuryo.io/functions/v1/api";
2
+ //# sourceMappingURL=build-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-config.d.ts","sourceRoot":"","sources":["../../src/generated/build-config.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,wBAAwB,oDAAoD,CAAC"}
@@ -0,0 +1,2 @@
1
+ // Generated build config. Local development keeps the dev API by default.
2
+ export const DEFAULT_AGENTPAY_API_URL = 'https://agents-api.mercuryo.io/functions/v1/api';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA4QA,iBAAe,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4KhE;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":";AAoYA,iBAAe,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoMhE;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAWzF"}