pi-agent-browser-native 0.9.2 → 0.9.4

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 (392) hide show
  1. package/CHANGELOG.md +91 -5
  2. package/README.md +120 -86
  3. package/dist/extensions/agent-browser/index.js +43065 -2016
  4. package/dist/extensions/agent-browser/lib/argv-descriptor.js +49 -26
  5. package/dist/extensions/agent-browser/lib/argv-grammar.js +82 -93
  6. package/dist/extensions/agent-browser/lib/bash-guard.js +129 -126
  7. package/dist/extensions/agent-browser/lib/batch-lifecycle.js +113 -49
  8. package/dist/extensions/agent-browser/lib/browser-execution-claim-codec.js +61 -0
  9. package/dist/extensions/agent-browser/lib/browser-execution-claim-storage.js +232 -0
  10. package/dist/extensions/agent-browser/lib/browser-execution-claims.js +202 -0
  11. package/dist/extensions/agent-browser/lib/browser-execution-identity.js +77 -0
  12. package/dist/extensions/agent-browser/lib/browser-journal-branch.js +98 -0
  13. package/dist/extensions/agent-browser/lib/browser-journal-contracts.js +1 -0
  14. package/dist/extensions/agent-browser/lib/browser-journal-projection.js +221 -0
  15. package/dist/extensions/agent-browser/lib/browser-journal-reader.js +89 -0
  16. package/dist/extensions/agent-browser/lib/browser-journal-replay.js +246 -0
  17. package/dist/extensions/agent-browser/lib/browser-journal.js +103 -394
  18. package/dist/extensions/agent-browser/lib/browser-legacy-pages.js +220 -0
  19. package/dist/extensions/agent-browser/lib/browser-legacy-projection.js +282 -0
  20. package/dist/extensions/agent-browser/lib/browser-legacy-types.js +1 -0
  21. package/dist/extensions/agent-browser/lib/browser-session-conversion-stream.js +217 -0
  22. package/dist/extensions/agent-browser/lib/browser-session-conversion.js +80 -335
  23. package/dist/extensions/agent-browser/lib/browser-transcript-contracts.js +35 -0
  24. package/dist/extensions/agent-browser/lib/browser-transcript-validation.js +166 -0
  25. package/dist/extensions/agent-browser/lib/browser-transcript.js +137 -81
  26. package/dist/extensions/agent-browser/lib/browser-value-parsing.js +15 -0
  27. package/dist/extensions/agent-browser/lib/command-capabilities.js +340 -0
  28. package/dist/extensions/agent-browser/lib/command-policy.js +107 -88
  29. package/dist/extensions/agent-browser/lib/command-taxonomy.js +49 -322
  30. package/dist/extensions/agent-browser/lib/config-policy.js +138 -343
  31. package/dist/extensions/agent-browser/lib/config-providers.js +71 -0
  32. package/dist/extensions/agent-browser/lib/config-validation.js +218 -0
  33. package/dist/extensions/agent-browser/lib/config.js +19 -7
  34. package/dist/extensions/agent-browser/lib/electron/cdp.js +15 -7
  35. package/dist/extensions/agent-browser/lib/electron/cleanup.js +134 -55
  36. package/dist/extensions/agent-browser/lib/electron/discovery-darwin.js +109 -0
  37. package/dist/extensions/agent-browser/lib/electron/discovery-desktop.js +136 -0
  38. package/dist/extensions/agent-browser/lib/electron/discovery-evidence.js +89 -0
  39. package/dist/extensions/agent-browser/lib/electron/discovery-linux.js +93 -0
  40. package/dist/extensions/agent-browser/lib/electron/discovery-packages.js +162 -0
  41. package/dist/extensions/agent-browser/lib/electron/discovery-types.js +2 -0
  42. package/dist/extensions/agent-browser/lib/electron/discovery.js +140 -549
  43. package/dist/extensions/agent-browser/lib/electron/launch-monitor.js +102 -0
  44. package/dist/extensions/agent-browser/lib/electron/launch-process.js +209 -0
  45. package/dist/extensions/agent-browser/lib/electron/launch-types.js +2 -0
  46. package/dist/extensions/agent-browser/lib/electron/launch.js +249 -354
  47. package/dist/extensions/agent-browser/lib/executable-path.js +21 -12
  48. package/dist/extensions/agent-browser/lib/execution-cwd.js +35 -18
  49. package/dist/extensions/agent-browser/lib/input-modes/electron.js +162 -121
  50. package/dist/extensions/agent-browser/lib/input-modes/job.js +116 -313
  51. package/dist/extensions/agent-browser/lib/input-modes/lookup-network-evidence.js +104 -0
  52. package/dist/extensions/agent-browser/lib/input-modes/lookup-plan.js +132 -0
  53. package/dist/extensions/agent-browser/lib/input-modes/lookup-redaction.js +57 -0
  54. package/dist/extensions/agent-browser/lib/input-modes/lookup-source-evidence.js +151 -0
  55. package/dist/extensions/agent-browser/lib/input-modes/lookup-workspace.js +142 -0
  56. package/dist/extensions/agent-browser/lib/input-modes/lookups.js +57 -412
  57. package/dist/extensions/agent-browser/lib/input-modes/params.js +63 -17
  58. package/dist/extensions/agent-browser/lib/input-modes/qa-analysis.js +268 -0
  59. package/dist/extensions/agent-browser/lib/input-modes/qa-presentation.js +117 -0
  60. package/dist/extensions/agent-browser/lib/input-modes/script-child.js +396 -0
  61. package/dist/extensions/agent-browser/lib/input-modes/script-protocol.js +86 -0
  62. package/dist/extensions/agent-browser/lib/input-modes/script-types.js +1 -0
  63. package/dist/extensions/agent-browser/lib/input-modes/script-validation.js +60 -0
  64. package/dist/extensions/agent-browser/lib/input-modes/script.js +60 -409
  65. package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +218 -128
  66. package/dist/extensions/agent-browser/lib/input-modes/shared.js +15 -4
  67. package/dist/extensions/agent-browser/lib/input-modes/types.js +56 -7
  68. package/dist/extensions/agent-browser/lib/json-schema.js +22 -10
  69. package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +17 -5
  70. package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +92 -425
  71. package/dist/extensions/agent-browser/lib/managed-session-posix-storage.js +58 -0
  72. package/dist/extensions/agent-browser/lib/managed-session-project-identity.js +244 -0
  73. package/dist/extensions/agent-browser/lib/managed-session-restore-context.js +84 -0
  74. package/dist/extensions/agent-browser/lib/managed-session-restore-policy.js +119 -0
  75. package/dist/extensions/agent-browser/lib/managed-session-restore-state.js +83 -0
  76. package/dist/extensions/agent-browser/lib/managed-session-restore.js +168 -300
  77. package/dist/extensions/agent-browser/lib/managed-session-snapshot-records.js +277 -0
  78. package/dist/extensions/agent-browser/lib/managed-session-snapshots.js +128 -305
  79. package/dist/extensions/agent-browser/lib/managed-session-storage.js +56 -253
  80. package/dist/extensions/agent-browser/lib/native-confirmation.js +140 -0
  81. package/dist/extensions/agent-browser/lib/native-output.js +44 -9
  82. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +107 -66
  83. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-merge.js +14 -6
  84. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +109 -57
  85. package/dist/extensions/agent-browser/lib/orchestration/browser-run/browser-observation-result.js +82 -0
  86. package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +171 -57
  87. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostic-values.js +31 -0
  88. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +152 -781
  89. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-observation.js +202 -0
  90. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-text-diagnostics.js +109 -0
  91. package/dist/extensions/agent-browser/lib/orchestration/browser-run/fill-diagnostics.js +119 -0
  92. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-action-recovery.js +147 -0
  93. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-actions.js +144 -0
  94. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-content.js +123 -0
  95. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-contracts.js +1 -0
  96. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-details.js +156 -0
  97. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js +179 -0
  98. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-evidence.js +39 -0
  99. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-missing-binary.js +89 -0
  100. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-recovery.js +97 -0
  101. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js +106 -0
  102. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-timeout.js +110 -0
  103. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +41 -538
  104. package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +204 -108
  105. package/dist/extensions/agent-browser/lib/orchestration/browser-run/interaction-diagnostics.js +290 -0
  106. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-close.js +167 -0
  107. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-inspection.js +108 -0
  108. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +127 -199
  109. package/dist/extensions/agent-browser/lib/orchestration/browser-run/native-helper-observation.js +65 -0
  110. package/dist/extensions/agent-browser/lib/orchestration/browser-run/observation-types.js +1 -0
  111. package/dist/extensions/agent-browser/lib/orchestration/browser-run/overlay-diagnostics.js +120 -0
  112. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +113 -30
  113. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +109 -28
  114. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter-data.js +150 -0
  115. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +138 -253
  116. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-rendered-text.js +147 -0
  117. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +59 -24
  118. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-artifacts.js +159 -0
  119. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-command.js +131 -0
  120. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-contracts.js +1 -0
  121. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-daemon.js +93 -0
  122. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-failure.js +42 -0
  123. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-guards.js +242 -0
  124. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-input.js +75 -0
  125. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-observations.js +92 -0
  126. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-selection.js +254 -0
  127. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-state.js +121 -0
  128. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-refs.js +130 -0
  129. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-resources.js +114 -0
  130. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-semantic.js +121 -0
  131. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-session-plan.js +222 -0
  132. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-timeouts.js +68 -0
  133. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +176 -1114
  134. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-analysis.js +191 -0
  135. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-confirmation.js +152 -0
  136. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-diagnostics.js +182 -0
  137. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-electron.js +150 -0
  138. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-contracts.js +1 -0
  139. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase-contracts.js +1 -0
  140. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase.js +115 -0
  141. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle.js +256 -0
  142. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed-contracts.js +1 -0
  143. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed.js +256 -0
  144. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase-contracts.js +1 -0
  145. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase.js +93 -0
  146. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native.js +113 -0
  147. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation-contracts.js +1 -0
  148. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation.js +316 -0
  149. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-ownership.js +28 -0
  150. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase-contracts.js +1 -0
  151. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase.js +142 -0
  152. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation-contracts.js +1 -0
  153. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation.js +333 -0
  154. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase-contracts.js +1 -0
  155. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase.js +71 -0
  156. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication.js +201 -0
  157. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-receipts.js +183 -0
  158. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-refs.js +200 -0
  159. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-tabs.js +142 -0
  160. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +18 -910
  161. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +23 -13
  162. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-receipt-reconciliation.js +198 -0
  163. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-contracts.js +1 -0
  164. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-presentation.js +154 -0
  165. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery.js +68 -151
  166. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-capture.js +14 -0
  167. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-observation.js +169 -46
  168. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-commands.js +130 -0
  169. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-electron.js +210 -0
  170. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-observations.js +61 -0
  171. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-outcomes.js +187 -0
  172. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-refs.js +171 -0
  173. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-tabs.js +228 -0
  174. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +77 -753
  175. package/dist/extensions/agent-browser/lib/orchestration/browser-run/text-visibility-diagnostics.js +182 -0
  176. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-diagnostics.js +256 -0
  177. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-progress.js +108 -0
  178. package/dist/extensions/agent-browser/lib/orchestration/code-artifact-observation.js +39 -0
  179. package/dist/extensions/agent-browser/lib/orchestration/code-image-observation.js +119 -0
  180. package/dist/extensions/agent-browser/lib/orchestration/electron-host/branch.js +92 -0
  181. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup-result.js +58 -0
  182. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup.js +78 -0
  183. package/dist/extensions/agent-browser/lib/orchestration/electron-host/contracts.js +1 -0
  184. package/dist/extensions/agent-browser/lib/orchestration/electron-host/discovery.js +106 -0
  185. package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +48 -816
  186. package/dist/extensions/agent-browser/lib/orchestration/electron-host/policy.js +86 -0
  187. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-collection.js +69 -0
  188. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-data.js +167 -0
  189. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js +164 -0
  190. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe.js +161 -0
  191. package/dist/extensions/agent-browser/lib/orchestration/electron-host/status.js +165 -0
  192. package/dist/extensions/agent-browser/lib/orchestration/execution-queue.js +21 -9
  193. package/dist/extensions/agent-browser/lib/orchestration/extension-artifact-preflight.js +211 -0
  194. package/dist/extensions/agent-browser/lib/orchestration/extension-artifacts.js +23 -0
  195. package/dist/extensions/agent-browser/lib/orchestration/extension-attachment-replay.js +99 -0
  196. package/dist/extensions/agent-browser/lib/orchestration/extension-branch-restore.js +275 -0
  197. package/dist/extensions/agent-browser/lib/orchestration/extension-code.js +280 -0
  198. package/dist/extensions/agent-browser/lib/orchestration/extension-command-admission.js +303 -0
  199. package/dist/extensions/agent-browser/lib/orchestration/extension-command-output.js +36 -0
  200. package/dist/extensions/agent-browser/lib/orchestration/extension-command-result.js +335 -0
  201. package/dist/extensions/agent-browser/lib/orchestration/extension-command-run.js +227 -0
  202. package/dist/extensions/agent-browser/lib/orchestration/extension-command-state.js +1 -0
  203. package/dist/extensions/agent-browser/lib/orchestration/extension-electron-ownership.js +204 -0
  204. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-locks.js +139 -0
  205. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-queue.js +24 -0
  206. package/dist/extensions/agent-browser/lib/orchestration/extension-host-coordination.js +98 -0
  207. package/dist/extensions/agent-browser/lib/orchestration/extension-host-run.js +295 -0
  208. package/dist/extensions/agent-browser/lib/orchestration/extension-intent-replay.js +41 -0
  209. package/dist/extensions/agent-browser/lib/orchestration/extension-invocation.js +7 -0
  210. package/dist/extensions/agent-browser/lib/orchestration/extension-lifecycle.js +102 -0
  211. package/dist/extensions/agent-browser/lib/orchestration/extension-managed-ownership.js +133 -0
  212. package/dist/extensions/agent-browser/lib/orchestration/extension-observation.js +120 -0
  213. package/dist/extensions/agent-browser/lib/orchestration/extension-prompt.js +180 -0
  214. package/dist/extensions/agent-browser/lib/orchestration/extension-recording.js +290 -0
  215. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-contracts.js +1 -0
  216. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-replay.js +269 -0
  217. package/dist/extensions/agent-browser/lib/orchestration/extension-result-state.js +113 -0
  218. package/dist/extensions/agent-browser/lib/orchestration/extension-runtime.js +146 -0
  219. package/dist/extensions/agent-browser/lib/orchestration/extension-script-leases.js +58 -0
  220. package/dist/extensions/agent-browser/lib/orchestration/extension-tool-boundary.js +62 -0
  221. package/dist/extensions/agent-browser/lib/orchestration/extension-version-check.js +54 -0
  222. package/dist/extensions/agent-browser/lib/orchestration/input-plan-types.js +1 -0
  223. package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +261 -185
  224. package/dist/extensions/agent-browser/lib/orchestration/input-redaction.js +62 -0
  225. package/dist/extensions/agent-browser/lib/orchestration/native-config.js +144 -0
  226. package/dist/extensions/agent-browser/lib/orchestration/native-root-launch.js +77 -0
  227. package/dist/extensions/agent-browser/lib/orchestration/native-session-defaults.js +210 -139
  228. package/dist/extensions/agent-browser/lib/orchestration/operation-paths.js +124 -58
  229. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +198 -98
  230. package/dist/extensions/agent-browser/lib/orchestration/script-mode.js +199 -96
  231. package/dist/extensions/agent-browser/lib/owned-managed-session-context.js +55 -0
  232. package/dist/extensions/agent-browser/lib/page-target-batch.js +118 -0
  233. package/dist/extensions/agent-browser/lib/page-target-guards.js +50 -0
  234. package/dist/extensions/agent-browser/lib/page-target-navigation.js +104 -0
  235. package/dist/extensions/agent-browser/lib/page-target-validation.js +59 -243
  236. package/dist/extensions/agent-browser/lib/parsing.js +13 -4
  237. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +134 -68
  238. package/dist/extensions/agent-browser/lib/playbook.js +18 -14
  239. package/dist/extensions/agent-browser/lib/process-child.js +284 -0
  240. package/dist/extensions/agent-browser/lib/process-environment.js +22 -6
  241. package/dist/extensions/agent-browser/lib/process-errors.js +23 -0
  242. package/dist/extensions/agent-browser/lib/process-identity.js +47 -15
  243. package/dist/extensions/agent-browser/lib/process-socket-storage.js +256 -0
  244. package/dist/extensions/agent-browser/lib/process-stdout.js +74 -0
  245. package/dist/extensions/agent-browser/lib/process.js +146 -537
  246. package/dist/extensions/agent-browser/lib/prompt-artifacts.js +287 -0
  247. package/dist/extensions/agent-browser/lib/prompt-policy.js +15 -194
  248. package/dist/extensions/agent-browser/lib/read-command.js +41 -0
  249. package/dist/extensions/agent-browser/lib/read-confirmation.js +138 -35
  250. package/dist/extensions/agent-browser/lib/recording-reservations.js +118 -45
  251. package/dist/extensions/agent-browser/lib/redaction-fields.js +75 -0
  252. package/dist/extensions/agent-browser/lib/redaction-json.js +149 -0
  253. package/dist/extensions/agent-browser/lib/redaction-url.js +88 -0
  254. package/dist/extensions/agent-browser/lib/results/action-contracts.js +1 -0
  255. package/dist/extensions/agent-browser/lib/results/action-recommendations.js +28 -271
  256. package/dist/extensions/agent-browser/lib/results/artifact-contracts.js +1 -0
  257. package/dist/extensions/agent-browser/lib/results/artifact-manifest-validation.js +133 -0
  258. package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +96 -94
  259. package/dist/extensions/agent-browser/lib/results/artifact-recommendations.js +73 -0
  260. package/dist/extensions/agent-browser/lib/results/categories.js +111 -54
  261. package/dist/extensions/agent-browser/lib/results/confirmation.js +29 -10
  262. package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +62 -27
  263. package/dist/extensions/agent-browser/lib/results/electron-recommendations.js +83 -0
  264. package/dist/extensions/agent-browser/lib/results/envelope-decoding.js +48 -0
  265. package/dist/extensions/agent-browser/lib/results/envelope.js +93 -66
  266. package/dist/extensions/agent-browser/lib/results/evidence-contracts.js +1 -0
  267. package/dist/extensions/agent-browser/lib/results/failure-recommendations.js +180 -0
  268. package/dist/extensions/agent-browser/lib/results/network-routes.js +86 -45
  269. package/dist/extensions/agent-browser/lib/results/network.js +35 -12
  270. package/dist/extensions/agent-browser/lib/results/next-actions.js +49 -19
  271. package/dist/extensions/agent-browser/lib/results/presentation/artifact-files.js +320 -0
  272. package/dist/extensions/agent-browser/lib/results/presentation/artifact-format.js +138 -0
  273. package/dist/extensions/agent-browser/lib/results/presentation/artifact-images.js +113 -0
  274. package/dist/extensions/agent-browser/lib/results/presentation/artifact-verification.js +145 -0
  275. package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +99 -552
  276. package/dist/extensions/agent-browser/lib/results/presentation/batch-contracts.js +1 -0
  277. package/dist/extensions/agent-browser/lib/results/presentation/batch-recording.js +118 -0
  278. package/dist/extensions/agent-browser/lib/results/presentation/batch-redaction.js +68 -0
  279. package/dist/extensions/agent-browser/lib/results/presentation/batch-rendering.js +135 -0
  280. package/dist/extensions/agent-browser/lib/results/presentation/batch-step.js +227 -0
  281. package/dist/extensions/agent-browser/lib/results/presentation/batch-summary.js +91 -0
  282. package/dist/extensions/agent-browser/lib/results/presentation/batch.js +91 -460
  283. package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +9 -5
  284. package/dist/extensions/agent-browser/lib/results/presentation/command-presenters.js +216 -0
  285. package/dist/extensions/agent-browser/lib/results/presentation/common.js +26 -9
  286. package/dist/extensions/agent-browser/lib/results/presentation/content.js +86 -29
  287. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-a11y.js +67 -0
  288. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-health.js +79 -0
  289. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-identity.js +199 -0
  290. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-logs.js +75 -0
  291. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network-actions.js +216 -0
  292. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network.js +124 -0
  293. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js +64 -0
  294. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js +209 -0
  295. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-stream.js +69 -0
  296. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-summary.js +222 -0
  297. package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +103 -1019
  298. package/dist/extensions/agent-browser/lib/results/presentation/early-result.js +70 -0
  299. package/dist/extensions/agent-browser/lib/results/presentation/errors.js +130 -60
  300. package/dist/extensions/agent-browser/lib/results/presentation/input-contracts.js +1 -0
  301. package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +60 -145
  302. package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +147 -88
  303. package/dist/extensions/agent-browser/lib/results/presentation/notices.js +75 -0
  304. package/dist/extensions/agent-browser/lib/results/presentation/observation-contracts.js +1 -0
  305. package/dist/extensions/agent-browser/lib/results/presentation/observation-rendering.js +127 -0
  306. package/dist/extensions/agent-browser/lib/results/presentation/outcomes.js +120 -0
  307. package/dist/extensions/agent-browser/lib/results/presentation/output-completion.js +77 -0
  308. package/dist/extensions/agent-browser/lib/results/presentation/output-spill.js +51 -0
  309. package/dist/extensions/agent-browser/lib/results/presentation/registry.js +117 -237
  310. package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +35 -21
  311. package/dist/extensions/agent-browser/lib/results/presentation/skills.js +104 -73
  312. package/dist/extensions/agent-browser/lib/results/presentation/source.js +109 -0
  313. package/dist/extensions/agent-browser/lib/results/presentation.js +17 -248
  314. package/dist/extensions/agent-browser/lib/results/recommendation-contracts.js +1 -0
  315. package/dist/extensions/agent-browser/lib/results/recording.js +52 -14
  316. package/dist/extensions/agent-browser/lib/results/recovery-actions.js +14 -5
  317. package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +30 -22
  318. package/dist/extensions/agent-browser/lib/results/selector-recovery-target.js +83 -0
  319. package/dist/extensions/agent-browser/lib/results/selector-recovery.js +123 -123
  320. package/dist/extensions/agent-browser/lib/results/snapshot-compact.js +266 -0
  321. package/dist/extensions/agent-browser/lib/results/snapshot-content.js +32 -0
  322. package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +104 -71
  323. package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +31 -11
  324. package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +125 -66
  325. package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +26 -7
  326. package/dist/extensions/agent-browser/lib/results/snapshot.js +28 -248
  327. package/dist/extensions/agent-browser/lib/results/text.js +16 -5
  328. package/dist/extensions/agent-browser/lib/runtime-args-validation.js +133 -0
  329. package/dist/extensions/agent-browser/lib/runtime-compatibility.js +81 -0
  330. package/dist/extensions/agent-browser/lib/runtime-contracts.js +1 -0
  331. package/dist/extensions/agent-browser/lib/runtime-redaction.js +118 -0
  332. package/dist/extensions/agent-browser/lib/runtime-replay-events.js +144 -0
  333. package/dist/extensions/agent-browser/lib/runtime-session-identity.js +76 -0
  334. package/dist/extensions/agent-browser/lib/runtime-session-plan.js +114 -0
  335. package/dist/extensions/agent-browser/lib/runtime-session-replay.js +123 -0
  336. package/dist/extensions/agent-browser/lib/runtime-tab-correction.js +65 -0
  337. package/dist/extensions/agent-browser/lib/runtime-timeouts.js +28 -0
  338. package/dist/extensions/agent-browser/lib/runtime.js +137 -1037
  339. package/dist/extensions/agent-browser/lib/session-identity.js +51 -0
  340. package/dist/extensions/agent-browser/lib/session-page-observation.js +357 -0
  341. package/dist/extensions/agent-browser/lib/session-page-state.js +188 -324
  342. package/dist/extensions/agent-browser/lib/session-page-types.js +1 -0
  343. package/dist/extensions/agent-browser/lib/temp-artifact-budget.js +78 -0
  344. package/dist/extensions/agent-browser/lib/temp-mutation-queue.js +7 -0
  345. package/dist/extensions/agent-browser/lib/temp-root-ownership.js +234 -0
  346. package/dist/extensions/agent-browser/lib/temp-root.js +207 -0
  347. package/dist/extensions/agent-browser/lib/temp.js +33 -446
  348. package/dist/extensions/agent-browser/lib/tool-surface.js +94 -24
  349. package/dist/extensions/agent-browser/lib/upstream-version.js +3 -2
  350. package/dist/extensions/agent-browser/lib/web-search-providers.js +229 -0
  351. package/dist/extensions/agent-browser/lib/web-search-request.js +108 -0
  352. package/dist/extensions/agent-browser/lib/web-search-results.js +281 -0
  353. package/dist/extensions/agent-browser/lib/web-search-schema.js +82 -0
  354. package/dist/extensions/agent-browser/lib/web-search.js +109 -617
  355. package/dist/extensions/agent-browser/lib/webmcp-observation.js +13 -6
  356. package/dist/extensions/agent-browser/lib/windows-stock-launcher.js +63 -37
  357. package/dist/extensions/agent-browser/script-worker.js +80 -43
  358. package/dist/scripts/agent-browser-target.mjs +4 -2
  359. package/docs/ARCHITECTURE.md +22 -10
  360. package/docs/CODE_QUALITY.md +242 -0
  361. package/docs/COMMAND_REFERENCE.md +264 -229
  362. package/docs/ELECTRON.md +53 -44
  363. package/docs/RELEASE.md +21 -17
  364. package/docs/REQUIREMENTS.md +2 -0
  365. package/docs/SESSION_STORAGE.md +1 -1
  366. package/docs/SUPPORT_MATRIX.md +84 -77
  367. package/docs/TOOL_CONTRACT.md +165 -130
  368. package/docs/platform-smoke.md +5 -5
  369. package/package.json +143 -120
  370. package/scripts/agent-browser-capability-baseline.mjs +361 -957
  371. package/scripts/agent-browser-target.mjs +6 -2
  372. package/scripts/build.mjs +37 -8
  373. package/scripts/capability-core-commands.mjs +193 -0
  374. package/scripts/capability-options.mjs +283 -0
  375. package/scripts/capability-samples.mjs +133 -0
  376. package/scripts/capability-section.mjs +11 -0
  377. package/scripts/config.mjs +213 -114
  378. package/scripts/convert-browser-session.mjs +30 -9
  379. package/scripts/doctor-sources.mjs +195 -0
  380. package/scripts/doctor.mjs +92 -247
  381. package/scripts/platform-smoke/artifacts.mjs +38 -11
  382. package/scripts/platform-smoke/commands.mjs +104 -0
  383. package/scripts/platform-smoke/crabbox-runner.mjs +167 -80
  384. package/scripts/platform-smoke/doctor-support.mjs +157 -0
  385. package/scripts/platform-smoke/doctor-windows.mjs +230 -0
  386. package/scripts/platform-smoke/doctor.mjs +212 -320
  387. package/scripts/platform-smoke/lease-evidence.mjs +134 -0
  388. package/scripts/platform-smoke/suite-checks.mjs +98 -0
  389. package/scripts/platform-smoke/suite-evidence.mjs +281 -0
  390. package/scripts/platform-smoke/targets.mjs +158 -472
  391. package/scripts/platform-smoke.mjs +55 -40
  392. package/scripts/prepare.mjs +16 -7
@@ -1,87 +1,9 @@
1
1
  import { isRecord } from "../parsing.js";
2
- import { summarizeNetworkFailures } from "../results/network.js";
3
- import { truncateText } from "../results/text.js";
4
- import { getBatchResultItems, getCommandNameFromBatchItem } from "./shared.js";
2
+ import { isStringArray } from "./shared.js";
5
3
  import { AGENT_BROWSER_QA_LOAD_STATES, } from "./types.js";
6
- function describeQaChecksRun(checks) {
7
- const parts = [`load:${checks.loadState}`];
8
- if (checks.expectedText.length > 0)
9
- parts.push(`text×${checks.expectedText.length}`);
10
- if (checks.expectedSelector)
11
- parts.push("selector");
12
- if (checks.checkNetwork)
13
- parts.push("network");
14
- if (checks.checkConsole)
15
- parts.push("console");
16
- if (checks.checkErrors)
17
- parts.push("errors");
18
- if (checks.diagnosticsResetAtStart)
19
- parts.push("diagnostics-reset");
20
- else if (checks.checkNetwork || checks.checkConsole || checks.checkErrors)
21
- parts.push("attached-diagnostics-preserved");
22
- if (checks.screenshotPath)
23
- parts.push("screenshot");
24
- return parts.join(", ");
25
- }
26
- export function extractQaPageContext(options) {
27
- if (options.attachedTarget?.title || options.attachedTarget?.url) {
28
- return { title: options.attachedTarget.title, url: options.attachedTarget.url };
29
- }
30
- for (const item of getBatchResultItems(options.batchData)) {
31
- if (getCommandNameFromBatchItem(item) !== "open" || !isRecord(item.result))
32
- continue;
33
- const url = typeof item.result.url === "string" ? item.result.url : undefined;
34
- const title = typeof item.result.title === "string" ? item.result.title : undefined;
35
- if (url || title)
36
- return { title, url };
37
- }
38
- if (options.compiled?.checks.url) {
39
- return { url: options.compiled.checks.url };
40
- }
41
- return {};
42
- }
43
- export function buildQaCompactPassText(options) {
44
- const lines = [options.qaPreset.summary];
45
- const pageParts = [options.page?.title, options.page?.url].filter((part) => typeof part === "string" && part.length > 0);
46
- if (pageParts.length > 0)
47
- lines.push(`Page: ${pageParts.join(" — ")}`);
48
- lines.push(`Checks run: ${describeQaChecksRun(options.checks)} (${options.batchStepCount} batch step${options.batchStepCount === 1 ? "" : "s"})`);
49
- if (options.checks.diagnosticsResetAtStart && (options.checks.checkNetwork || options.checks.checkConsole || options.checks.checkErrors)) {
50
- lines.push("Diagnostic isolation: URL QA requests clears of enabled diagnostic buffers before opening the target.");
51
- }
52
- if (options.checks.attached && !options.checks.diagnosticsResetAtStart && (options.checks.checkNetwork || options.checks.checkConsole || options.checks.checkErrors)) {
53
- lines.push("Attached diagnostics: existing upstream session console/network/error buffers were preserved; rows may include events from before qa.attached started.");
54
- }
55
- if (options.checks.screenshotPath) {
56
- const verification = options.artifactVerification;
57
- lines.push(verification
58
- ? `Screenshot: ${options.checks.screenshotPath} (${verification.verifiedCount}/${verification.artifacts.length} verified on disk)`
59
- : `Screenshot: ${options.checks.screenshotPath}`);
60
- }
61
- lines.push("Full diagnostic matrix: see details.qaPreset and details.batchSteps.");
62
- return lines.join("\n");
63
- }
64
- export function buildQaCompactFailureText(options) {
65
- const lines = [options.causalError
66
- ? truncateText(options.causalError.replace(/\s+/g, " ").trim(), 700)
67
- : options.qaPreset.summary];
68
- const pageParts = [options.page?.title, options.page?.url].filter((part) => typeof part === "string" && part.length > 0);
69
- if (pageParts.length > 0)
70
- lines.push(`Page: ${pageParts.join(" — ")}`);
71
- if (options.qaPreset.failedChecks.length > 0)
72
- lines.push("Failed checks:", ...options.qaPreset.failedChecks.map((failure) => `- ${failure}`));
73
- if (options.qaPreset.notRunChecks.length > 0)
74
- lines.push("Not run:", ...options.qaPreset.notRunChecks.map((check) => `- ${check}`));
75
- if (options.qaPreset.warnings.length > 0)
76
- lines.push("Warnings:", ...options.qaPreset.warnings.map((warning) => `- ${warning}`));
77
- lines.push(`Execution: ${options.executedStepCount ?? "unknown"}/${options.plannedStepCount} batch steps`);
78
- lines.push("Full diagnostic matrix: see details.qaPreset and details.batchSteps.");
79
- return lines.join("\n");
80
- }
4
+ export { analyzeQaPresetResults, analyzeQaPresetTimeout } from "./qa-analysis.js";
5
+ export { extractQaPageContext, buildQaCompactPassText, buildQaCompactFailureText, } from "./qa-presentation.js";
81
6
  const QA_VISIBLE_TEXT_TIMEOUT_MS = 5_000;
82
- function formatQaExpectedTextPreview(text) {
83
- return JSON.stringify(text.length > 80 ? `${text.slice(0, 77)}...` : text);
84
- }
85
7
  function buildQaVisibleTextPredicate(text) {
86
8
  return `(() => {
87
9
  const expected = ${JSON.stringify(text)}.replace(/\\s+/g, " ").trim();
@@ -120,270 +42,151 @@ function buildQaVisibleTextPredicate(text) {
120
42
  return false;
121
43
  })()`;
122
44
  }
123
- function qaVisibleTextWaitPassed(item, step) {
124
- if (step.args[0] !== "wait" || step.args[1] !== "--fn")
125
- return undefined;
126
- if (!item || item.success === false)
127
- return false;
128
- if (typeof item.result === "boolean")
129
- return item.result;
130
- if (isRecord(item.result) && typeof item.result.result === "boolean")
131
- return item.result.result;
132
- return true;
133
- }
134
- function extractQaTextAssertionResultText(item) {
135
- if (!item || item.success === false)
136
- return undefined;
137
- const result = item.result;
138
- if (typeof result === "string")
139
- return result;
140
- if (!isRecord(result))
141
- return undefined;
142
- for (const key of ["result", "text", "value"]) {
143
- const value = result[key];
144
- if (typeof value === "string")
145
- return value;
146
- }
147
- return undefined;
148
- }
149
- function qaErrorSignature(error) {
150
- if (typeof error === "string")
151
- return error;
152
- try {
153
- return JSON.stringify(error);
45
+ function validateQaIdentity(input) {
46
+ if (input.attached !== undefined && typeof input.attached !== "boolean") {
47
+ return "qa.attached must be a boolean when provided.";
154
48
  }
155
- catch {
156
- return String(error);
49
+ if (input.attached === true) {
50
+ return input.url === undefined ? undefined : "qa.url must be omitted when qa.attached is true.";
157
51
  }
52
+ return typeof input.url !== "string" || input.url.trim().length === 0
53
+ ? "qa.url must be a non-empty string."
54
+ : undefined;
158
55
  }
159
- function subtractQaBaselineErrors(errors, baselineErrors) {
160
- const baselineCounts = new Map();
161
- for (const error of baselineErrors) {
162
- const signature = qaErrorSignature(error);
163
- baselineCounts.set(signature, (baselineCounts.get(signature) ?? 0) + 1);
164
- }
165
- let matchedCount = 0;
166
- const novelErrors = errors.filter((error) => {
167
- const signature = qaErrorSignature(error);
168
- const count = baselineCounts.get(signature) ?? 0;
169
- if (count === 0)
170
- return true;
171
- baselineCounts.set(signature, count - 1);
172
- matchedCount += 1;
173
- return false;
174
- });
175
- return { matchedCount, novelErrors };
176
- }
177
- function isDiagnosticResetCommand(item) {
178
- const command = item.command;
179
- if (!Array.isArray(command) || !command.every((token) => typeof token === "string"))
180
- return false;
181
- const [name, subcommand] = command;
182
- return command.includes("--clear") && (name === "console" || name === "errors" || (name === "network" && subcommand === "requests"));
183
- }
184
- export function analyzeQaPresetTimeout(compiled) {
185
- if (compiled.checks.expectedText.length === 0)
186
- return undefined;
187
- const failedChecks = compiled.checks.expectedText.map((text) => `expected text was not verified before timeout: ${formatQaExpectedTextPreview(text)}`);
188
- return {
189
- failedChecks,
190
- notRunChecks: [],
191
- passed: false,
192
- summary: `QA preset failed: ${failedChecks.join("; ")}.`,
193
- warnings: ["The wrapper timed out before expected-text evidence could be verified; inspect timeoutPartialProgress and retry with a narrower readiness condition if the page was still loading."],
194
- };
195
- }
196
- function describeNotRunQaChecks(compiled, executedStepCount) {
197
- const checks = [];
198
- let expectedTextIndex = 0;
199
- for (const [index, step] of compiled.steps.entries()) {
200
- let check;
201
- if (step.action === "assertText") {
202
- const expected = compiled.checks.expectedText[expectedTextIndex++];
203
- if (expected)
204
- check = `expected text: ${formatQaExpectedTextPreview(expected)}`;
205
- }
206
- else if (step.args[0] === "wait" && step.args[1] === "--load") {
207
- check = `load state: ${step.args[2]}`;
208
- }
209
- else if (compiled.checks.expectedSelector && step.args[0] === "wait" && step.args[1] === compiled.checks.expectedSelector) {
210
- check = `expected selector: ${formatQaExpectedTextPreview(compiled.checks.expectedSelector)}`;
211
- }
212
- else if (step.args[0] === "network" && !step.args.includes("--clear")) {
213
- check = "network diagnostics";
214
- }
215
- else if (step.args[0] === "console" && !step.args.includes("--clear")) {
216
- check = "console diagnostics";
56
+ function validateQaOptions(input) {
57
+ for (const field of ["expectedSelector", "screenshotPath"]) {
58
+ const value = input[field];
59
+ if (value !== undefined && (typeof value !== "string" || value.trim().length === 0)) {
60
+ return `qa.${field} must be a non-empty string when provided.`;
217
61
  }
218
- else if (step.args[0] === "errors" && !step.args.includes("--clear") && step.generatedFrom !== "qa.errorBaselineAfterClear") {
219
- check = "page error diagnostics";
220
- }
221
- else if (step.action === "screenshot") {
222
- check = `screenshot: ${formatQaExpectedTextPreview(step.args[1] ?? "")}`;
223
- }
224
- if (index >= executedStepCount && check)
225
- checks.push(check);
226
62
  }
227
- return checks;
228
- }
229
- export function analyzeQaPresetResults(data, compiled) {
230
- const items = getBatchResultItems(data);
231
- if (items.length === 0)
232
- return undefined;
233
- const failedChecks = [];
234
- const warnings = [];
235
- const baselineErrorIndex = compiled?.checks.diagnosticsResetAtStart && compiled.checks.checkErrors
236
- ? compiled.steps.findIndex((step) => step.generatedFrom === "qa.errorBaselineAfterClear")
237
- : -1;
238
- const baselineErrorItem = baselineErrorIndex >= 0 ? items[baselineErrorIndex] : undefined;
239
- const baselineErrorResult = isRecord(baselineErrorItem?.result) ? baselineErrorItem.result : undefined;
240
- const baselineErrors = Array.isArray(baselineErrorResult?.errors) ? baselineErrorResult.errors : [];
241
- for (const [index, item] of items.entries()) {
242
- if (item.success === false) {
243
- failedChecks.push(`${getCommandNameFromBatchItem(item) ?? "step"} failed`);
244
- }
245
- if (index === baselineErrorIndex)
246
- continue;
247
- const result = isRecord(item.result) ? item.result : undefined;
248
- const commandName = getCommandNameFromBatchItem(item);
249
- if (compiled?.checks.diagnosticsResetAtStart && isDiagnosticResetCommand(item)) {
250
- continue;
251
- }
252
- if (commandName === "errors" && Array.isArray(result?.errors) && result.errors.length > 0) {
253
- const { matchedCount, novelErrors } = subtractQaBaselineErrors(result.errors, baselineErrors);
254
- if (novelErrors.length > 0)
255
- failedChecks.push(`${novelErrors.length} page error(s)`);
256
- if (matchedCount > 0)
257
- failedChecks.push(`page-error check could not be verified (${matchedCount} row(s) matched the post-clear baseline; old residue and identical new errors are indistinguishable)`);
258
- }
259
- if (commandName === "console" && Array.isArray(result?.messages)) {
260
- const errorCount = result.messages.filter((message) => isRecord(message) && /error/i.test(String(message.type ?? message.level ?? ""))).length;
261
- if (errorCount > 0)
262
- failedChecks.push(`${errorCount} console error message(s)`);
263
- }
264
- if (commandName === "network" && Array.isArray(result?.requests)) {
265
- const networkFailures = summarizeNetworkFailures(result.requests);
266
- if (networkFailures.actionableCount > 0)
267
- failedChecks.push(`${networkFailures.actionableCount} actionable failed network request(s)`);
268
- if (networkFailures.benignCount > 0)
269
- warnings.push(`${networkFailures.benignCount} benign network request failure(s) ignored`);
63
+ for (const field of ["checkConsole", "checkErrors", "checkNetwork"]) {
64
+ const value = input[field];
65
+ if (value !== undefined && typeof value !== "boolean") {
66
+ return `qa.${field} must be a boolean when provided.`;
270
67
  }
271
68
  }
272
- if (compiled?.checks.expectedText.length) {
273
- let expectedTextIndex = 0;
274
- compiled.steps.forEach((step, index) => {
275
- if (step.action !== "assertText")
276
- return;
277
- const expected = compiled.checks.expectedText[expectedTextIndex++];
278
- if (!expected)
279
- return;
280
- if (!items[index])
281
- return;
282
- const visibleTextPassed = qaVisibleTextWaitPassed(items[index], step);
283
- if (visibleTextPassed === true)
284
- return;
285
- const actual = extractQaTextAssertionResultText(items[index]);
286
- if (!actual || !actual.includes(expected))
287
- failedChecks.push(`expected text not found: ${formatQaExpectedTextPreview(expected)}`);
288
- });
69
+ return undefined;
70
+ }
71
+ function normalizeExpectedText(value) {
72
+ if (value === undefined) {
73
+ return [];
289
74
  }
290
- const stoppedEarly = compiled && items.length < compiled.steps.length;
291
- const failedFast = stoppedEarly && items.at(-1)?.success === false;
292
- if (stoppedEarly && !failedFast)
293
- failedChecks.push("QA execution could not be verified (incomplete batch results)");
294
- const uniqueFailures = [...new Set(failedChecks)];
295
- const uniqueWarnings = [...new Set(warnings)];
296
- const notRunChecks = compiled && failedFast ? describeNotRunQaChecks(compiled, items.length) : [];
297
- return {
298
- failedChecks: uniqueFailures,
299
- notRunChecks,
300
- passed: uniqueFailures.length === 0,
301
- summary: uniqueFailures.length === 0
302
- ? uniqueWarnings.length === 0 ? "QA preset passed." : `QA preset passed with warnings: ${uniqueWarnings.join("; ")}.`
303
- : `QA preset failed: ${uniqueFailures.join("; ")}.`,
304
- warnings: uniqueWarnings,
305
- };
75
+ return typeof value === "string" ? [value] : value;
306
76
  }
307
- export function compileAgentBrowserQaPreset(input) {
77
+ function validateQa(input) {
308
78
  if (!isRecord(input)) {
309
79
  return { error: "qa must be an object." };
310
80
  }
311
- const attached = input.attached === true;
312
- if (input.attached !== undefined && typeof input.attached !== "boolean") {
313
- return { error: "qa.attached must be a boolean when provided." };
314
- }
315
- const url = input.url;
316
- if (attached && url !== undefined) {
317
- return { error: "qa.url must be omitted when qa.attached is true." };
81
+ const identityError = validateQaIdentity(input);
82
+ if (identityError !== undefined) {
83
+ return { error: identityError };
318
84
  }
319
- if (!attached && (typeof url !== "string" || url.trim().length === 0)) {
320
- return { error: "qa.url must be a non-empty string." };
85
+ const expectedText = normalizeExpectedText(input.expectedText);
86
+ if (!isStringArray(expectedText) || expectedText.some((text) => text.trim().length === 0)) {
87
+ return {
88
+ error: "qa.expectedText must be a non-empty string or array of non-empty strings when provided.",
89
+ };
321
90
  }
322
- const normalizedUrl = typeof url === "string" ? url.trim() : undefined;
323
- const expectedText = input.expectedText === undefined
324
- ? []
325
- : typeof input.expectedText === "string"
326
- ? [input.expectedText]
327
- : Array.isArray(input.expectedText)
328
- ? input.expectedText
329
- : undefined;
330
- if (!expectedText || expectedText.some((text) => typeof text !== "string" || text.trim().length === 0)) {
331
- return { error: "qa.expectedText must be a non-empty string or array of non-empty strings when provided." };
91
+ const optionsError = validateQaOptions(input);
92
+ if (optionsError !== undefined) {
93
+ return { error: optionsError };
332
94
  }
333
- const expectedSelector = input.expectedSelector;
334
- if (expectedSelector !== undefined && (typeof expectedSelector !== "string" || expectedSelector.trim().length === 0)) {
335
- return { error: "qa.expectedSelector must be a non-empty string when provided." };
336
- }
337
- const screenshotPath = input.screenshotPath;
338
- if (screenshotPath !== undefined && (typeof screenshotPath !== "string" || screenshotPath.trim().length === 0)) {
339
- return { error: "qa.screenshotPath must be a non-empty string when provided." };
340
- }
341
- for (const field of ["checkConsole", "checkErrors", "checkNetwork"]) {
342
- if (input[field] !== undefined && typeof input[field] !== "boolean") {
343
- return { error: `qa.${field} must be a boolean when provided.` };
344
- }
345
- }
346
- const rawLoadState = input.loadState;
347
- if (rawLoadState !== undefined && (typeof rawLoadState !== "string" || !AGENT_BROWSER_QA_LOAD_STATES.includes(rawLoadState))) {
95
+ const loadState = AGENT_BROWSER_QA_LOAD_STATES.find((value) => value === input.loadState);
96
+ if (input.loadState !== undefined && loadState === undefined) {
348
97
  return { error: `qa.loadState must be one of: ${AGENT_BROWSER_QA_LOAD_STATES.join(", ")}.` };
349
98
  }
350
- const checkConsole = typeof input.checkConsole === "boolean" ? input.checkConsole : !attached;
351
- const checkErrors = typeof input.checkErrors === "boolean" ? input.checkErrors : !attached;
352
- const checkNetwork = typeof input.checkNetwork === "boolean" ? input.checkNetwork : !attached;
353
- const loadState = rawLoadState ?? "domcontentloaded";
354
- const diagnosticsResetAtStart = !attached;
99
+ return { checks: qaChecks(input, expectedText, loadState ?? "domcontentloaded") };
100
+ }
101
+ function qaChecks(input, expectedText, loadState) {
102
+ const attached = input.attached === true;
103
+ return {
104
+ attached,
105
+ checkConsole: typeof input.checkConsole === "boolean" ? input.checkConsole : !attached,
106
+ checkErrors: typeof input.checkErrors === "boolean" ? input.checkErrors : !attached,
107
+ checkNetwork: typeof input.checkNetwork === "boolean" ? input.checkNetwork : !attached,
108
+ diagnosticsResetAtStart: !attached,
109
+ expectedSelector: typeof input.expectedSelector === "string" ? input.expectedSelector : undefined,
110
+ expectedText,
111
+ loadState,
112
+ screenshotPath: typeof input.screenshotPath === "string" ? input.screenshotPath : undefined,
113
+ url: typeof input.url === "string" ? input.url.trim() : undefined,
114
+ };
115
+ }
116
+ function diagnosticResetSteps(checks) {
355
117
  const steps = [];
356
- if (diagnosticsResetAtStart && checkNetwork)
118
+ if (!checks.diagnosticsResetAtStart) {
119
+ return steps;
120
+ }
121
+ if (checks.checkNetwork) {
357
122
  steps.push({ action: "wait", args: ["network", "requests", "--clear"] });
358
- if (diagnosticsResetAtStart && checkConsole)
123
+ }
124
+ if (checks.checkConsole) {
359
125
  steps.push({ action: "wait", args: ["console", "--clear"] });
360
- if (diagnosticsResetAtStart && checkErrors) {
126
+ }
127
+ if (checks.checkErrors) {
361
128
  steps.push({ action: "wait", args: ["errors", "--clear"] });
362
129
  steps.push({ action: "wait", args: ["errors"], generatedFrom: "qa.errorBaselineAfterClear" });
363
130
  }
364
- if (!attached && normalizedUrl)
365
- steps.push({ action: "open", args: ["open", normalizedUrl] });
366
- steps.push({ action: "wait", args: ["wait", "--load", loadState] });
367
- if (checkConsole || checkErrors)
131
+ return steps;
132
+ }
133
+ function readinessSteps(checks) {
134
+ const steps = [];
135
+ if (!checks.attached && checks.url !== undefined && checks.url.length > 0) {
136
+ steps.push({ action: "open", args: ["open", checks.url] });
137
+ }
138
+ steps.push({ action: "wait", args: ["wait", "--load", checks.loadState] });
139
+ if (checks.checkConsole || checks.checkErrors) {
368
140
  steps.push({ action: "wait", args: ["wait", "150"], generatedFrom: "qa.diagnosticSettle" });
369
- for (const text of expectedText) {
370
- steps.push({ action: "assertText", args: ["wait", "--fn", buildQaVisibleTextPredicate(text), "--timeout", String(QA_VISIBLE_TEXT_TIMEOUT_MS)] });
371
141
  }
372
- if (typeof expectedSelector === "string") {
373
- steps.push({ action: "wait", args: ["wait", expectedSelector] });
142
+ for (const text of checks.expectedText) {
143
+ steps.push({
144
+ action: "assertText",
145
+ args: [
146
+ "wait",
147
+ "--fn",
148
+ buildQaVisibleTextPredicate(text),
149
+ "--timeout",
150
+ String(QA_VISIBLE_TEXT_TIMEOUT_MS),
151
+ ],
152
+ });
153
+ }
154
+ if (checks.expectedSelector !== undefined) {
155
+ steps.push({ action: "wait", args: ["wait", checks.expectedSelector] });
374
156
  }
375
- if (checkNetwork)
157
+ return steps;
158
+ }
159
+ function diagnosticReadSteps(checks) {
160
+ const steps = [];
161
+ if (checks.checkNetwork) {
376
162
  steps.push({ action: "wait", args: ["network", "requests"] });
377
- if (checkConsole)
163
+ }
164
+ if (checks.checkConsole) {
378
165
  steps.push({ action: "wait", args: ["console"] });
379
- if (checkErrors)
166
+ }
167
+ if (checks.checkErrors) {
380
168
  steps.push({ action: "wait", args: ["errors"] });
381
- if (typeof screenshotPath === "string")
382
- steps.push({ action: "screenshot", args: ["screenshot", screenshotPath] });
169
+ }
170
+ if (checks.screenshotPath !== undefined) {
171
+ steps.push({ action: "screenshot", args: ["screenshot", checks.screenshotPath] });
172
+ }
173
+ return steps;
174
+ }
175
+ export function compileAgentBrowserQaPreset(input) {
176
+ const validation = validateQa(input);
177
+ if (validation.error !== undefined) {
178
+ return { error: validation.error };
179
+ }
180
+ const checks = validation.checks;
181
+ const steps = [
182
+ ...diagnosticResetSteps(checks),
183
+ ...readinessSteps(checks),
184
+ ...diagnosticReadSteps(checks),
185
+ ];
383
186
  return {
384
187
  compiled: {
385
188
  args: ["batch", "--bail"],
386
- checks: { attached, checkConsole, checkErrors, checkNetwork, diagnosticsResetAtStart, expectedSelector, expectedText, loadState, screenshotPath, url: normalizedUrl },
189
+ checks,
387
190
  failFast: true,
388
191
  stdin: JSON.stringify(steps.map((step) => step.args)),
389
192
  steps,
@@ -0,0 +1,104 @@
1
+ import { isRecord } from "../parsing.js";
2
+ import { getLookupResultPayload, sourceCandidatesFromValue } from "./lookup-source-evidence.js";
3
+ import { getBatchResultItems } from "./shared.js";
4
+ function networkRequestMatchesQuery(url, queryText) {
5
+ return (queryText === undefined ||
6
+ url === undefined ||
7
+ url.includes(queryText) ||
8
+ queryText.includes(url));
9
+ }
10
+ function isFailedNetworkRecord(request) {
11
+ const status = typeof request.status === "number" ? request.status : undefined;
12
+ const error = typeof request.error === "string" ? request.error : undefined;
13
+ return request.failed === true || error !== undefined || (status !== undefined && status >= 400);
14
+ }
15
+ function requestId(request) {
16
+ if (typeof request.id === "string") {
17
+ return request.id;
18
+ }
19
+ return typeof request.requestId === "string" ? request.requestId : undefined;
20
+ }
21
+ function failedRequestValues(payload) {
22
+ if (isRecord(payload) && Array.isArray(payload.requests)) {
23
+ return payload.requests;
24
+ }
25
+ if (Array.isArray(payload)) {
26
+ return payload;
27
+ }
28
+ return isRecord(payload) ? [payload] : [];
29
+ }
30
+ export function getFailedNetworkRequests(data, queryText) {
31
+ const failed = [];
32
+ for (const item of getBatchResultItems(data)) {
33
+ for (const request of failedRequestValues(getLookupResultPayload(item))) {
34
+ if (!isRecord(request)) {
35
+ continue;
36
+ }
37
+ const url = typeof request.url === "string" ? request.url : undefined;
38
+ if (!networkRequestMatchesQuery(url, queryText) || !isFailedNetworkRecord(request)) {
39
+ continue;
40
+ }
41
+ failed.push({
42
+ error: typeof request.error === "string" ? request.error : undefined,
43
+ method: typeof request.method === "string" ? request.method : undefined,
44
+ requestId: requestId(request),
45
+ status: typeof request.status === "number" ? request.status : undefined,
46
+ url,
47
+ });
48
+ }
49
+ }
50
+ return failed;
51
+ }
52
+ export function distinctNetworkCandidates(candidates) {
53
+ const keys = new Set();
54
+ return candidates.filter((candidate) => {
55
+ const key = [
56
+ candidate.source,
57
+ candidate.file ?? "",
58
+ candidate.line ?? "",
59
+ candidate.requestUrl ?? "",
60
+ ].join(":");
61
+ if (keys.has(key)) {
62
+ return false;
63
+ }
64
+ keys.add(key);
65
+ return true;
66
+ });
67
+ }
68
+ function initiatorCandidates(request) {
69
+ const requestUrl = typeof request.url === "string" ? request.url : undefined;
70
+ return [request.initiator, request.stack, request.source, request.trace].flatMap((field) => sourceCandidatesFromValue(field, {
71
+ source: "dom-attribute",
72
+ evidence: ["failed network request included source-like initiator metadata"],
73
+ }).map((candidate) => ({
74
+ confidence: "medium",
75
+ evidence: candidate.evidence,
76
+ file: candidate.file,
77
+ line: candidate.line,
78
+ requestUrl,
79
+ source: "initiator",
80
+ })));
81
+ }
82
+ function correlatesWithFailure(value, failedIds, failedUrls) {
83
+ const id = requestId(value);
84
+ const url = typeof value.url === "string" ? value.url : undefined;
85
+ return (id !== undefined && failedIds.has(id)) || (url !== undefined && failedUrls.has(url));
86
+ }
87
+ export function observeInitiatorCandidates(data, failedRequests) {
88
+ const failedIds = new Set(failedRequests.map((request) => request.requestId).filter((value) => value !== undefined));
89
+ const failedUrls = new Set(failedRequests.map((request) => request.url).filter((value) => value !== undefined));
90
+ const candidates = [];
91
+ for (const item of getBatchResultItems(data)) {
92
+ const payload = getLookupResultPayload(item);
93
+ const values = isRecord(payload) && Array.isArray(payload.requests) ? payload.requests : [payload];
94
+ for (const value of values) {
95
+ if (!isRecord(value)) {
96
+ continue;
97
+ }
98
+ if (correlatesWithFailure(value, failedIds, failedUrls) || isFailedNetworkRecord(value)) {
99
+ candidates.push(...initiatorCandidates(value));
100
+ }
101
+ }
102
+ }
103
+ return distinctNetworkCandidates(candidates);
104
+ }