pi-agent-browser-native 0.9.3 → 0.9.5

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 (394) hide show
  1. package/CHANGELOG.md +106 -5
  2. package/README.md +58 -791
  3. package/dist/extensions/agent-browser/index.js +43101 -2031
  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 +112 -51
  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 -82
  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 +231 -0
  33. package/dist/extensions/agent-browser/lib/config.js +20 -8
  34. package/dist/extensions/agent-browser/lib/electron/cdp.js +20 -8
  35. package/dist/extensions/agent-browser/lib/electron/cleanup.js +128 -83
  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 +90 -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 +261 -355
  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/fs-utils.js +1 -9
  50. package/dist/extensions/agent-browser/lib/input-modes/electron.js +162 -121
  51. package/dist/extensions/agent-browser/lib/input-modes/job.js +123 -317
  52. package/dist/extensions/agent-browser/lib/input-modes/lookup-network-evidence.js +116 -0
  53. package/dist/extensions/agent-browser/lib/input-modes/lookup-plan.js +132 -0
  54. package/dist/extensions/agent-browser/lib/input-modes/lookup-redaction.js +57 -0
  55. package/dist/extensions/agent-browser/lib/input-modes/lookup-source-evidence.js +151 -0
  56. package/dist/extensions/agent-browser/lib/input-modes/lookup-workspace.js +142 -0
  57. package/dist/extensions/agent-browser/lib/input-modes/lookups.js +58 -412
  58. package/dist/extensions/agent-browser/lib/input-modes/params.js +86 -40
  59. package/dist/extensions/agent-browser/lib/input-modes/qa-analysis.js +268 -0
  60. package/dist/extensions/agent-browser/lib/input-modes/qa-presentation.js +117 -0
  61. package/dist/extensions/agent-browser/lib/input-modes/script-child.js +396 -0
  62. package/dist/extensions/agent-browser/lib/input-modes/script-protocol.js +86 -0
  63. package/dist/extensions/agent-browser/lib/input-modes/script-types.js +1 -0
  64. package/dist/extensions/agent-browser/lib/input-modes/script-validation.js +60 -0
  65. package/dist/extensions/agent-browser/lib/input-modes/script.js +60 -409
  66. package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +218 -128
  67. package/dist/extensions/agent-browser/lib/input-modes/shared.js +15 -4
  68. package/dist/extensions/agent-browser/lib/input-modes/types.js +56 -7
  69. package/dist/extensions/agent-browser/lib/json-schema.js +22 -10
  70. package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +17 -5
  71. package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +92 -425
  72. package/dist/extensions/agent-browser/lib/managed-session-posix-storage.js +58 -0
  73. package/dist/extensions/agent-browser/lib/managed-session-project-identity.js +244 -0
  74. package/dist/extensions/agent-browser/lib/managed-session-restore-context.js +84 -0
  75. package/dist/extensions/agent-browser/lib/managed-session-restore-policy.js +119 -0
  76. package/dist/extensions/agent-browser/lib/managed-session-restore-state.js +83 -0
  77. package/dist/extensions/agent-browser/lib/managed-session-restore.js +168 -300
  78. package/dist/extensions/agent-browser/lib/managed-session-snapshot-records.js +277 -0
  79. package/dist/extensions/agent-browser/lib/managed-session-snapshots.js +128 -305
  80. package/dist/extensions/agent-browser/lib/managed-session-storage.js +56 -253
  81. package/dist/extensions/agent-browser/lib/native-confirmation.js +140 -0
  82. package/dist/extensions/agent-browser/lib/native-output.js +43 -9
  83. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +106 -59
  84. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-merge.js +14 -6
  85. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +109 -57
  86. package/dist/extensions/agent-browser/lib/orchestration/browser-run/browser-observation-result.js +82 -0
  87. package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +164 -60
  88. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostic-values.js +31 -0
  89. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +152 -781
  90. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-observation.js +203 -0
  91. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-text-diagnostics.js +109 -0
  92. package/dist/extensions/agent-browser/lib/orchestration/browser-run/fill-diagnostics.js +119 -0
  93. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-action-recovery.js +147 -0
  94. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-actions.js +144 -0
  95. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-content.js +123 -0
  96. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-contracts.js +1 -0
  97. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-details.js +156 -0
  98. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js +187 -0
  99. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-evidence.js +39 -0
  100. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-missing-binary.js +89 -0
  101. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-recovery.js +97 -0
  102. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js +106 -0
  103. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-timeout.js +110 -0
  104. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +41 -538
  105. package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +199 -154
  106. package/dist/extensions/agent-browser/lib/orchestration/browser-run/interaction-diagnostics.js +290 -0
  107. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-close.js +167 -0
  108. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-inspection.js +108 -0
  109. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +127 -205
  110. package/dist/extensions/agent-browser/lib/orchestration/browser-run/native-helper-observation.js +65 -0
  111. package/dist/extensions/agent-browser/lib/orchestration/browser-run/observation-types.js +1 -0
  112. package/dist/extensions/agent-browser/lib/orchestration/browser-run/overlay-diagnostics.js +120 -0
  113. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +113 -30
  114. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +109 -28
  115. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter-data.js +150 -0
  116. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +147 -253
  117. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-rendered-text.js +147 -0
  118. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +59 -24
  119. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-artifacts.js +159 -0
  120. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-command.js +131 -0
  121. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-contracts.js +1 -0
  122. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-daemon.js +93 -0
  123. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-failure.js +42 -0
  124. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-guards.js +242 -0
  125. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-input.js +75 -0
  126. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-observations.js +92 -0
  127. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-selection.js +254 -0
  128. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-state.js +121 -0
  129. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-refs.js +130 -0
  130. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-resources.js +114 -0
  131. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-semantic.js +121 -0
  132. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-session-plan.js +222 -0
  133. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-timeouts.js +68 -0
  134. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +176 -1123
  135. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-analysis.js +191 -0
  136. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-confirmation.js +152 -0
  137. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-diagnostics.js +182 -0
  138. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-electron.js +150 -0
  139. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-contracts.js +1 -0
  140. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase-contracts.js +1 -0
  141. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase.js +115 -0
  142. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle.js +256 -0
  143. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed-contracts.js +1 -0
  144. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed.js +256 -0
  145. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase-contracts.js +1 -0
  146. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase.js +93 -0
  147. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native.js +113 -0
  148. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation-contracts.js +1 -0
  149. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation.js +316 -0
  150. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-ownership.js +28 -0
  151. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase-contracts.js +1 -0
  152. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase.js +142 -0
  153. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation-contracts.js +1 -0
  154. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation.js +333 -0
  155. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase-contracts.js +1 -0
  156. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase.js +71 -0
  157. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication.js +201 -0
  158. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-receipts.js +183 -0
  159. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-refs.js +200 -0
  160. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-tabs.js +142 -0
  161. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +18 -968
  162. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +23 -13
  163. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-receipt-reconciliation.js +198 -0
  164. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-contracts.js +1 -0
  165. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-presentation.js +154 -0
  166. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery.js +68 -151
  167. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-capture.js +14 -0
  168. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-observation.js +169 -46
  169. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-commands.js +130 -0
  170. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-electron.js +212 -0
  171. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-observations.js +61 -0
  172. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-outcomes.js +187 -0
  173. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-refs.js +169 -0
  174. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-tabs.js +228 -0
  175. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +77 -765
  176. package/dist/extensions/agent-browser/lib/orchestration/browser-run/text-visibility-diagnostics.js +182 -0
  177. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-diagnostics.js +256 -0
  178. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-progress.js +108 -0
  179. package/dist/extensions/agent-browser/lib/orchestration/code-artifact-observation.js +39 -0
  180. package/dist/extensions/agent-browser/lib/orchestration/code-image-observation.js +119 -0
  181. package/dist/extensions/agent-browser/lib/orchestration/electron-host/branch.js +93 -0
  182. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup-result.js +58 -0
  183. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup.js +78 -0
  184. package/dist/extensions/agent-browser/lib/orchestration/electron-host/contracts.js +1 -0
  185. package/dist/extensions/agent-browser/lib/orchestration/electron-host/discovery.js +106 -0
  186. package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +48 -821
  187. package/dist/extensions/agent-browser/lib/orchestration/electron-host/policy.js +86 -0
  188. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-collection.js +68 -0
  189. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-data.js +169 -0
  190. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js +182 -0
  191. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe.js +161 -0
  192. package/dist/extensions/agent-browser/lib/orchestration/electron-host/status.js +167 -0
  193. package/dist/extensions/agent-browser/lib/orchestration/execution-queue.js +22 -10
  194. package/dist/extensions/agent-browser/lib/orchestration/extension-artifact-preflight.js +211 -0
  195. package/dist/extensions/agent-browser/lib/orchestration/extension-artifacts.js +23 -0
  196. package/dist/extensions/agent-browser/lib/orchestration/extension-attachment-replay.js +99 -0
  197. package/dist/extensions/agent-browser/lib/orchestration/extension-branch-restore.js +275 -0
  198. package/dist/extensions/agent-browser/lib/orchestration/extension-code.js +280 -0
  199. package/dist/extensions/agent-browser/lib/orchestration/extension-command-admission.js +303 -0
  200. package/dist/extensions/agent-browser/lib/orchestration/extension-command-output.js +36 -0
  201. package/dist/extensions/agent-browser/lib/orchestration/extension-command-result.js +335 -0
  202. package/dist/extensions/agent-browser/lib/orchestration/extension-command-run.js +227 -0
  203. package/dist/extensions/agent-browser/lib/orchestration/extension-command-state.js +1 -0
  204. package/dist/extensions/agent-browser/lib/orchestration/extension-electron-ownership.js +204 -0
  205. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-locks.js +139 -0
  206. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-queue.js +24 -0
  207. package/dist/extensions/agent-browser/lib/orchestration/extension-host-coordination.js +98 -0
  208. package/dist/extensions/agent-browser/lib/orchestration/extension-host-run.js +295 -0
  209. package/dist/extensions/agent-browser/lib/orchestration/extension-intent-replay.js +41 -0
  210. package/dist/extensions/agent-browser/lib/orchestration/extension-invocation.js +7 -0
  211. package/dist/extensions/agent-browser/lib/orchestration/extension-lifecycle.js +102 -0
  212. package/dist/extensions/agent-browser/lib/orchestration/extension-managed-ownership.js +133 -0
  213. package/dist/extensions/agent-browser/lib/orchestration/extension-observation.js +120 -0
  214. package/dist/extensions/agent-browser/lib/orchestration/extension-prompt.js +180 -0
  215. package/dist/extensions/agent-browser/lib/orchestration/extension-recording.js +290 -0
  216. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-contracts.js +1 -0
  217. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-replay.js +269 -0
  218. package/dist/extensions/agent-browser/lib/orchestration/extension-result-state.js +113 -0
  219. package/dist/extensions/agent-browser/lib/orchestration/extension-runtime.js +146 -0
  220. package/dist/extensions/agent-browser/lib/orchestration/extension-script-leases.js +58 -0
  221. package/dist/extensions/agent-browser/lib/orchestration/extension-tool-boundary.js +62 -0
  222. package/dist/extensions/agent-browser/lib/orchestration/extension-version-check.js +54 -0
  223. package/dist/extensions/agent-browser/lib/orchestration/input-plan-types.js +1 -0
  224. package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +261 -185
  225. package/dist/extensions/agent-browser/lib/orchestration/input-redaction.js +62 -0
  226. package/dist/extensions/agent-browser/lib/orchestration/native-config.js +144 -0
  227. package/dist/extensions/agent-browser/lib/orchestration/native-root-launch.js +77 -0
  228. package/dist/extensions/agent-browser/lib/orchestration/native-session-defaults.js +210 -157
  229. package/dist/extensions/agent-browser/lib/orchestration/operation-paths.js +124 -58
  230. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +197 -99
  231. package/dist/extensions/agent-browser/lib/orchestration/script-mode.js +199 -96
  232. package/dist/extensions/agent-browser/lib/owned-managed-session-context.js +55 -0
  233. package/dist/extensions/agent-browser/lib/page-target-batch.js +118 -0
  234. package/dist/extensions/agent-browser/lib/page-target-guards.js +50 -0
  235. package/dist/extensions/agent-browser/lib/page-target-navigation.js +104 -0
  236. package/dist/extensions/agent-browser/lib/page-target-validation.js +55 -246
  237. package/dist/extensions/agent-browser/lib/parsing.js +13 -4
  238. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +133 -68
  239. package/dist/extensions/agent-browser/lib/playbook.js +16 -12
  240. package/dist/extensions/agent-browser/lib/process-child.js +284 -0
  241. package/dist/extensions/agent-browser/lib/process-environment.js +13 -6
  242. package/dist/extensions/agent-browser/lib/process-errors.js +23 -0
  243. package/dist/extensions/agent-browser/lib/process-identity.js +47 -15
  244. package/dist/extensions/agent-browser/lib/process-socket-storage.js +256 -0
  245. package/dist/extensions/agent-browser/lib/process-stdout.js +74 -0
  246. package/dist/extensions/agent-browser/lib/process.js +145 -536
  247. package/dist/extensions/agent-browser/lib/prompt-artifacts.js +287 -0
  248. package/dist/extensions/agent-browser/lib/prompt-policy.js +15 -194
  249. package/dist/extensions/agent-browser/lib/read-command.js +41 -0
  250. package/dist/extensions/agent-browser/lib/read-confirmation.js +131 -68
  251. package/dist/extensions/agent-browser/lib/recording-reservations.js +118 -45
  252. package/dist/extensions/agent-browser/lib/redaction-fields.js +75 -0
  253. package/dist/extensions/agent-browser/lib/redaction-json.js +149 -0
  254. package/dist/extensions/agent-browser/lib/redaction-url.js +88 -0
  255. package/dist/extensions/agent-browser/lib/results/action-contracts.js +1 -0
  256. package/dist/extensions/agent-browser/lib/results/action-recommendations.js +28 -271
  257. package/dist/extensions/agent-browser/lib/results/artifact-contracts.js +1 -0
  258. package/dist/extensions/agent-browser/lib/results/artifact-manifest-validation.js +133 -0
  259. package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +96 -94
  260. package/dist/extensions/agent-browser/lib/results/artifact-recommendations.js +73 -0
  261. package/dist/extensions/agent-browser/lib/results/categories.js +111 -54
  262. package/dist/extensions/agent-browser/lib/results/confirmation.js +29 -13
  263. package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +62 -27
  264. package/dist/extensions/agent-browser/lib/results/electron-recommendations.js +83 -0
  265. package/dist/extensions/agent-browser/lib/results/envelope-decoding.js +48 -0
  266. package/dist/extensions/agent-browser/lib/results/envelope.js +90 -67
  267. package/dist/extensions/agent-browser/lib/results/evidence-contracts.js +1 -0
  268. package/dist/extensions/agent-browser/lib/results/failure-recommendations.js +180 -0
  269. package/dist/extensions/agent-browser/lib/results/network-routes.js +86 -45
  270. package/dist/extensions/agent-browser/lib/results/network.js +35 -12
  271. package/dist/extensions/agent-browser/lib/results/next-actions.js +49 -19
  272. package/dist/extensions/agent-browser/lib/results/presentation/artifact-files.js +320 -0
  273. package/dist/extensions/agent-browser/lib/results/presentation/artifact-format.js +138 -0
  274. package/dist/extensions/agent-browser/lib/results/presentation/artifact-images.js +113 -0
  275. package/dist/extensions/agent-browser/lib/results/presentation/artifact-verification.js +145 -0
  276. package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +99 -555
  277. package/dist/extensions/agent-browser/lib/results/presentation/batch-contracts.js +1 -0
  278. package/dist/extensions/agent-browser/lib/results/presentation/batch-recording.js +118 -0
  279. package/dist/extensions/agent-browser/lib/results/presentation/batch-redaction.js +68 -0
  280. package/dist/extensions/agent-browser/lib/results/presentation/batch-rendering.js +135 -0
  281. package/dist/extensions/agent-browser/lib/results/presentation/batch-step.js +227 -0
  282. package/dist/extensions/agent-browser/lib/results/presentation/batch-summary.js +91 -0
  283. package/dist/extensions/agent-browser/lib/results/presentation/batch.js +91 -460
  284. package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +9 -5
  285. package/dist/extensions/agent-browser/lib/results/presentation/command-presenters.js +216 -0
  286. package/dist/extensions/agent-browser/lib/results/presentation/common.js +26 -9
  287. package/dist/extensions/agent-browser/lib/results/presentation/content.js +86 -29
  288. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-a11y.js +67 -0
  289. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-health.js +79 -0
  290. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-identity.js +199 -0
  291. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-logs.js +75 -0
  292. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network-actions.js +216 -0
  293. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network.js +124 -0
  294. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js +64 -0
  295. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js +209 -0
  296. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-stream.js +69 -0
  297. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-summary.js +222 -0
  298. package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +103 -1052
  299. package/dist/extensions/agent-browser/lib/results/presentation/early-result.js +70 -0
  300. package/dist/extensions/agent-browser/lib/results/presentation/errors.js +130 -60
  301. package/dist/extensions/agent-browser/lib/results/presentation/input-contracts.js +1 -0
  302. package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +60 -145
  303. package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +147 -88
  304. package/dist/extensions/agent-browser/lib/results/presentation/notices.js +75 -0
  305. package/dist/extensions/agent-browser/lib/results/presentation/observation-contracts.js +1 -0
  306. package/dist/extensions/agent-browser/lib/results/presentation/observation-rendering.js +127 -0
  307. package/dist/extensions/agent-browser/lib/results/presentation/outcomes.js +120 -0
  308. package/dist/extensions/agent-browser/lib/results/presentation/output-completion.js +77 -0
  309. package/dist/extensions/agent-browser/lib/results/presentation/output-spill.js +51 -0
  310. package/dist/extensions/agent-browser/lib/results/presentation/registry.js +116 -240
  311. package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +35 -21
  312. package/dist/extensions/agent-browser/lib/results/presentation/skills.js +109 -73
  313. package/dist/extensions/agent-browser/lib/results/presentation/source.js +109 -0
  314. package/dist/extensions/agent-browser/lib/results/presentation.js +17 -261
  315. package/dist/extensions/agent-browser/lib/results/recommendation-contracts.js +1 -0
  316. package/dist/extensions/agent-browser/lib/results/recording.js +52 -14
  317. package/dist/extensions/agent-browser/lib/results/recovery-actions.js +14 -5
  318. package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +30 -22
  319. package/dist/extensions/agent-browser/lib/results/selector-recovery-target.js +83 -0
  320. package/dist/extensions/agent-browser/lib/results/selector-recovery.js +119 -119
  321. package/dist/extensions/agent-browser/lib/results/snapshot-compact.js +266 -0
  322. package/dist/extensions/agent-browser/lib/results/snapshot-content.js +32 -0
  323. package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +104 -71
  324. package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +31 -11
  325. package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +125 -66
  326. package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +26 -7
  327. package/dist/extensions/agent-browser/lib/results/snapshot.js +28 -248
  328. package/dist/extensions/agent-browser/lib/results/text.js +16 -5
  329. package/dist/extensions/agent-browser/lib/runtime-args-validation.js +133 -0
  330. package/dist/extensions/agent-browser/lib/runtime-compatibility.js +81 -0
  331. package/dist/extensions/agent-browser/lib/runtime-contracts.js +1 -0
  332. package/dist/extensions/agent-browser/lib/runtime-redaction.js +118 -0
  333. package/dist/extensions/agent-browser/lib/runtime-replay-events.js +144 -0
  334. package/dist/extensions/agent-browser/lib/runtime-session-identity.js +76 -0
  335. package/dist/extensions/agent-browser/lib/runtime-session-plan.js +114 -0
  336. package/dist/extensions/agent-browser/lib/runtime-session-replay.js +123 -0
  337. package/dist/extensions/agent-browser/lib/runtime-tab-correction.js +65 -0
  338. package/dist/extensions/agent-browser/lib/runtime-timeouts.js +28 -0
  339. package/dist/extensions/agent-browser/lib/runtime.js +137 -1041
  340. package/dist/extensions/agent-browser/lib/session-identity.js +51 -0
  341. package/dist/extensions/agent-browser/lib/session-page-observation.js +357 -0
  342. package/dist/extensions/agent-browser/lib/session-page-state.js +178 -333
  343. package/dist/extensions/agent-browser/lib/session-page-types.js +1 -0
  344. package/dist/extensions/agent-browser/lib/temp-artifact-budget.js +81 -0
  345. package/dist/extensions/agent-browser/lib/temp-mutation-queue.js +7 -0
  346. package/dist/extensions/agent-browser/lib/temp-root-ownership.js +234 -0
  347. package/dist/extensions/agent-browser/lib/temp-root.js +211 -0
  348. package/dist/extensions/agent-browser/lib/temp.js +33 -446
  349. package/dist/extensions/agent-browser/lib/tool-surface.js +94 -24
  350. package/dist/extensions/agent-browser/lib/upstream-version.js +3 -2
  351. package/dist/extensions/agent-browser/lib/web-search-providers.js +193 -0
  352. package/dist/extensions/agent-browser/lib/web-search-request.js +102 -0
  353. package/dist/extensions/agent-browser/lib/web-search-results.js +281 -0
  354. package/dist/extensions/agent-browser/lib/web-search-schema.js +82 -0
  355. package/dist/extensions/agent-browser/lib/web-search.js +124 -614
  356. package/dist/extensions/agent-browser/lib/webmcp-observation.js +13 -6
  357. package/dist/extensions/agent-browser/lib/windows-stock-launcher.js +63 -37
  358. package/dist/extensions/agent-browser/script-worker.js +80 -43
  359. package/dist/scripts/agent-browser-target.mjs +4 -2
  360. package/docs/ARCHITECTURE.md +19 -6
  361. package/docs/CODE_QUALITY.md +267 -0
  362. package/docs/COMMAND_REFERENCE.md +272 -241
  363. package/docs/ELECTRON.md +77 -46
  364. package/docs/REFERENCE.md +869 -0
  365. package/docs/RELEASE.md +25 -22
  366. package/docs/REQUIREMENTS.md +2 -1
  367. package/docs/SUPPORT_MATRIX.md +81 -79
  368. package/docs/TOOL_CONTRACT.md +158 -125
  369. package/docs/platform-smoke.md +8 -8
  370. package/package.json +144 -120
  371. package/scripts/agent-browser-capability-baseline.mjs +361 -957
  372. package/scripts/agent-browser-target.mjs +6 -2
  373. package/scripts/build.mjs +37 -8
  374. package/scripts/capability-core-commands.mjs +193 -0
  375. package/scripts/capability-options.mjs +283 -0
  376. package/scripts/capability-samples.mjs +133 -0
  377. package/scripts/capability-section.mjs +11 -0
  378. package/scripts/config.mjs +235 -132
  379. package/scripts/convert-browser-session.mjs +30 -9
  380. package/scripts/doctor-sources.mjs +195 -0
  381. package/scripts/doctor.mjs +94 -249
  382. package/scripts/platform-smoke/artifacts.mjs +38 -11
  383. package/scripts/platform-smoke/commands.mjs +104 -0
  384. package/scripts/platform-smoke/crabbox-runner.mjs +167 -80
  385. package/scripts/platform-smoke/doctor-support.mjs +157 -0
  386. package/scripts/platform-smoke/doctor-windows.mjs +230 -0
  387. package/scripts/platform-smoke/doctor.mjs +212 -320
  388. package/scripts/platform-smoke/lease-evidence.mjs +132 -0
  389. package/scripts/platform-smoke/linux-image/Dockerfile +8 -2
  390. package/scripts/platform-smoke/suite-checks.mjs +98 -0
  391. package/scripts/platform-smoke/suite-evidence.mjs +281 -0
  392. package/scripts/platform-smoke/targets.mjs +154 -472
  393. package/scripts/platform-smoke.mjs +55 -40
  394. 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();
@@ -97,9 +19,10 @@ function buildQaVisibleTextPredicate(text) {
97
19
  if (style.display === "none" || style.visibility === "hidden" || Number(style.opacity) === 0) return false;
98
20
  return element.getClientRects().length > 0;
99
21
  };
100
- const hasVisibleAncestors = (node) => {
22
+ const ancestorsAllowVisibility = (node) => {
101
23
  for (let element = node.parentElement; element; element = element.parentElement) {
102
- if (!isVisibleElement(element)) return false;
24
+ const style = window.getComputedStyle(element);
25
+ if (style.display === "none" || Number(style.opacity) === 0) return false;
103
26
  if (element === root) break;
104
27
  }
105
28
  return true;
@@ -107,283 +30,166 @@ function buildQaVisibleTextPredicate(text) {
107
30
  const textWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
108
31
  let visitedText = 0;
109
32
  for (let node = textWalker.nextNode(); node && visitedText < 6000; node = textWalker.nextNode(), visitedText += 1) {
110
- if (!hasVisibleAncestors(node)) continue;
33
+ const parent = node.parentElement;
34
+ if (!(parent instanceof HTMLElement) || skipTags.has(parent.tagName)) continue;
35
+ if (window.getComputedStyle(parent).visibility === "hidden" || !ancestorsAllowVisibility(node)) continue;
111
36
  if (normalize(node.nodeValue).includes(expected)) return true;
112
37
  }
113
38
  const elementWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
114
39
  let visitedElements = 0;
115
40
  for (let node = elementWalker.nextNode(); node && visitedElements < 3000; node = elementWalker.nextNode(), visitedElements += 1) {
116
41
  const element = node;
117
- if (!isVisibleElement(element) || !("value" in element)) continue;
42
+ if (!isVisibleElement(element) || !ancestorsAllowVisibility(element) || !("value" in element)) continue;
118
43
  if (normalize(element.value).includes(expected)) return true;
119
44
  }
120
45
  return false;
121
46
  })()`;
122
47
  }
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);
48
+ function validateQaIdentity(input) {
49
+ if (input.attached !== undefined && typeof input.attached !== "boolean") {
50
+ return "qa.attached must be a boolean when provided.";
154
51
  }
155
- catch {
156
- return String(error);
52
+ if (input.attached === true) {
53
+ return input.url === undefined ? undefined : "qa.url must be omitted when qa.attached is true.";
157
54
  }
55
+ return typeof input.url !== "string" || input.url.trim().length === 0
56
+ ? "qa.url must be a non-empty string."
57
+ : undefined;
158
58
  }
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";
59
+ function validateQaOptions(input) {
60
+ for (const field of ["expectedSelector", "screenshotPath"]) {
61
+ const value = input[field];
62
+ if (value !== undefined && (typeof value !== "string" || value.trim().length === 0)) {
63
+ return `qa.${field} must be a non-empty string when provided.`;
217
64
  }
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
65
  }
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`);
66
+ for (const field of ["checkConsole", "checkErrors", "checkNetwork"]) {
67
+ const value = input[field];
68
+ if (value !== undefined && typeof value !== "boolean") {
69
+ return `qa.${field} must be a boolean when provided.`;
270
70
  }
271
71
  }
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
- });
72
+ return undefined;
73
+ }
74
+ function normalizeExpectedText(value) {
75
+ if (value === undefined) {
76
+ return [];
289
77
  }
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
- };
78
+ return typeof value === "string" ? [value] : value;
306
79
  }
307
- export function compileAgentBrowserQaPreset(input) {
80
+ function validateQa(input) {
308
81
  if (!isRecord(input)) {
309
82
  return { error: "qa must be an object." };
310
83
  }
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." };
84
+ const identityError = validateQaIdentity(input);
85
+ if (identityError !== undefined) {
86
+ return { error: identityError };
318
87
  }
319
- if (!attached && (typeof url !== "string" || url.trim().length === 0)) {
320
- return { error: "qa.url must be a non-empty string." };
88
+ const expectedText = normalizeExpectedText(input.expectedText);
89
+ if (!isStringArray(expectedText) || expectedText.some((text) => text.trim().length === 0)) {
90
+ return {
91
+ error: "qa.expectedText must be a non-empty string or array of non-empty strings when provided.",
92
+ };
321
93
  }
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." };
94
+ const optionsError = validateQaOptions(input);
95
+ if (optionsError !== undefined) {
96
+ return { error: optionsError };
332
97
  }
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))) {
98
+ const loadState = AGENT_BROWSER_QA_LOAD_STATES.find((value) => value === input.loadState);
99
+ if (input.loadState !== undefined && loadState === undefined) {
348
100
  return { error: `qa.loadState must be one of: ${AGENT_BROWSER_QA_LOAD_STATES.join(", ")}.` };
349
101
  }
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;
102
+ return { checks: qaChecks(input, expectedText, loadState ?? "domcontentloaded") };
103
+ }
104
+ function qaChecks(input, expectedText, loadState) {
105
+ const attached = input.attached === true;
106
+ return {
107
+ attached,
108
+ checkConsole: typeof input.checkConsole === "boolean" ? input.checkConsole : !attached,
109
+ checkErrors: typeof input.checkErrors === "boolean" ? input.checkErrors : !attached,
110
+ checkNetwork: typeof input.checkNetwork === "boolean" ? input.checkNetwork : !attached,
111
+ diagnosticsResetAtStart: !attached,
112
+ expectedSelector: typeof input.expectedSelector === "string" ? input.expectedSelector : undefined,
113
+ expectedText,
114
+ loadState,
115
+ screenshotPath: typeof input.screenshotPath === "string" ? input.screenshotPath : undefined,
116
+ url: typeof input.url === "string" ? input.url.trim() : undefined,
117
+ };
118
+ }
119
+ function diagnosticResetSteps(checks) {
355
120
  const steps = [];
356
- if (diagnosticsResetAtStart && checkNetwork)
121
+ if (!checks.diagnosticsResetAtStart) {
122
+ return steps;
123
+ }
124
+ if (checks.checkNetwork) {
357
125
  steps.push({ action: "wait", args: ["network", "requests", "--clear"] });
358
- if (diagnosticsResetAtStart && checkConsole)
126
+ }
127
+ if (checks.checkConsole) {
359
128
  steps.push({ action: "wait", args: ["console", "--clear"] });
360
- if (diagnosticsResetAtStart && checkErrors) {
129
+ }
130
+ if (checks.checkErrors) {
361
131
  steps.push({ action: "wait", args: ["errors", "--clear"] });
362
132
  steps.push({ action: "wait", args: ["errors"], generatedFrom: "qa.errorBaselineAfterClear" });
363
133
  }
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)
134
+ return steps;
135
+ }
136
+ function readinessSteps(checks) {
137
+ const steps = [];
138
+ if (!checks.attached && checks.url !== undefined && checks.url.length > 0) {
139
+ steps.push({ action: "open", args: ["open", checks.url] });
140
+ }
141
+ steps.push({ action: "wait", args: ["wait", "--load", checks.loadState] });
142
+ if (checks.checkConsole || checks.checkErrors) {
368
143
  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
144
  }
372
- if (typeof expectedSelector === "string") {
373
- steps.push({ action: "wait", args: ["wait", expectedSelector] });
145
+ for (const text of checks.expectedText) {
146
+ steps.push({
147
+ action: "assertText",
148
+ args: [
149
+ "wait",
150
+ "--fn",
151
+ buildQaVisibleTextPredicate(text),
152
+ "--timeout",
153
+ String(QA_VISIBLE_TEXT_TIMEOUT_MS),
154
+ ],
155
+ });
156
+ }
157
+ if (checks.expectedSelector !== undefined) {
158
+ steps.push({ action: "wait", args: ["wait", checks.expectedSelector] });
374
159
  }
375
- if (checkNetwork)
160
+ return steps;
161
+ }
162
+ function diagnosticReadSteps(checks) {
163
+ const steps = [];
164
+ if (checks.checkNetwork) {
376
165
  steps.push({ action: "wait", args: ["network", "requests"] });
377
- if (checkConsole)
166
+ }
167
+ if (checks.checkConsole) {
378
168
  steps.push({ action: "wait", args: ["console"] });
379
- if (checkErrors)
169
+ }
170
+ if (checks.checkErrors) {
380
171
  steps.push({ action: "wait", args: ["errors"] });
381
- if (typeof screenshotPath === "string")
382
- steps.push({ action: "screenshot", args: ["screenshot", screenshotPath] });
172
+ }
173
+ if (checks.screenshotPath !== undefined) {
174
+ steps.push({ action: "screenshot", args: ["screenshot", checks.screenshotPath] });
175
+ }
176
+ return steps;
177
+ }
178
+ export function compileAgentBrowserQaPreset(input) {
179
+ const validation = validateQa(input);
180
+ if (validation.error !== undefined) {
181
+ return { error: validation.error };
182
+ }
183
+ const checks = validation.checks;
184
+ const steps = [
185
+ ...diagnosticResetSteps(checks),
186
+ ...readinessSteps(checks),
187
+ ...diagnosticReadSteps(checks),
188
+ ];
383
189
  return {
384
190
  compiled: {
385
191
  args: ["batch", "--bail"],
386
- checks: { attached, checkConsole, checkErrors, checkNetwork, diagnosticsResetAtStart, expectedSelector, expectedText, loadState, screenshotPath, url: normalizedUrl },
192
+ checks,
387
193
  failFast: true,
388
194
  stdin: JSON.stringify(steps.map((step) => step.args)),
389
195
  steps,
@@ -0,0 +1,116 @@
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
+ const seenRequestIds = new Set();
51
+ return failed.filter(({ requestId: id }) => {
52
+ if (id === undefined) {
53
+ return true;
54
+ }
55
+ if (seenRequestIds.has(id)) {
56
+ return false;
57
+ }
58
+ seenRequestIds.add(id);
59
+ return true;
60
+ });
61
+ }
62
+ export function distinctNetworkCandidates(candidates) {
63
+ const keys = new Set();
64
+ return candidates.filter((candidate) => {
65
+ const key = [
66
+ candidate.source,
67
+ candidate.file ?? "",
68
+ candidate.line ?? "",
69
+ candidate.requestUrl ?? "",
70
+ ].join(":");
71
+ if (keys.has(key)) {
72
+ return false;
73
+ }
74
+ keys.add(key);
75
+ return true;
76
+ });
77
+ }
78
+ function initiatorCandidates(request) {
79
+ const requestUrl = typeof request.url === "string" ? request.url : undefined;
80
+ return [request.initiator, request.stack, request.source, request.trace].flatMap((field) => sourceCandidatesFromValue(field, {
81
+ source: "dom-attribute",
82
+ evidence: ["failed network request included source-like initiator metadata"],
83
+ }).map((candidate) => ({
84
+ confidence: "medium",
85
+ evidence: candidate.evidence,
86
+ file: candidate.file,
87
+ line: candidate.line,
88
+ requestUrl,
89
+ source: "initiator",
90
+ })));
91
+ }
92
+ function correlatesWithFailure(value, failedIds, failedUrls) {
93
+ const id = requestId(value);
94
+ const url = typeof value.url === "string" ? value.url : undefined;
95
+ return (id !== undefined && failedIds.has(id)) || (url !== undefined && failedUrls.has(url));
96
+ }
97
+ export function observeInitiatorCandidates(data, failedRequests, queryText) {
98
+ const failedIds = new Set(failedRequests.map((request) => request.requestId).filter((value) => value !== undefined));
99
+ const failedUrls = new Set(failedRequests.map((request) => request.url).filter((value) => value !== undefined));
100
+ const candidates = [];
101
+ for (const item of getBatchResultItems(data)) {
102
+ const payload = getLookupResultPayload(item);
103
+ const values = isRecord(payload) && Array.isArray(payload.requests) ? payload.requests : [payload];
104
+ for (const value of values) {
105
+ if (!isRecord(value)) {
106
+ continue;
107
+ }
108
+ const url = typeof value.url === "string" ? value.url : undefined;
109
+ if (networkRequestMatchesQuery(url, queryText) &&
110
+ (correlatesWithFailure(value, failedIds, failedUrls) || isFailedNetworkRecord(value))) {
111
+ candidates.push(...initiatorCandidates(value));
112
+ }
113
+ }
114
+ }
115
+ return distinctNetworkCandidates(candidates);
116
+ }