@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
@@ -0,0 +1,409 @@
1
+ const INTERNAL_SPAN_KIND = 1;
2
+ const CLIENT_SPAN_KIND = 3;
3
+ const STATUS_CODE_UNSET = 0;
4
+ const STATUS_CODE_OK = 1;
5
+ const STATUS_CODE_ERROR = 2;
6
+ const MAX_ATTRIBUTE_STRING_LENGTH = 256;
7
+ const MAX_REASON_LENGTH = 512;
8
+ const SENSITIVE_KEY_PATTERN = /(secret|token|password|authorization|cookie|api[-_]?key|raw[-_]?value|raw[-_]?values|resolved[-_]?values|protected[-_]?values)/i;
9
+ function isoToUnixNano(value, fallback) {
10
+ const source = value ?? fallback;
11
+ const millis = new Date(source).getTime();
12
+ const safeMillis = Number.isFinite(millis) ? millis : new Date(fallback).getTime();
13
+ return `${Math.max(0, safeMillis) * 1_000_000}`;
14
+ }
15
+ function truncateString(value, maxLength = MAX_ATTRIBUTE_STRING_LENGTH) {
16
+ return value.length <= maxLength ? value : `${value.slice(0, maxLength)}...`;
17
+ }
18
+ export function sanitizeUrlForTelemetry(url) {
19
+ try {
20
+ const parsed = new URL(url);
21
+ parsed.username = '';
22
+ parsed.password = '';
23
+ parsed.search = '';
24
+ parsed.hash = '';
25
+ return parsed.toString();
26
+ }
27
+ catch {
28
+ return truncateString(url);
29
+ }
30
+ }
31
+ function isSensitiveKey(key) {
32
+ return SENSITIVE_KEY_PATTERN.test(key);
33
+ }
34
+ function normalizePrimitiveForTelemetry(key, value) {
35
+ if (value === null || value === undefined) {
36
+ return undefined;
37
+ }
38
+ if (isSensitiveKey(key)) {
39
+ return '[redacted]';
40
+ }
41
+ if (typeof value === 'string') {
42
+ if (key.toLowerCase().includes('url')) {
43
+ return sanitizeUrlForTelemetry(value);
44
+ }
45
+ if (key.toLowerCase().includes('reason')) {
46
+ return truncateString(value, MAX_REASON_LENGTH);
47
+ }
48
+ if (key.toLowerCase().includes('message')) {
49
+ return truncateString(value, MAX_ATTRIBUTE_STRING_LENGTH);
50
+ }
51
+ return truncateString(value);
52
+ }
53
+ if (typeof value === 'boolean' || typeof value === 'number') {
54
+ return value;
55
+ }
56
+ return undefined;
57
+ }
58
+ function flattenTelemetryAttributes(prefix, value, target) {
59
+ if (value === null || value === undefined) {
60
+ return;
61
+ }
62
+ if (Array.isArray(value)) {
63
+ if (value.length === 0) {
64
+ return;
65
+ }
66
+ const normalized = value
67
+ .map((entry, index) => normalizePrimitiveForTelemetry(`${prefix}[${index}]`, entry))
68
+ .filter((entry) => entry !== undefined);
69
+ if (normalized.length > 0) {
70
+ target[prefix] = normalized;
71
+ }
72
+ return;
73
+ }
74
+ if (typeof value === 'object') {
75
+ for (const [key, nested] of Object.entries(value)) {
76
+ const nextPrefix = prefix.length > 0 ? `${prefix}.${key}` : key;
77
+ flattenTelemetryAttributes(nextPrefix, nested, target);
78
+ }
79
+ return;
80
+ }
81
+ const normalized = normalizePrimitiveForTelemetry(prefix, value);
82
+ if (normalized !== undefined) {
83
+ target[prefix] = normalized;
84
+ }
85
+ }
86
+ function toAnyValue(value) {
87
+ if (typeof value === 'string') {
88
+ return { stringValue: value };
89
+ }
90
+ if (typeof value === 'boolean') {
91
+ return { boolValue: value };
92
+ }
93
+ if (typeof value === 'number') {
94
+ if (Number.isInteger(value)) {
95
+ return { intValue: String(value) };
96
+ }
97
+ return { doubleValue: value };
98
+ }
99
+ if (Array.isArray(value)) {
100
+ const values = value.map(toAnyValue).filter((entry) => entry !== null);
101
+ return { arrayValue: { values } };
102
+ }
103
+ if (value && typeof value === 'object') {
104
+ const values = Object.entries(value)
105
+ .map(([key, nested]) => {
106
+ const nestedValue = toAnyValue(nested);
107
+ return nestedValue ? { key, value: nestedValue } : null;
108
+ })
109
+ .filter((entry) => entry !== null);
110
+ return { kvlistValue: { values } };
111
+ }
112
+ return null;
113
+ }
114
+ function toKeyValues(values) {
115
+ return Object.entries(values)
116
+ .map(([key, value]) => {
117
+ const anyValue = toAnyValue(value);
118
+ return anyValue ? { key, value: anyValue } : null;
119
+ })
120
+ .filter((entry) => entry !== null);
121
+ }
122
+ function getPrimaryRunSiteHost(run) {
123
+ return run.hostHints?.find((entry) => typeof entry === 'string' && entry.length > 0);
124
+ }
125
+ function buildResourceAttributes(run) {
126
+ const siteHost = getPrimaryRunSiteHost(run);
127
+ const values = {
128
+ 'service.name': run.resource.serviceName,
129
+ 'service.version': run.resource.serviceVersion,
130
+ 'service.instance.id': run.resource.serviceInstanceId,
131
+ 'telemetry.sdk.language': run.resource.telemetrySdkLanguage,
132
+ 'agentbrowse.session.id': run.sessionId,
133
+ 'agentbrowse.run.id': run.runId,
134
+ 'agentbrowse.run.source': run.source,
135
+ 'agentbrowse.run.entry_command': run.entryCommand,
136
+ 'agentbrowse.run.display_name': run.displayName,
137
+ 'agentbrowse.run.profile': run.profile,
138
+ 'agentbrowse.run.site_host': siteHost,
139
+ 'agentbrowse.run.started_at': run.startedAt,
140
+ 'agentbrowse.run.ended_at': run.endedAt,
141
+ 'agentbrowse.run.status': run.status,
142
+ 'agentbrowse.run.protected': run.protectedRun,
143
+ 'agentbrowse.run.final_outcome_type': run.finalOutcome?.outcomeType,
144
+ 'agentbrowse.run.final_message': run.finalOutcome?.message,
145
+ 'agentbrowse.run.final_reason': run.finalOutcome?.reason,
146
+ };
147
+ if (run.hostHints && run.hostHints.length > 0) {
148
+ values['agentbrowse.run.host_hints'] = run.hostHints.map((host) => truncateString(host));
149
+ }
150
+ return toKeyValues(values);
151
+ }
152
+ function buildSnapshotAttributes(snapshot) {
153
+ return {
154
+ 'agentbrowse.snapshot.phase': snapshot.phase,
155
+ 'agentbrowse.snapshot.page_ref': snapshot.pageRef,
156
+ 'agentbrowse.snapshot.url': sanitizeUrlForTelemetry(snapshot.url),
157
+ 'agentbrowse.snapshot.tab_count': snapshot.tabs.length,
158
+ 'agentbrowse.snapshot.runtime.page_count': snapshot.runtimeSummary.pageCount,
159
+ 'agentbrowse.snapshot.runtime.surface_count': snapshot.runtimeSummary.surfaceCount,
160
+ 'agentbrowse.snapshot.runtime.target_count': snapshot.runtimeSummary.targetCount,
161
+ 'agentbrowse.snapshot.runtime.fillable_form_count': snapshot.runtimeSummary.fillableFormCount,
162
+ 'agentbrowse.snapshot.runtime.secret_request_count': snapshot.runtimeSummary.secretRequestCount,
163
+ 'agentbrowse.snapshot.runtime.protected_page_count': snapshot.runtimeSummary.protectedPageCount,
164
+ 'agentbrowse.snapshot.protected.active': snapshot.protectionState?.protectedExposureActive ?? false,
165
+ 'agentbrowse.snapshot.protected.fill_ref': snapshot.protectionState?.fillRef,
166
+ 'agentbrowse.snapshot.protected.request_id': snapshot.protectionState?.requestId,
167
+ 'agentbrowse.snapshot.protected.reason': snapshot.protectionState?.reason,
168
+ };
169
+ }
170
+ function buildArtifactAttributes(manifest) {
171
+ return {
172
+ 'agentbrowse.artifacts.manifest_id': manifest.artifactManifestId,
173
+ 'agentbrowse.artifacts.screenshot_count': manifest.screenshots.length,
174
+ 'agentbrowse.artifacts.html_count': manifest.htmlSnapshots.length,
175
+ 'agentbrowse.artifacts.trace_count': manifest.traces.length,
176
+ 'agentbrowse.artifacts.log_count': manifest.logs.length,
177
+ 'agentbrowse.artifacts.suppressed_count': manifest.suppressed.length,
178
+ 'agentbrowse.artifacts.suppressed_reasons': manifest.suppressed.map((entry) => `${entry.kind}:${entry.reason}`),
179
+ };
180
+ }
181
+ function buildStepAttributes(run, step, artifactManifest) {
182
+ const values = {
183
+ 'agentbrowse.run.id': run.runId,
184
+ 'agentbrowse.session.id': run.sessionId,
185
+ 'agentbrowse.step.id': step.stepId,
186
+ 'agentbrowse.step.ordinal': step.ordinal,
187
+ 'agentbrowse.step.command': step.command,
188
+ 'agentbrowse.step.protected': step.protectedStep,
189
+ 'agentbrowse.step.page_ref': step.refs?.pageRef,
190
+ 'agentbrowse.step.target_ref': step.refs?.targetRef,
191
+ 'agentbrowse.step.surface_ref': step.refs?.surfaceRef,
192
+ 'agentbrowse.step.fill_ref': step.refs?.fillRef,
193
+ 'agentbrowse.step.request_id': step.refs?.requestId,
194
+ 'agentbrowse.step.success': step.outputSummary?.success,
195
+ 'agentbrowse.step.outcome_type': step.outputSummary?.outcomeType,
196
+ 'agentbrowse.step.message': step.outputSummary?.message,
197
+ 'agentbrowse.step.reason': step.outputSummary?.reason,
198
+ 'agentbrowse.step.before_snapshot_id': step.beforeSnapshotId,
199
+ 'agentbrowse.step.after_snapshot_id': step.afterSnapshotId,
200
+ 'agentbrowse.step.event_count': step.eventIds.length,
201
+ 'agentbrowse.step.child_span_count': step.childSpans?.length ?? step.childSpanIds?.length ?? 0,
202
+ 'agentbrowse.trace.propagation_mode': run.traceContext.propagationMode,
203
+ };
204
+ const flattenedInput = {};
205
+ flattenTelemetryAttributes('agentbrowse.step.input', step.input, flattenedInput);
206
+ Object.assign(values, flattenedInput);
207
+ if (artifactManifest) {
208
+ Object.assign(values, buildArtifactAttributes(artifactManifest));
209
+ }
210
+ return toKeyValues(values);
211
+ }
212
+ function buildRunRootSpanName(run) {
213
+ const siteHost = getPrimaryRunSiteHost(run);
214
+ const displayName = typeof run.displayName === 'string' && run.displayName.trim().length > 0
215
+ ? run.displayName.trim()
216
+ : undefined;
217
+ if (siteHost && displayName) {
218
+ return truncateString(`${siteHost} - ${displayName}`);
219
+ }
220
+ if (displayName) {
221
+ return truncateString(displayName);
222
+ }
223
+ if (siteHost) {
224
+ return truncateString(siteHost);
225
+ }
226
+ if (run.entryCommand) {
227
+ return `agentbrowse.${truncateString(run.entryCommand)}`;
228
+ }
229
+ return 'agentbrowse.run';
230
+ }
231
+ function buildRunRootSpanAttributes(run) {
232
+ const siteHost = getPrimaryRunSiteHost(run);
233
+ const values = {
234
+ 'agentbrowse.run.id': run.runId,
235
+ 'agentbrowse.session.id': run.sessionId,
236
+ 'agentbrowse.run.entry_command': run.entryCommand,
237
+ 'agentbrowse.run.display_name': run.displayName,
238
+ 'agentbrowse.run.site_host': siteHost,
239
+ 'agentbrowse.run.status': run.status,
240
+ 'agentbrowse.run.protected': run.protectedRun,
241
+ 'agentbrowse.run.step_count': run.stepIds.length,
242
+ 'agentbrowse.run.final_outcome_type': run.finalOutcome?.outcomeType,
243
+ 'agentbrowse.run.final_message': run.finalOutcome?.message,
244
+ 'agentbrowse.run.final_reason': run.finalOutcome?.reason,
245
+ };
246
+ if (run.hostHints && run.hostHints.length > 0) {
247
+ values['agentbrowse.run.host_hints'] = run.hostHints.map((host) => truncateString(host));
248
+ }
249
+ return toKeyValues(values);
250
+ }
251
+ function buildEventAttributes(attributes) {
252
+ const flattened = {};
253
+ flattenTelemetryAttributes('', attributes, flattened);
254
+ const keyValues = toKeyValues(flattened);
255
+ return keyValues.length > 0 ? keyValues : undefined;
256
+ }
257
+ function buildSpanEvents(params) {
258
+ const spanEvents = params.events.map((event) => ({
259
+ name: event.name,
260
+ timeUnixNano: isoToUnixNano(event.emittedAt, event.emittedAt),
261
+ ...(buildEventAttributes(event.attributes)
262
+ ? { attributes: buildEventAttributes(event.attributes) }
263
+ : {}),
264
+ }));
265
+ for (const snapshot of [params.beforeSnapshot, params.afterSnapshot]) {
266
+ if (!snapshot) {
267
+ continue;
268
+ }
269
+ spanEvents.push({
270
+ name: `browser.snapshot.${snapshot.phase}`,
271
+ timeUnixNano: isoToUnixNano(snapshot.capturedAt, snapshot.capturedAt),
272
+ attributes: toKeyValues(buildSnapshotAttributes(snapshot)),
273
+ });
274
+ }
275
+ if (params.artifactManifest) {
276
+ spanEvents.push({
277
+ name: 'artifacts.recorded',
278
+ timeUnixNano: params.afterSnapshot
279
+ ? isoToUnixNano(params.afterSnapshot.capturedAt, params.afterSnapshot.capturedAt)
280
+ : String(Date.now() * 1_000_000),
281
+ attributes: toKeyValues(buildArtifactAttributes(params.artifactManifest)),
282
+ });
283
+ }
284
+ spanEvents.sort((left, right) => left.timeUnixNano.localeCompare(right.timeUnixNano));
285
+ return spanEvents;
286
+ }
287
+ function buildSpanLinks(step) {
288
+ if (!step.otel.linkedSpanIds || step.otel.linkedSpanIds.length === 0) {
289
+ return undefined;
290
+ }
291
+ return step.otel.linkedSpanIds.map((spanId) => ({
292
+ traceId: step.otel.traceId,
293
+ spanId,
294
+ }));
295
+ }
296
+ function buildSpanStatus(step) {
297
+ const code = step.otel.statusCode === 'ok'
298
+ ? STATUS_CODE_OK
299
+ : step.otel.statusCode === 'error'
300
+ ? STATUS_CODE_ERROR
301
+ : STATUS_CODE_UNSET;
302
+ return {
303
+ code,
304
+ ...(step.otel.statusMessage ? { message: truncateString(step.otel.statusMessage) } : {}),
305
+ };
306
+ }
307
+ function buildChildSpanStatus(childSpan) {
308
+ const code = childSpan.statusCode === 'ok'
309
+ ? STATUS_CODE_OK
310
+ : childSpan.statusCode === 'error'
311
+ ? STATUS_CODE_ERROR
312
+ : STATUS_CODE_UNSET;
313
+ return {
314
+ code,
315
+ ...(childSpan.statusMessage ? { message: truncateString(childSpan.statusMessage) } : {}),
316
+ };
317
+ }
318
+ function buildChildSpanAttributes(childSpan) {
319
+ return toKeyValues(childSpan.attributes);
320
+ }
321
+ export function projectStepToOtlpTraceRequest(params) {
322
+ const span = {
323
+ traceId: params.step.otel.traceId,
324
+ spanId: params.step.otel.spanId,
325
+ ...(params.step.otel.parentSpanId ? { parentSpanId: params.step.otel.parentSpanId } : {}),
326
+ name: params.step.otel.spanName,
327
+ kind: INTERNAL_SPAN_KIND,
328
+ startTimeUnixNano: isoToUnixNano(params.step.startedAt, params.run.startedAt),
329
+ endTimeUnixNano: isoToUnixNano(params.step.endedAt, params.step.startedAt),
330
+ attributes: buildStepAttributes(params.run, params.step, params.artifactManifest ?? null),
331
+ events: buildSpanEvents({
332
+ events: params.events ?? [],
333
+ beforeSnapshot: params.beforeSnapshot,
334
+ afterSnapshot: params.afterSnapshot,
335
+ artifactManifest: params.artifactManifest,
336
+ }),
337
+ ...(buildSpanLinks(params.step) ? { links: buildSpanLinks(params.step) } : {}),
338
+ status: buildSpanStatus(params.step),
339
+ };
340
+ const childSpans = (params.step.childSpans ?? []).map((childSpan) => ({
341
+ traceId: params.step.otel.traceId,
342
+ spanId: childSpan.spanId,
343
+ parentSpanId: childSpan.parentSpanId,
344
+ name: childSpan.name,
345
+ kind: CLIENT_SPAN_KIND,
346
+ startTimeUnixNano: isoToUnixNano(childSpan.startedAt, params.step.startedAt),
347
+ endTimeUnixNano: isoToUnixNano(childSpan.endedAt, childSpan.startedAt),
348
+ attributes: buildChildSpanAttributes(childSpan),
349
+ status: buildChildSpanStatus(childSpan),
350
+ }));
351
+ return {
352
+ resourceSpans: [
353
+ {
354
+ resource: {
355
+ attributes: buildResourceAttributes(params.run),
356
+ },
357
+ scopeSpans: [
358
+ {
359
+ scope: {
360
+ name: params.step.otel.instrumentationScope,
361
+ },
362
+ spans: [span, ...childSpans],
363
+ },
364
+ ],
365
+ },
366
+ ],
367
+ };
368
+ }
369
+ export function projectRunRootToOtlpTraceRequest(params) {
370
+ const statusCode = params.run.finalOutcome?.success === true || params.run.status === 'completed'
371
+ ? STATUS_CODE_OK
372
+ : params.run.finalOutcome?.success === false ||
373
+ params.run.status === 'failed' ||
374
+ params.run.status === 'aborted'
375
+ ? STATUS_CODE_ERROR
376
+ : STATUS_CODE_UNSET;
377
+ const span = {
378
+ traceId: params.run.traceContext.traceId,
379
+ spanId: params.run.traceContext.rootSpanId,
380
+ name: buildRunRootSpanName(params.run),
381
+ kind: INTERNAL_SPAN_KIND,
382
+ startTimeUnixNano: isoToUnixNano(params.run.startedAt, params.run.startedAt),
383
+ endTimeUnixNano: isoToUnixNano(params.run.endedAt, params.run.startedAt),
384
+ attributes: buildRunRootSpanAttributes(params.run),
385
+ status: {
386
+ code: statusCode,
387
+ ...(params.run.finalOutcome?.reason
388
+ ? { message: truncateString(params.run.finalOutcome.reason) }
389
+ : {}),
390
+ },
391
+ };
392
+ return {
393
+ resourceSpans: [
394
+ {
395
+ resource: {
396
+ attributes: buildResourceAttributes(params.run),
397
+ },
398
+ scopeSpans: [
399
+ {
400
+ scope: {
401
+ name: 'agentbrowse.local-run-store',
402
+ },
403
+ spans: [span],
404
+ },
405
+ ],
406
+ },
407
+ ],
408
+ };
409
+ }
@@ -1,7 +1,7 @@
1
1
  import { type BrowseSession } from './session.js';
2
2
  export type CloseOwnedBrowserResult = {
3
3
  success: true;
4
- method: 'already_closed' | 'cdp' | 'signal';
4
+ method: 'already_closed' | 'cdp' | 'signal' | 'cleanup';
5
5
  } | {
6
6
  success: false;
7
7
  reason: string;
@@ -1 +1 @@
1
- {"version":3,"file":"owned-browser.d.ts","sourceRoot":"","sources":["../src/owned-browser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAKlE,MAAM,MAAM,uBAAuB,GAC/B;IACE,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,gBAAgB,GAAG,KAAK,GAAG,QAAQ,CAAC;CAC7C,GACD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA2BhG"}
1
+ {"version":3,"file":"owned-browser.d.ts","sourceRoot":"","sources":["../src/owned-browser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAMlE,MAAM,MAAM,uBAAuB,GAC/B;IACE,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;CACzD,GACD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAuChG"}
@@ -1,6 +1,7 @@
1
1
  import { connectPlaywright } from './playwright-runtime.js';
2
- import { terminateOwnedPid } from './owned-process.js';
2
+ import { cleanupManagedBrowserPids, terminateOwnedPid } from './owned-process.js';
3
3
  import { getSessionPort } from './session.js';
4
+ import { getUserDataDir } from './solver/config.js';
4
5
  const ENDPOINT_WAIT_ATTEMPTS = 10;
5
6
  const ENDPOINT_WAIT_MS = 100;
6
7
  export async function closeOwnedBrowser(session) {
@@ -19,6 +20,17 @@ export async function closeOwnedBrowser(session) {
19
20
  method: endpointAliveBeforeClose ? 'signal' : 'already_closed',
20
21
  };
21
22
  }
23
+ if (session.profile) {
24
+ const cleanup = await cleanupManagedBrowserPids({
25
+ userDataDir: getUserDataDir(session.profile),
26
+ });
27
+ if (await waitForBrowserEndpointToClose(port)) {
28
+ return {
29
+ success: true,
30
+ method: cleanup.terminated.length > 0 ? 'cleanup' : 'already_closed',
31
+ };
32
+ }
33
+ }
22
34
  if (!endpointAliveBeforeClose && termination === 'not_found') {
23
35
  return { success: true, method: 'already_closed' };
24
36
  }
@@ -7,9 +7,11 @@ export declare function isPidAlive(pid: number): boolean;
7
7
  export declare function terminateOwnedPid(pid: number): Promise<OwnedPidTerminationResult>;
8
8
  export declare function cleanupManagedBrowserPids(options?: {
9
9
  excludePids?: Iterable<number>;
10
+ userDataDir?: string;
10
11
  }): Promise<ManagedBrowserCleanupResult>;
11
12
  export declare function listManagedBrowserPids(options?: {
12
13
  processTable?: string;
14
+ userDataDir?: string;
13
15
  }): number[];
14
16
  export declare function isManagedBrowserPid(pid: number, options?: {
15
17
  processTable?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"owned-process.d.ts","sourceRoot":"","sources":["../src/owned-process.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,yBAAyB,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,aAAa,CAAC;AACjG,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAW/C;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAOvF;AAiCD,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAO,GAC/C,OAAO,CAAC,2BAA2B,CAAC,CAqBtC;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,MAAM,EAAE,CAuBV;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,OAAO,CAET"}
1
+ {"version":3,"file":"owned-process.d.ts","sourceRoot":"","sources":["../src/owned-process.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,yBAAyB,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,aAAa,CAAC;AACjG,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAW/C;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAOvF;AAiCD,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACrE,OAAO,CAAC,2BAA2B,CAAC,CAqBtC;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,MAAM,EAAE,CAwBV;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,OAAO,CAET"}
@@ -58,7 +58,7 @@ export async function cleanupManagedBrowserPids(options = {}) {
58
58
  const excludePids = new Set(options.excludePids ?? []);
59
59
  const terminated = [];
60
60
  const blocked = [];
61
- for (const pid of listManagedBrowserPids()) {
61
+ for (const pid of listManagedBrowserPids({ userDataDir: options.userDataDir })) {
62
62
  if (excludePids.has(pid)) {
63
63
  continue;
64
64
  }
@@ -76,6 +76,7 @@ export async function cleanupManagedBrowserPids(options = {}) {
76
76
  export function listManagedBrowserPids(options = {}) {
77
77
  const processTable = options.processTable ?? readProcessTable();
78
78
  const pids = new Set();
79
+ const scopedUserDataDir = options.userDataDir ? path.resolve(options.userDataDir) : null;
79
80
  for (const line of processTable.split(/\r?\n/)) {
80
81
  const match = line.trimStart().match(/^(\d+)\s+(.*)$/);
81
82
  if (!match) {
@@ -86,7 +87,7 @@ export function listManagedBrowserPids(options = {}) {
86
87
  if (!Number.isFinite(pid) || pid <= 0 || pid === process.pid) {
87
88
  continue;
88
89
  }
89
- if (!isManagedBrowserCommand(command)) {
90
+ if (!isManagedBrowserCommand(command, scopedUserDataDir)) {
90
91
  continue;
91
92
  }
92
93
  pids.add(pid);
@@ -123,7 +124,7 @@ function readProcessTable() {
123
124
  return '';
124
125
  }
125
126
  }
126
- function isManagedBrowserCommand(command) {
127
+ function isManagedBrowserCommand(command, scopedUserDataDir) {
127
128
  if (!command.includes('--remote-debugging-address=127.0.0.1')) {
128
129
  return false;
129
130
  }
@@ -132,6 +133,9 @@ function isManagedBrowserCommand(command) {
132
133
  return false;
133
134
  }
134
135
  const normalizedUserDataDir = path.resolve(userDataDir);
136
+ if (scopedUserDataDir && normalizedUserDataDir !== scopedUserDataDir) {
137
+ return false;
138
+ }
135
139
  return MANAGED_PROFILE_ROOTS.some((root) => isWithinRoot(normalizedUserDataDir, root));
136
140
  }
137
141
  function readCommandFlag(command, flag) {
@@ -1,7 +1,7 @@
1
1
  import { type Browser, type Page } from 'playwright-core';
2
2
  import type { BrowseSession } from './session.js';
3
3
  export declare function connectPlaywright(cdpUrl: string): Promise<Browser>;
4
- export declare function disconnectPlaywright(browser: Browser): void;
4
+ export declare function disconnectPlaywright(browser: Browser): Promise<void>;
5
5
  export declare function listPages(browser: Browser): Page[];
6
6
  type LaunchPageMetadata = {
7
7
  page: Page | null;
@@ -1 +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;AA8CD,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;AAQF,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,QAAQ,GAAG,gBAAgB,CAAC;CAC5C,CAAC;AA4IF,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,CA+C7B;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;AA+CD,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,0BAA0B,CAAC,CAqCrC;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,EACV,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,MAAM,CAAC;CACrB,GACL,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB5D"}
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;AAIlD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAExE;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE,CAElD;AA8CD,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;AAQF,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,QAAQ,GAAG,gBAAgB,CAAC;CAC5C,CAAC;AA4IF,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,CA+C7B;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;AA+CD,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,0BAA0B,CAAC,CAqCrC;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,EACV,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,MAAM,CAAC;CACrB,GACL,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB5D"}
@@ -1,15 +1,15 @@
1
1
  import { chromium } from 'playwright-core';
2
- import { ensureRuntimeState, registerPage, updatePage } from './runtime-state.js';
2
+ import { ensureRuntimeState } from './runtime-state.js';
3
+ import { registerPage, updatePage } from './runtime-page-state.js';
3
4
  export async function connectPlaywright(cdpUrl) {
4
5
  return chromium.connectOverCDP(cdpUrl);
5
6
  }
6
- export function disconnectPlaywright(browser) {
7
- void browser;
8
- // Playwright exposes no safe public disconnect for CDP browsers here.
9
- // Private connection close paths can terminate the remote browser target,
10
- // which breaks follow-up observe/act calls in the same process.
11
- // The CLI process is short-lived, so we intentionally leave the CDP socket
12
- // cleanup to process teardown instead of risking remote browser shutdown.
7
+ export async function disconnectPlaywright(browser) {
8
+ const maybeClose = browser.close;
9
+ if (typeof maybeClose !== 'function') {
10
+ return;
11
+ }
12
+ await Promise.resolve(maybeClose.call(browser)).catch(() => undefined);
13
13
  }
14
14
  export function listPages(browser) {
15
15
  return browser.contexts().flatMap((context) => context.pages());
@@ -0,0 +1,25 @@
1
+ import type { BrowseSession } from './session.js';
2
+ import { type BrowserStateSnapshot, type RunEventRecord, type StepRecord } from './run-store.js';
3
+ type StepHandle = Pick<StepRecord, 'runId' | 'stepId' | 'command'> | null | undefined;
4
+ export declare function captureStepSnapshotBestEffort(params: {
5
+ session: BrowseSession;
6
+ step: StepHandle;
7
+ phase: BrowserStateSnapshot['phase'];
8
+ pageRef?: string;
9
+ url?: string;
10
+ title?: string;
11
+ artifactRefs?: BrowserStateSnapshot['artifactRefs'];
12
+ }): string | undefined;
13
+ export declare function appendStepEventBestEffort(params: {
14
+ step: StepHandle;
15
+ source: RunEventRecord['source'];
16
+ name: string;
17
+ attributes?: Record<string, unknown>;
18
+ }): string | undefined;
19
+ export declare function appendCommandLifecycleEventBestEffort(params: {
20
+ step: StepHandle;
21
+ phase: 'started' | 'completed' | 'failed';
22
+ attributes?: Record<string, unknown>;
23
+ }): string | undefined;
24
+ export {};
25
+ //# sourceMappingURL=run-observability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-observability.d.ts","sourceRoot":"","sources":["../src/run-observability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AAExB,KAAK,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AA+EtF,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;CACrD,GAAG,MAAM,GAAG,SAAS,CAqBrB;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,GAAG,MAAM,GAAG,SAAS,CAiBrB;AAED,wBAAgB,qCAAqC,CAAC,MAAM,EAAE;IAC5D,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,sBAWA"}