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,70 +1,110 @@
1
1
  import { projectUpstreamGlobalFlags } from "../argv-grammar.js";
2
+ import { isStringArray } from "../input-modes/shared.js";
3
+ import { stringifyUnknown } from "../results/text.js";
2
4
  /** Bare open's native launch action drops prior launch options. URL reads lazily launch without navigating. */
3
5
  export function normalizeUrlLessOpen(args, stdin, batchStep = false) {
4
- const { tokens, indices } = batchStep ? { tokens: args, indices: args.map((_, index) => index) } : projectUpstreamGlobalFlags(args);
5
- if (tokens[0] === "open" && !tokens.slice(1).some(token => !token.startsWith("--"))) {
6
+ const { tokens, indices } = batchStep
7
+ ? { tokens: args, indices: args.map((_, index) => index) }
8
+ : projectUpstreamGlobalFlags(args);
9
+ if (tokens[0] === "open" && !tokens.slice(1).some((token) => !token.startsWith("--"))) {
6
10
  const index = indices[0];
7
11
  return { args: [...args.slice(0, index), "get", "url", ...args.slice(index + 1)], stdin };
8
12
  }
9
- if (tokens[0] !== "batch")
13
+ if (tokens[0] !== "batch") {
10
14
  return { args, stdin };
11
- const rawSteps = tokens.slice(1).flatMap((token, offset) => {
12
- const step = token === "--bail" ? undefined : parseBatchCommandArgument(token).step;
13
- return step ? [{ index: indices[offset + 1], step }] : [];
14
- });
15
- if (tokens.slice(1).some(token => token !== "--bail")) {
16
- let normalized = args;
17
- for (const { index, step } of rawSteps) {
18
- const row = normalizeUrlLessOpen(step, undefined, true).args;
19
- if (row === step)
20
- continue;
21
- if (normalized === args)
22
- normalized = [...args];
23
- normalized[index] = row.map(token => `'${token.replaceAll("'", "'\\''")}'`).join(" ");
24
- }
25
- return { args: normalized, stdin };
15
+ }
16
+ if (tokens.slice(1).some((token) => token !== "--bail")) {
17
+ return { args: normalizeRawBatchRows(args, tokens, indices), stdin };
26
18
  }
27
19
  const steps = parseUserBatchStdin(stdin).steps;
28
- if (!steps?.length)
20
+ if (steps === undefined || steps.length === 0) {
29
21
  return { args, stdin };
30
- const normalized = steps.map(step => normalizeUrlLessOpen(step, undefined, true).args);
31
- return { args, stdin: normalized.some((step, index) => step !== steps[index]) ? JSON.stringify(normalized) : stdin };
22
+ }
23
+ const normalized = steps.map((step) => normalizeUrlLessOpen(step, undefined, true).args);
24
+ return {
25
+ args,
26
+ stdin: normalized.some((step, index) => step !== steps[index])
27
+ ? JSON.stringify(normalized)
28
+ : stdin,
29
+ };
30
+ }
31
+ function normalizeRawBatchRows(args, tokens, indices) {
32
+ let normalized;
33
+ for (const [offset, token] of tokens.slice(1).entries()) {
34
+ if (token === "--bail") {
35
+ continue;
36
+ }
37
+ const step = parseBatchCommandArgument(token).step;
38
+ if (step === undefined) {
39
+ continue;
40
+ }
41
+ const row = normalizeUrlLessOpen(step, undefined, true).args;
42
+ if (row === step) {
43
+ continue;
44
+ }
45
+ normalized ??= [...args];
46
+ normalized[indices[offset + 1]] = row
47
+ .map((word) => `'${word.replaceAll("'", "'\\''")}'`)
48
+ .join(" ");
49
+ }
50
+ return normalized ?? args;
32
51
  }
33
52
  const BATCH_STDIN_EXAMPLE = ' Example: { "args": ["batch"], "stdin": "[[\\"get\\",\\"title\\"],[\\"get\\",\\"url\\"]]" }';
34
- // Mirror upstream commands::shell_words_split so policy inspection sees the same argv.
35
- export function parseBatchCommandArgument(command) {
36
- const tokens = [];
37
- let token = "";
38
- let inDoubleQuote = false;
39
- let inSingleQuote = false;
40
- for (let index = 0; index < command.length; index += 1) {
41
- const character = command[index];
42
- if (character === "\\" && !inSingleQuote) {
43
- const next = command[index + 1];
44
- if (next !== undefined) {
45
- token += next;
46
- index += 1;
47
- }
53
+ // Mirrors upstream commands::shell_words_split for policy inspection.
54
+ class BatchWords {
55
+ token = "";
56
+ tokens = [];
57
+ inDoubleQuote = false;
58
+ inSingleQuote = false;
59
+ consumeQuote(character) {
60
+ if (character === '"' && !this.inSingleQuote) {
61
+ this.inDoubleQuote = !this.inDoubleQuote;
62
+ return true;
48
63
  }
49
- else if (character === '"' && !inSingleQuote) {
50
- inDoubleQuote = !inDoubleQuote;
64
+ if (character === "'" && !this.inDoubleQuote) {
65
+ this.inSingleQuote = !this.inSingleQuote;
66
+ return true;
51
67
  }
52
- else if (character === "'" && !inDoubleQuote) {
53
- inSingleQuote = !inSingleQuote;
68
+ return false;
69
+ }
70
+ finishWord() {
71
+ if (this.token.length > 0) {
72
+ this.tokens.push(this.token);
73
+ this.token = "";
54
74
  }
55
- else if (character === " " && !inDoubleQuote && !inSingleQuote) {
56
- if (token !== "") {
57
- tokens.push(token);
58
- token = "";
75
+ }
76
+ consume(character, next) {
77
+ if (character === "\\" && !this.inSingleQuote) {
78
+ if (next !== undefined) {
79
+ this.token += next;
80
+ return true;
59
81
  }
82
+ return false;
83
+ }
84
+ if (this.consumeQuote(character)) {
85
+ return false;
86
+ }
87
+ if (character === " " && !this.inDoubleQuote && !this.inSingleQuote) {
88
+ this.finishWord();
60
89
  }
61
90
  else {
62
- token += character;
91
+ this.token += character;
63
92
  }
93
+ return false;
94
+ }
95
+ finish() {
96
+ this.finishWord();
97
+ return this.tokens.length > 0 ? { step: this.tokens } : { error: "batch command is empty" };
64
98
  }
65
- if (token !== "")
66
- tokens.push(token);
67
- return tokens.length > 0 ? { step: tokens } : { error: "batch command is empty" };
99
+ }
100
+ export function parseBatchCommandArgument(command) {
101
+ const words = new BatchWords();
102
+ for (let index = 0; index < command.length; index++) {
103
+ if (words.consume(command[index], command.at(index + 1))) {
104
+ index++;
105
+ }
106
+ }
107
+ return words.finish();
68
108
  }
69
109
  function validateUserBatchStep(step, index) {
70
110
  if (!Array.isArray(step)) {
@@ -73,14 +113,14 @@ function validateUserBatchStep(step, index) {
73
113
  ok: false,
74
114
  };
75
115
  }
76
- const invalidTokenIndex = step.findIndex((token) => typeof token !== "string");
77
- if (invalidTokenIndex !== -1) {
116
+ if (!isStringArray(step)) {
117
+ const invalidTokenIndex = step.findIndex((token) => typeof token !== "string");
78
118
  return {
79
119
  error: `agent_browser batch stdin step ${index} token ${invalidTokenIndex} must be a string.${BATCH_STDIN_EXAMPLE}`,
80
120
  ok: false,
81
121
  };
82
122
  }
83
- return { ok: true, step: step };
123
+ return { ok: true, step };
84
124
  }
85
125
  export function parseBatchStdinJsonArray(stdin) {
86
126
  if (stdin === undefined) {
@@ -89,19 +129,23 @@ export function parseBatchStdinJsonArray(stdin) {
89
129
  try {
90
130
  const parsed = JSON.parse(stdin);
91
131
  if (!Array.isArray(parsed)) {
92
- return { error: `agent_browser batch stdin must be a JSON array of command steps.${BATCH_STDIN_EXAMPLE}` };
132
+ return {
133
+ error: `agent_browser batch stdin must be a JSON array of command steps.${BATCH_STDIN_EXAMPLE}`,
134
+ };
93
135
  }
94
136
  return { steps: parsed };
95
137
  }
96
138
  catch (error) {
97
- const message = error instanceof Error ? error.message : String(error);
98
- return { error: `agent_browser batch stdin could not be parsed as JSON: ${message}.${BATCH_STDIN_EXAMPLE}` };
139
+ const message = error instanceof Error ? error.message : stringifyUnknown(error);
140
+ return {
141
+ error: `agent_browser batch stdin could not be parsed as JSON: ${message}.${BATCH_STDIN_EXAMPLE}`,
142
+ };
99
143
  }
100
144
  }
101
145
  export function parseUserBatchStdin(stdin) {
102
146
  const parsed = parseBatchStdinJsonArray(stdin);
103
- if (parsed.error || parsed.steps === undefined) {
104
- return parsed.error ? { error: parsed.error } : { steps: [] };
147
+ if (parsed.error !== undefined || parsed.steps === undefined) {
148
+ return parsed.error !== undefined ? { error: parsed.error } : { steps: [] };
105
149
  }
106
150
  const steps = [];
107
151
  for (const [index, rawStep] of parsed.steps.entries()) {
@@ -121,15 +165,18 @@ export function parseUserBatchStdin(stdin) {
121
165
  * ignored.
122
166
  */
123
167
  export function getUpstreamEffectiveBatchSteps(commandTokens, stdin) {
124
- if (commandTokens[0] !== "batch")
168
+ if (commandTokens[0] !== "batch") {
125
169
  return [];
170
+ }
126
171
  const argumentSteps = commandTokens.slice(1).flatMap((command) => {
127
- if (command === "--bail")
172
+ if (command === "--bail") {
128
173
  return [];
174
+ }
129
175
  const step = parseBatchCommandArgument(command).step;
130
176
  return step ? [step] : [];
131
177
  });
132
- if (argumentSteps.length > 0)
178
+ if (commandTokens.slice(1).some((token) => token !== "--bail")) {
133
179
  return argumentSteps;
134
- return parseUserBatchStdin(stdin).steps?.filter(step => step.length > 0) ?? [];
180
+ }
181
+ return parseUserBatchStdin(stdin).steps?.filter((step) => step.length > 0) ?? [];
135
182
  }
@@ -1,16 +1,24 @@
1
- import { getSessionArtifactManifestEntryKey, isPendingRecordingCommand, mergeSessionArtifactManifest } from "../../results/artifact-manifest.js";
1
+ import { getSessionArtifactManifestEntryKey, isPendingRecordingCommand, mergeSessionArtifactManifest, } from "../../results/artifact-manifest.js";
2
2
  export function mergeBrowserRunArtifactManifest(current, initial, updated) {
3
- if (!updated || updated === initial)
3
+ if (!updated || updated === initial) {
4
4
  return current;
5
- if (current === initial)
5
+ }
6
+ if (current === initial) {
6
7
  return updated;
8
+ }
7
9
  const initialEntries = new Map((initial?.entries ?? []).map((entry) => [getSessionArtifactManifestEntryKey(entry), entry]));
8
10
  const changedEntries = updated.entries
9
11
  .map((entry, index) => ({ entry, index }))
10
12
  .filter(({ entry }) => initialEntries.get(getSessionArtifactManifestEntryKey(entry)) !== entry)
11
- .sort((left, right) => left.entry.createdAtMs - right.entry.createdAtMs
12
- || Number(isPendingRecordingCommand(left.entry.command, left.entry.subcommand, left.entry.kind)) - Number(isPendingRecordingCommand(right.entry.command, right.entry.subcommand, right.entry.kind))
13
- || left.index - right.index)
13
+ .sort((left, right) => {
14
+ const timestampOrder = left.entry.createdAtMs - right.entry.createdAtMs;
15
+ if (timestampOrder !== 0 && !Number.isNaN(timestampOrder)) {
16
+ return timestampOrder;
17
+ }
18
+ const pendingOrder = Number(isPendingRecordingCommand(left.entry.command, left.entry.subcommand, left.entry.kind)) -
19
+ Number(isPendingRecordingCommand(right.entry.command, right.entry.subcommand, right.entry.kind));
20
+ return pendingOrder !== 0 ? pendingOrder : left.index - right.index;
21
+ })
14
22
  .map(({ entry }) => entry);
15
23
  return changedEntries.length === 0
16
24
  ? current
@@ -2,22 +2,29 @@ import { lstatSync, readlinkSync, realpathSync, statSync } from "node:fs";
2
2
  import { basename, dirname, extname, join, resolve } from "node:path";
3
3
  import { foldAgentBrowserFilesystemIdentity } from "../../argv-grammar.js";
4
4
  import { parseWaitCommandTokens } from "../../argv-descriptor.js";
5
- import { getRecordCommandOperandIndices, getRecordCommandOperands } from "../../command-taxonomy.js";
5
+ import { getRecordCommandOperandIndices, getRecordCommandOperands, } from "../../command-taxonomy.js";
6
6
  const SCREENSHOT_IMAGE_EXTENSIONS = [".jpeg", ".jpg", ".png", ".webp"];
7
7
  function isSingleScreenshotPathToken(token) {
8
8
  const explicitlyRelative = token.startsWith("./") || token.startsWith("../");
9
- if (token.startsWith("#") || token.startsWith("@") || (token.startsWith(".") && !explicitlyRelative && !token.includes("/")))
9
+ if (token.startsWith("#") ||
10
+ token.startsWith("@") ||
11
+ (token.startsWith(".") && !explicitlyRelative && !token.includes("/"))) {
10
12
  return false;
11
- return explicitlyRelative || token.includes("/") || SCREENSHOT_IMAGE_EXTENSIONS.some((extension) => token.endsWith(extension));
13
+ }
14
+ return (explicitlyRelative ||
15
+ token.includes("/") ||
16
+ SCREENSHOT_IMAGE_EXTENSIONS.some((extension) => token.endsWith(extension)));
12
17
  }
13
18
  export function getScreenshotPositionalIndices(commandTokens) {
14
- if (commandTokens[0] !== "screenshot")
19
+ if (commandTokens[0] !== "screenshot") {
15
20
  return [];
21
+ }
16
22
  const positionalIndices = [];
17
23
  for (let index = 1; index < commandTokens.length; index += 1) {
18
24
  const token = commandTokens[index];
19
- if (token === "--full" || token === "-f" || token === "--if-changed")
25
+ if (token === "--full" || token === "-f" || token === "--if-changed") {
20
26
  continue;
27
+ }
21
28
  if (token === "--threshold") {
22
29
  index += 1;
23
30
  continue;
@@ -28,8 +35,9 @@ export function getScreenshotPositionalIndices(commandTokens) {
28
35
  }
29
36
  export function getScreenshotPathTokenIndex(commandTokens) {
30
37
  const positionalIndices = getScreenshotPositionalIndices(commandTokens);
31
- if (positionalIndices.length === 0)
38
+ if (positionalIndices.length === 0) {
32
39
  return undefined;
40
+ }
33
41
  const candidateIndex = positionalIndices.length >= 2 ? positionalIndices[1] : positionalIndices[0];
34
42
  const candidate = commandTokens[candidateIndex];
35
43
  if (positionalIndices.length >= 2 || isSingleScreenshotPathToken(candidate)) {
@@ -37,64 +45,93 @@ export function getScreenshotPathTokenIndex(commandTokens) {
37
45
  }
38
46
  return undefined;
39
47
  }
40
- const DIFF_SCREENSHOT_VALUE_FLAGS = new Set(["-b", "--baseline", "-o", "--output", "-s", "--selector", "-t", "--threshold"]);
48
+ const DIFF_SCREENSHOT_VALUE_FLAGS = new Set([
49
+ "-b",
50
+ "--baseline",
51
+ "-o",
52
+ "--output",
53
+ "-s",
54
+ "--selector",
55
+ "-t",
56
+ "--threshold",
57
+ ]);
41
58
  export function getDiffFilePathIndices(commandTokens) {
42
- if (commandTokens[0] !== "diff" || !["snapshot", "screenshot"].includes(commandTokens[1]))
59
+ if (commandTokens[0] !== "diff" || !["snapshot", "screenshot"].includes(commandTokens[1])) {
43
60
  return {};
44
- const valueFlags = commandTokens[1] === "screenshot" ? DIFF_SCREENSHOT_VALUE_FLAGS : new Set(["-b", "--baseline", "-s", "--selector", "-d", "--depth"]);
61
+ }
62
+ const valueFlags = commandTokens[1] === "screenshot"
63
+ ? DIFF_SCREENSHOT_VALUE_FLAGS
64
+ : new Set(["-b", "--baseline", "-s", "--selector", "-d", "--depth"]);
45
65
  const paths = {};
46
66
  for (let index = 2; index < commandTokens.length; index += 1) {
47
67
  const token = commandTokens[index];
48
- if (!valueFlags.has(token))
68
+ if (!valueFlags.has(token)) {
49
69
  continue;
50
- const value = commandTokens[index + 1];
51
- if (value === undefined)
70
+ }
71
+ const value = commandTokens.at(index + 1);
72
+ if (value === undefined) {
52
73
  return {};
53
- if (token === "-o" || token === "--output")
74
+ }
75
+ if (["-o", "--output"].includes(token)) {
54
76
  paths.output = index + 1;
55
- if (token === "-b" || token === "--baseline")
77
+ }
78
+ if (["-b", "--baseline"].includes(token)) {
56
79
  paths.baseline = index + 1;
80
+ }
57
81
  index += 1;
58
82
  }
59
83
  return paths;
60
84
  }
85
+ function canonicalFileIdentity(path, platform) {
86
+ try {
87
+ const stats = statSync(path, { bigint: true });
88
+ if (stats.ino > 0n) {
89
+ return `inode:${stats.dev}:${stats.ino}`;
90
+ }
91
+ }
92
+ catch {
93
+ // The destination does not exist yet; canonical ancestry still catches aliases.
94
+ }
95
+ return foldAgentBrowserFilesystemIdentity(path, platform);
96
+ }
97
+ function readSymlinkTarget(path) {
98
+ try {
99
+ return lstatSync(path).isSymbolicLink()
100
+ ? resolve(dirname(path), readlinkSync(path))
101
+ : undefined;
102
+ }
103
+ catch {
104
+ // Missing ancestry is resolved by walking to the next existing parent.
105
+ return undefined;
106
+ }
107
+ }
61
108
  function canonicalizeArtifactPath(absolutePath, platform, seenSymlinks) {
62
109
  let cursor = absolutePath;
63
110
  const suffix = [];
64
111
  while (true) {
65
112
  try {
66
113
  const canonicalPath = join(realpathSync.native(cursor), ...suffix);
67
- try {
68
- const stats = statSync(canonicalPath, { bigint: true });
69
- if (stats.ino > 0n)
70
- return `inode:${stats.dev}:${stats.ino}`;
71
- }
72
- catch {
73
- // The destination does not exist yet; canonical ancestry still catches aliases.
74
- }
75
- return foldAgentBrowserFilesystemIdentity(canonicalPath, platform);
114
+ return canonicalFileIdentity(canonicalPath, platform);
76
115
  }
77
116
  catch {
78
- let symlinkTarget;
79
- try {
80
- if (lstatSync(cursor).isSymbolicLink())
81
- symlinkTarget = resolve(dirname(cursor), readlinkSync(cursor));
117
+ // Resolve missing destinations through their existing ancestry below.
118
+ }
119
+ const symlinkTarget = readSymlinkTarget(cursor);
120
+ if (symlinkTarget !== undefined && symlinkTarget !== "") {
121
+ if (seenSymlinks.has(cursor)) {
122
+ throw new Error(`Artifact destination contains a symlink loop: ${absolutePath}`);
82
123
  }
83
- catch { }
84
- if (symlinkTarget) {
85
- if (seenSymlinks.has(cursor))
86
- throw new Error(`Artifact destination contains a symlink loop: ${absolutePath}`);
87
- if (seenSymlinks.size >= 32)
88
- throw new Error(`Artifact destination has too many symlink hops: ${absolutePath}`);
89
- seenSymlinks.add(cursor);
90
- return canonicalizeArtifactPath(join(symlinkTarget, ...suffix), platform, seenSymlinks);
124
+ if (seenSymlinks.size >= 32) {
125
+ throw new Error(`Artifact destination has too many symlink hops: ${absolutePath}`);
91
126
  }
92
- const parent = dirname(cursor);
93
- if (parent === cursor)
94
- return foldAgentBrowserFilesystemIdentity(absolutePath, platform);
95
- suffix.unshift(basename(cursor));
96
- cursor = parent;
127
+ return canonicalizeArtifactPath(join(symlinkTarget, ...suffix), platform, new Set([...seenSymlinks, cursor]));
128
+ }
129
+ const parent = dirname(cursor);
130
+ if (parent === cursor) {
131
+ return foldAgentBrowserFilesystemIdentity(absolutePath, platform);
97
132
  }
133
+ suffix.unshift(basename(cursor));
134
+ cursor = parent;
98
135
  }
99
136
  }
100
137
  export function canonicalizeExplicitArtifactDestination(cwd, destination, platform = process.platform) {
@@ -102,33 +139,48 @@ export function canonicalizeExplicitArtifactDestination(cwd, destination, platfo
102
139
  }
103
140
  export function getRecordContactSheetDestination(commandTokens) {
104
141
  const path = getRecordCommandOperands(commandTokens).path;
105
- if (!path || !commandTokens.some((token) => token === "--contact-sheet" || token === "--contact-sheet-threshold"))
142
+ if (path === undefined ||
143
+ path === "" ||
144
+ !commandTokens.some((token) => token === "--contact-sheet" || token === "--contact-sheet-threshold")) {
106
145
  return undefined;
146
+ }
107
147
  const extension = extname(path);
108
- return extension ? `${path.slice(0, -extension.length)}.contact-sheet.png` : undefined;
148
+ return extension !== "" ? `${path.slice(0, -extension.length)}.contact-sheet.png` : undefined;
149
+ }
150
+ function getCompoundArtifactDestinationIndex(commandTokens) {
151
+ const [command, subcommand] = commandTokens;
152
+ if (command === "state" && subcommand === "save") {
153
+ return 2;
154
+ }
155
+ if (command === "diff" && subcommand === "screenshot") {
156
+ return getDiffFilePathIndices(commandTokens).output;
157
+ }
158
+ if (command === "network" && subcommand === "har" && commandTokens[2] === "stop") {
159
+ return 3;
160
+ }
161
+ if (["trace", "profiler"].includes(command) && subcommand === "stop") {
162
+ return 2;
163
+ }
164
+ return undefined;
109
165
  }
110
166
  export function getExplicitArtifactDestinationIndex(commandTokens) {
111
167
  const command = commandTokens[0];
112
- const subcommand = commandTokens[1];
113
- if (command === "screenshot")
168
+ if (command === "screenshot") {
114
169
  return getScreenshotPathTokenIndex(commandTokens);
115
- if (command === "download")
170
+ }
171
+ if (command === "download") {
116
172
  return 2;
117
- if (command === "pdf")
173
+ }
174
+ if (command === "pdf") {
118
175
  return 1;
119
- if (command === "wait")
176
+ }
177
+ if (command === "wait") {
120
178
  return parseWaitCommandTokens(commandTokens).downloadPathIndex;
121
- if (command === "state" && subcommand === "save")
122
- return 2;
123
- if (command === "diff" && subcommand === "screenshot")
124
- return getDiffFilePathIndices(commandTokens).output;
125
- if (command === "network" && subcommand === "har" && commandTokens[2] === "stop")
126
- return 3;
127
- if ((command === "trace" || command === "profiler") && subcommand === "stop")
128
- return 2;
129
- if (command === "record")
179
+ }
180
+ if (command === "record") {
130
181
  return getRecordCommandOperandIndices(commandTokens)[0];
131
- return undefined;
182
+ }
183
+ return getCompoundArtifactDestinationIndex(commandTokens);
132
184
  }
133
185
  export function getExplicitArtifactDestination(commandTokens) {
134
186
  const index = getExplicitArtifactDestinationIndex(commandTokens);
@@ -0,0 +1,82 @@
1
+ import { isBooleanFlagEnabled } from "../../argv-grammar.js";
2
+ import { isRecord } from "../../parsing.js";
3
+ import { redactSensitiveValue } from "../../runtime-redaction.js";
4
+ import { getNativeWebMcpCatalog } from "../../webmcp-observation.js";
5
+ import { formatWebMcpCatalogUpdate } from "../../results/presentation/common.js";
6
+ import { getSessionContextKey } from "./session-state.js";
7
+ function appendCatalogNotice(result, catalog, data, args) {
8
+ if (isBooleanFlagEnabled(args, "--json") ||
9
+ JSON.stringify(getNativeWebMcpCatalog(data)) === JSON.stringify(catalog)) {
10
+ return result;
11
+ }
12
+ const notice = formatWebMcpCatalogUpdate(catalog);
13
+ const content = [...result.content];
14
+ const first = content.at(0);
15
+ if (first?.type === "text") {
16
+ content[0] = { ...first, text: `${first.text}\n\n${notice}` };
17
+ }
18
+ else {
19
+ content.push({ type: "text", text: notice });
20
+ }
21
+ return { ...result, content };
22
+ }
23
+ function addCatalog(result, catalog, args) {
24
+ if (!catalog) {
25
+ return result;
26
+ }
27
+ const redacted = redactSensitiveValue(catalog);
28
+ if (!isRecord(redacted)) {
29
+ throw new Error("Browser catalog redaction did not preserve its object shape.");
30
+ }
31
+ const details = isRecord(result.details) ? result.details : undefined;
32
+ return appendCatalogNotice({ ...result, details: { ...details, webMcpCatalog: redacted } }, redacted, details?.data, args);
33
+ }
34
+ function addFailureError(result) {
35
+ const details = isRecord(result.details) ? result.details : undefined;
36
+ if (result.isError !== true || details?.error !== undefined) {
37
+ return result;
38
+ }
39
+ return {
40
+ ...result,
41
+ details: {
42
+ ...details,
43
+ error: details?.validationError ??
44
+ details?.summary ??
45
+ result.content
46
+ .filter((part) => part.type === "text")
47
+ .map((part) => part.text)
48
+ .join("\n"),
49
+ },
50
+ };
51
+ }
52
+ function addPendingPageState(result, state) {
53
+ const details = isRecord(result.details) ? result.details : undefined;
54
+ const key = getSessionContextKey(typeof details?.sessionName === "string" ? details.sessionName : undefined, typeof details?.namespace === "string" ? details.namespace : undefined);
55
+ const page = state.sessionPageState.get(key);
56
+ if (page.tabReopenPending === undefined) {
57
+ return result;
58
+ }
59
+ return {
60
+ ...result,
61
+ details: {
62
+ ...details,
63
+ sessionTabReopenPending: page.tabReopenPending,
64
+ ...(page.refSnapshotInvalidation
65
+ ? { refSnapshotInvalidation: page.refSnapshotInvalidation }
66
+ : {}),
67
+ },
68
+ };
69
+ }
70
+ export function projectBrowserObservationResult(options) {
71
+ let result = options.result;
72
+ const details = isRecord(result.details) ? result.details : undefined;
73
+ const confirmation = options.state.observedBrowserEffects?.readConfirmation;
74
+ if (details?.readConfirmation === undefined && Boolean(confirmation)) {
75
+ result = { ...result, details: { ...details, readConfirmation: confirmation } };
76
+ }
77
+ result = addFailureError(addCatalog(result, options.catalog, options.args));
78
+ if (options.modelVisible === false) {
79
+ result = { ...result, content: [] };
80
+ }
81
+ return addPendingPageState(result, options.state);
82
+ }