pi-agent-browser-native 0.9.2 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/CHANGELOG.md +91 -5
  2. package/README.md +120 -86
  3. package/dist/extensions/agent-browser/index.js +43065 -2016
  4. package/dist/extensions/agent-browser/lib/argv-descriptor.js +49 -26
  5. package/dist/extensions/agent-browser/lib/argv-grammar.js +82 -93
  6. package/dist/extensions/agent-browser/lib/bash-guard.js +129 -126
  7. package/dist/extensions/agent-browser/lib/batch-lifecycle.js +113 -49
  8. package/dist/extensions/agent-browser/lib/browser-execution-claim-codec.js +61 -0
  9. package/dist/extensions/agent-browser/lib/browser-execution-claim-storage.js +232 -0
  10. package/dist/extensions/agent-browser/lib/browser-execution-claims.js +202 -0
  11. package/dist/extensions/agent-browser/lib/browser-execution-identity.js +77 -0
  12. package/dist/extensions/agent-browser/lib/browser-journal-branch.js +98 -0
  13. package/dist/extensions/agent-browser/lib/browser-journal-contracts.js +1 -0
  14. package/dist/extensions/agent-browser/lib/browser-journal-projection.js +221 -0
  15. package/dist/extensions/agent-browser/lib/browser-journal-reader.js +89 -0
  16. package/dist/extensions/agent-browser/lib/browser-journal-replay.js +246 -0
  17. package/dist/extensions/agent-browser/lib/browser-journal.js +103 -394
  18. package/dist/extensions/agent-browser/lib/browser-legacy-pages.js +220 -0
  19. package/dist/extensions/agent-browser/lib/browser-legacy-projection.js +282 -0
  20. package/dist/extensions/agent-browser/lib/browser-legacy-types.js +1 -0
  21. package/dist/extensions/agent-browser/lib/browser-session-conversion-stream.js +217 -0
  22. package/dist/extensions/agent-browser/lib/browser-session-conversion.js +80 -335
  23. package/dist/extensions/agent-browser/lib/browser-transcript-contracts.js +35 -0
  24. package/dist/extensions/agent-browser/lib/browser-transcript-validation.js +166 -0
  25. package/dist/extensions/agent-browser/lib/browser-transcript.js +137 -81
  26. package/dist/extensions/agent-browser/lib/browser-value-parsing.js +15 -0
  27. package/dist/extensions/agent-browser/lib/command-capabilities.js +340 -0
  28. package/dist/extensions/agent-browser/lib/command-policy.js +107 -88
  29. package/dist/extensions/agent-browser/lib/command-taxonomy.js +49 -322
  30. package/dist/extensions/agent-browser/lib/config-policy.js +138 -343
  31. package/dist/extensions/agent-browser/lib/config-providers.js +71 -0
  32. package/dist/extensions/agent-browser/lib/config-validation.js +218 -0
  33. package/dist/extensions/agent-browser/lib/config.js +19 -7
  34. package/dist/extensions/agent-browser/lib/electron/cdp.js +15 -7
  35. package/dist/extensions/agent-browser/lib/electron/cleanup.js +134 -55
  36. package/dist/extensions/agent-browser/lib/electron/discovery-darwin.js +109 -0
  37. package/dist/extensions/agent-browser/lib/electron/discovery-desktop.js +136 -0
  38. package/dist/extensions/agent-browser/lib/electron/discovery-evidence.js +89 -0
  39. package/dist/extensions/agent-browser/lib/electron/discovery-linux.js +93 -0
  40. package/dist/extensions/agent-browser/lib/electron/discovery-packages.js +162 -0
  41. package/dist/extensions/agent-browser/lib/electron/discovery-types.js +2 -0
  42. package/dist/extensions/agent-browser/lib/electron/discovery.js +140 -549
  43. package/dist/extensions/agent-browser/lib/electron/launch-monitor.js +102 -0
  44. package/dist/extensions/agent-browser/lib/electron/launch-process.js +209 -0
  45. package/dist/extensions/agent-browser/lib/electron/launch-types.js +2 -0
  46. package/dist/extensions/agent-browser/lib/electron/launch.js +249 -354
  47. package/dist/extensions/agent-browser/lib/executable-path.js +21 -12
  48. package/dist/extensions/agent-browser/lib/execution-cwd.js +35 -18
  49. package/dist/extensions/agent-browser/lib/input-modes/electron.js +162 -121
  50. package/dist/extensions/agent-browser/lib/input-modes/job.js +116 -313
  51. package/dist/extensions/agent-browser/lib/input-modes/lookup-network-evidence.js +104 -0
  52. package/dist/extensions/agent-browser/lib/input-modes/lookup-plan.js +132 -0
  53. package/dist/extensions/agent-browser/lib/input-modes/lookup-redaction.js +57 -0
  54. package/dist/extensions/agent-browser/lib/input-modes/lookup-source-evidence.js +151 -0
  55. package/dist/extensions/agent-browser/lib/input-modes/lookup-workspace.js +142 -0
  56. package/dist/extensions/agent-browser/lib/input-modes/lookups.js +57 -412
  57. package/dist/extensions/agent-browser/lib/input-modes/params.js +63 -17
  58. package/dist/extensions/agent-browser/lib/input-modes/qa-analysis.js +268 -0
  59. package/dist/extensions/agent-browser/lib/input-modes/qa-presentation.js +117 -0
  60. package/dist/extensions/agent-browser/lib/input-modes/script-child.js +396 -0
  61. package/dist/extensions/agent-browser/lib/input-modes/script-protocol.js +86 -0
  62. package/dist/extensions/agent-browser/lib/input-modes/script-types.js +1 -0
  63. package/dist/extensions/agent-browser/lib/input-modes/script-validation.js +60 -0
  64. package/dist/extensions/agent-browser/lib/input-modes/script.js +60 -409
  65. package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +218 -128
  66. package/dist/extensions/agent-browser/lib/input-modes/shared.js +15 -4
  67. package/dist/extensions/agent-browser/lib/input-modes/types.js +56 -7
  68. package/dist/extensions/agent-browser/lib/json-schema.js +22 -10
  69. package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +17 -5
  70. package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +92 -425
  71. package/dist/extensions/agent-browser/lib/managed-session-posix-storage.js +58 -0
  72. package/dist/extensions/agent-browser/lib/managed-session-project-identity.js +244 -0
  73. package/dist/extensions/agent-browser/lib/managed-session-restore-context.js +84 -0
  74. package/dist/extensions/agent-browser/lib/managed-session-restore-policy.js +119 -0
  75. package/dist/extensions/agent-browser/lib/managed-session-restore-state.js +83 -0
  76. package/dist/extensions/agent-browser/lib/managed-session-restore.js +168 -300
  77. package/dist/extensions/agent-browser/lib/managed-session-snapshot-records.js +277 -0
  78. package/dist/extensions/agent-browser/lib/managed-session-snapshots.js +128 -305
  79. package/dist/extensions/agent-browser/lib/managed-session-storage.js +56 -253
  80. package/dist/extensions/agent-browser/lib/native-confirmation.js +140 -0
  81. package/dist/extensions/agent-browser/lib/native-output.js +44 -9
  82. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +107 -66
  83. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-merge.js +14 -6
  84. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +109 -57
  85. package/dist/extensions/agent-browser/lib/orchestration/browser-run/browser-observation-result.js +82 -0
  86. package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +171 -57
  87. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostic-values.js +31 -0
  88. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +152 -781
  89. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-observation.js +202 -0
  90. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-text-diagnostics.js +109 -0
  91. package/dist/extensions/agent-browser/lib/orchestration/browser-run/fill-diagnostics.js +119 -0
  92. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-action-recovery.js +147 -0
  93. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-actions.js +144 -0
  94. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-content.js +123 -0
  95. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-contracts.js +1 -0
  96. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-details.js +156 -0
  97. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js +179 -0
  98. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-evidence.js +39 -0
  99. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-missing-binary.js +89 -0
  100. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-recovery.js +97 -0
  101. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js +106 -0
  102. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-timeout.js +110 -0
  103. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +41 -538
  104. package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +204 -108
  105. package/dist/extensions/agent-browser/lib/orchestration/browser-run/interaction-diagnostics.js +290 -0
  106. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-close.js +167 -0
  107. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-inspection.js +108 -0
  108. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +127 -199
  109. package/dist/extensions/agent-browser/lib/orchestration/browser-run/native-helper-observation.js +65 -0
  110. package/dist/extensions/agent-browser/lib/orchestration/browser-run/observation-types.js +1 -0
  111. package/dist/extensions/agent-browser/lib/orchestration/browser-run/overlay-diagnostics.js +120 -0
  112. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +113 -30
  113. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +109 -28
  114. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter-data.js +150 -0
  115. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +138 -253
  116. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-rendered-text.js +147 -0
  117. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +59 -24
  118. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-artifacts.js +159 -0
  119. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-command.js +131 -0
  120. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-contracts.js +1 -0
  121. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-daemon.js +93 -0
  122. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-failure.js +42 -0
  123. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-guards.js +242 -0
  124. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-input.js +75 -0
  125. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-observations.js +92 -0
  126. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-selection.js +254 -0
  127. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-state.js +121 -0
  128. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-refs.js +130 -0
  129. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-resources.js +114 -0
  130. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-semantic.js +121 -0
  131. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-session-plan.js +222 -0
  132. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-timeouts.js +68 -0
  133. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +176 -1114
  134. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-analysis.js +191 -0
  135. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-confirmation.js +152 -0
  136. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-diagnostics.js +182 -0
  137. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-electron.js +150 -0
  138. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-contracts.js +1 -0
  139. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase-contracts.js +1 -0
  140. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase.js +115 -0
  141. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle.js +256 -0
  142. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed-contracts.js +1 -0
  143. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed.js +256 -0
  144. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase-contracts.js +1 -0
  145. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase.js +93 -0
  146. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native.js +113 -0
  147. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation-contracts.js +1 -0
  148. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation.js +316 -0
  149. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-ownership.js +28 -0
  150. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase-contracts.js +1 -0
  151. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase.js +142 -0
  152. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation-contracts.js +1 -0
  153. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation.js +333 -0
  154. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase-contracts.js +1 -0
  155. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase.js +71 -0
  156. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication.js +201 -0
  157. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-receipts.js +183 -0
  158. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-refs.js +200 -0
  159. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-tabs.js +142 -0
  160. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +18 -910
  161. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +23 -13
  162. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-receipt-reconciliation.js +198 -0
  163. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-contracts.js +1 -0
  164. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-presentation.js +154 -0
  165. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery.js +68 -151
  166. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-capture.js +14 -0
  167. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-observation.js +169 -46
  168. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-commands.js +130 -0
  169. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-electron.js +210 -0
  170. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-observations.js +61 -0
  171. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-outcomes.js +187 -0
  172. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-refs.js +171 -0
  173. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-tabs.js +228 -0
  174. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +77 -753
  175. package/dist/extensions/agent-browser/lib/orchestration/browser-run/text-visibility-diagnostics.js +182 -0
  176. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-diagnostics.js +256 -0
  177. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-progress.js +108 -0
  178. package/dist/extensions/agent-browser/lib/orchestration/code-artifact-observation.js +39 -0
  179. package/dist/extensions/agent-browser/lib/orchestration/code-image-observation.js +119 -0
  180. package/dist/extensions/agent-browser/lib/orchestration/electron-host/branch.js +92 -0
  181. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup-result.js +58 -0
  182. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup.js +78 -0
  183. package/dist/extensions/agent-browser/lib/orchestration/electron-host/contracts.js +1 -0
  184. package/dist/extensions/agent-browser/lib/orchestration/electron-host/discovery.js +106 -0
  185. package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +48 -816
  186. package/dist/extensions/agent-browser/lib/orchestration/electron-host/policy.js +86 -0
  187. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-collection.js +69 -0
  188. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-data.js +167 -0
  189. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js +164 -0
  190. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe.js +161 -0
  191. package/dist/extensions/agent-browser/lib/orchestration/electron-host/status.js +165 -0
  192. package/dist/extensions/agent-browser/lib/orchestration/execution-queue.js +21 -9
  193. package/dist/extensions/agent-browser/lib/orchestration/extension-artifact-preflight.js +211 -0
  194. package/dist/extensions/agent-browser/lib/orchestration/extension-artifacts.js +23 -0
  195. package/dist/extensions/agent-browser/lib/orchestration/extension-attachment-replay.js +99 -0
  196. package/dist/extensions/agent-browser/lib/orchestration/extension-branch-restore.js +275 -0
  197. package/dist/extensions/agent-browser/lib/orchestration/extension-code.js +280 -0
  198. package/dist/extensions/agent-browser/lib/orchestration/extension-command-admission.js +303 -0
  199. package/dist/extensions/agent-browser/lib/orchestration/extension-command-output.js +36 -0
  200. package/dist/extensions/agent-browser/lib/orchestration/extension-command-result.js +335 -0
  201. package/dist/extensions/agent-browser/lib/orchestration/extension-command-run.js +227 -0
  202. package/dist/extensions/agent-browser/lib/orchestration/extension-command-state.js +1 -0
  203. package/dist/extensions/agent-browser/lib/orchestration/extension-electron-ownership.js +204 -0
  204. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-locks.js +139 -0
  205. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-queue.js +24 -0
  206. package/dist/extensions/agent-browser/lib/orchestration/extension-host-coordination.js +98 -0
  207. package/dist/extensions/agent-browser/lib/orchestration/extension-host-run.js +295 -0
  208. package/dist/extensions/agent-browser/lib/orchestration/extension-intent-replay.js +41 -0
  209. package/dist/extensions/agent-browser/lib/orchestration/extension-invocation.js +7 -0
  210. package/dist/extensions/agent-browser/lib/orchestration/extension-lifecycle.js +102 -0
  211. package/dist/extensions/agent-browser/lib/orchestration/extension-managed-ownership.js +133 -0
  212. package/dist/extensions/agent-browser/lib/orchestration/extension-observation.js +120 -0
  213. package/dist/extensions/agent-browser/lib/orchestration/extension-prompt.js +180 -0
  214. package/dist/extensions/agent-browser/lib/orchestration/extension-recording.js +290 -0
  215. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-contracts.js +1 -0
  216. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-replay.js +269 -0
  217. package/dist/extensions/agent-browser/lib/orchestration/extension-result-state.js +113 -0
  218. package/dist/extensions/agent-browser/lib/orchestration/extension-runtime.js +146 -0
  219. package/dist/extensions/agent-browser/lib/orchestration/extension-script-leases.js +58 -0
  220. package/dist/extensions/agent-browser/lib/orchestration/extension-tool-boundary.js +62 -0
  221. package/dist/extensions/agent-browser/lib/orchestration/extension-version-check.js +54 -0
  222. package/dist/extensions/agent-browser/lib/orchestration/input-plan-types.js +1 -0
  223. package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +261 -185
  224. package/dist/extensions/agent-browser/lib/orchestration/input-redaction.js +62 -0
  225. package/dist/extensions/agent-browser/lib/orchestration/native-config.js +144 -0
  226. package/dist/extensions/agent-browser/lib/orchestration/native-root-launch.js +77 -0
  227. package/dist/extensions/agent-browser/lib/orchestration/native-session-defaults.js +210 -139
  228. package/dist/extensions/agent-browser/lib/orchestration/operation-paths.js +124 -58
  229. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +198 -98
  230. package/dist/extensions/agent-browser/lib/orchestration/script-mode.js +199 -96
  231. package/dist/extensions/agent-browser/lib/owned-managed-session-context.js +55 -0
  232. package/dist/extensions/agent-browser/lib/page-target-batch.js +118 -0
  233. package/dist/extensions/agent-browser/lib/page-target-guards.js +50 -0
  234. package/dist/extensions/agent-browser/lib/page-target-navigation.js +104 -0
  235. package/dist/extensions/agent-browser/lib/page-target-validation.js +59 -243
  236. package/dist/extensions/agent-browser/lib/parsing.js +13 -4
  237. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +134 -68
  238. package/dist/extensions/agent-browser/lib/playbook.js +18 -14
  239. package/dist/extensions/agent-browser/lib/process-child.js +284 -0
  240. package/dist/extensions/agent-browser/lib/process-environment.js +22 -6
  241. package/dist/extensions/agent-browser/lib/process-errors.js +23 -0
  242. package/dist/extensions/agent-browser/lib/process-identity.js +47 -15
  243. package/dist/extensions/agent-browser/lib/process-socket-storage.js +256 -0
  244. package/dist/extensions/agent-browser/lib/process-stdout.js +74 -0
  245. package/dist/extensions/agent-browser/lib/process.js +146 -537
  246. package/dist/extensions/agent-browser/lib/prompt-artifacts.js +287 -0
  247. package/dist/extensions/agent-browser/lib/prompt-policy.js +15 -194
  248. package/dist/extensions/agent-browser/lib/read-command.js +41 -0
  249. package/dist/extensions/agent-browser/lib/read-confirmation.js +138 -35
  250. package/dist/extensions/agent-browser/lib/recording-reservations.js +118 -45
  251. package/dist/extensions/agent-browser/lib/redaction-fields.js +75 -0
  252. package/dist/extensions/agent-browser/lib/redaction-json.js +149 -0
  253. package/dist/extensions/agent-browser/lib/redaction-url.js +88 -0
  254. package/dist/extensions/agent-browser/lib/results/action-contracts.js +1 -0
  255. package/dist/extensions/agent-browser/lib/results/action-recommendations.js +28 -271
  256. package/dist/extensions/agent-browser/lib/results/artifact-contracts.js +1 -0
  257. package/dist/extensions/agent-browser/lib/results/artifact-manifest-validation.js +133 -0
  258. package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +96 -94
  259. package/dist/extensions/agent-browser/lib/results/artifact-recommendations.js +73 -0
  260. package/dist/extensions/agent-browser/lib/results/categories.js +111 -54
  261. package/dist/extensions/agent-browser/lib/results/confirmation.js +29 -10
  262. package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +62 -27
  263. package/dist/extensions/agent-browser/lib/results/electron-recommendations.js +83 -0
  264. package/dist/extensions/agent-browser/lib/results/envelope-decoding.js +48 -0
  265. package/dist/extensions/agent-browser/lib/results/envelope.js +93 -66
  266. package/dist/extensions/agent-browser/lib/results/evidence-contracts.js +1 -0
  267. package/dist/extensions/agent-browser/lib/results/failure-recommendations.js +180 -0
  268. package/dist/extensions/agent-browser/lib/results/network-routes.js +86 -45
  269. package/dist/extensions/agent-browser/lib/results/network.js +35 -12
  270. package/dist/extensions/agent-browser/lib/results/next-actions.js +49 -19
  271. package/dist/extensions/agent-browser/lib/results/presentation/artifact-files.js +320 -0
  272. package/dist/extensions/agent-browser/lib/results/presentation/artifact-format.js +138 -0
  273. package/dist/extensions/agent-browser/lib/results/presentation/artifact-images.js +113 -0
  274. package/dist/extensions/agent-browser/lib/results/presentation/artifact-verification.js +145 -0
  275. package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +99 -552
  276. package/dist/extensions/agent-browser/lib/results/presentation/batch-contracts.js +1 -0
  277. package/dist/extensions/agent-browser/lib/results/presentation/batch-recording.js +118 -0
  278. package/dist/extensions/agent-browser/lib/results/presentation/batch-redaction.js +68 -0
  279. package/dist/extensions/agent-browser/lib/results/presentation/batch-rendering.js +135 -0
  280. package/dist/extensions/agent-browser/lib/results/presentation/batch-step.js +227 -0
  281. package/dist/extensions/agent-browser/lib/results/presentation/batch-summary.js +91 -0
  282. package/dist/extensions/agent-browser/lib/results/presentation/batch.js +91 -460
  283. package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +9 -5
  284. package/dist/extensions/agent-browser/lib/results/presentation/command-presenters.js +216 -0
  285. package/dist/extensions/agent-browser/lib/results/presentation/common.js +26 -9
  286. package/dist/extensions/agent-browser/lib/results/presentation/content.js +86 -29
  287. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-a11y.js +67 -0
  288. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-health.js +79 -0
  289. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-identity.js +199 -0
  290. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-logs.js +75 -0
  291. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network-actions.js +216 -0
  292. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network.js +124 -0
  293. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js +64 -0
  294. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js +209 -0
  295. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-stream.js +69 -0
  296. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-summary.js +222 -0
  297. package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +103 -1019
  298. package/dist/extensions/agent-browser/lib/results/presentation/early-result.js +70 -0
  299. package/dist/extensions/agent-browser/lib/results/presentation/errors.js +130 -60
  300. package/dist/extensions/agent-browser/lib/results/presentation/input-contracts.js +1 -0
  301. package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +60 -145
  302. package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +147 -88
  303. package/dist/extensions/agent-browser/lib/results/presentation/notices.js +75 -0
  304. package/dist/extensions/agent-browser/lib/results/presentation/observation-contracts.js +1 -0
  305. package/dist/extensions/agent-browser/lib/results/presentation/observation-rendering.js +127 -0
  306. package/dist/extensions/agent-browser/lib/results/presentation/outcomes.js +120 -0
  307. package/dist/extensions/agent-browser/lib/results/presentation/output-completion.js +77 -0
  308. package/dist/extensions/agent-browser/lib/results/presentation/output-spill.js +51 -0
  309. package/dist/extensions/agent-browser/lib/results/presentation/registry.js +117 -237
  310. package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +35 -21
  311. package/dist/extensions/agent-browser/lib/results/presentation/skills.js +104 -73
  312. package/dist/extensions/agent-browser/lib/results/presentation/source.js +109 -0
  313. package/dist/extensions/agent-browser/lib/results/presentation.js +17 -248
  314. package/dist/extensions/agent-browser/lib/results/recommendation-contracts.js +1 -0
  315. package/dist/extensions/agent-browser/lib/results/recording.js +52 -14
  316. package/dist/extensions/agent-browser/lib/results/recovery-actions.js +14 -5
  317. package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +30 -22
  318. package/dist/extensions/agent-browser/lib/results/selector-recovery-target.js +83 -0
  319. package/dist/extensions/agent-browser/lib/results/selector-recovery.js +123 -123
  320. package/dist/extensions/agent-browser/lib/results/snapshot-compact.js +266 -0
  321. package/dist/extensions/agent-browser/lib/results/snapshot-content.js +32 -0
  322. package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +104 -71
  323. package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +31 -11
  324. package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +125 -66
  325. package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +26 -7
  326. package/dist/extensions/agent-browser/lib/results/snapshot.js +28 -248
  327. package/dist/extensions/agent-browser/lib/results/text.js +16 -5
  328. package/dist/extensions/agent-browser/lib/runtime-args-validation.js +133 -0
  329. package/dist/extensions/agent-browser/lib/runtime-compatibility.js +81 -0
  330. package/dist/extensions/agent-browser/lib/runtime-contracts.js +1 -0
  331. package/dist/extensions/agent-browser/lib/runtime-redaction.js +118 -0
  332. package/dist/extensions/agent-browser/lib/runtime-replay-events.js +144 -0
  333. package/dist/extensions/agent-browser/lib/runtime-session-identity.js +76 -0
  334. package/dist/extensions/agent-browser/lib/runtime-session-plan.js +114 -0
  335. package/dist/extensions/agent-browser/lib/runtime-session-replay.js +123 -0
  336. package/dist/extensions/agent-browser/lib/runtime-tab-correction.js +65 -0
  337. package/dist/extensions/agent-browser/lib/runtime-timeouts.js +28 -0
  338. package/dist/extensions/agent-browser/lib/runtime.js +137 -1037
  339. package/dist/extensions/agent-browser/lib/session-identity.js +51 -0
  340. package/dist/extensions/agent-browser/lib/session-page-observation.js +357 -0
  341. package/dist/extensions/agent-browser/lib/session-page-state.js +188 -324
  342. package/dist/extensions/agent-browser/lib/session-page-types.js +1 -0
  343. package/dist/extensions/agent-browser/lib/temp-artifact-budget.js +78 -0
  344. package/dist/extensions/agent-browser/lib/temp-mutation-queue.js +7 -0
  345. package/dist/extensions/agent-browser/lib/temp-root-ownership.js +234 -0
  346. package/dist/extensions/agent-browser/lib/temp-root.js +207 -0
  347. package/dist/extensions/agent-browser/lib/temp.js +33 -446
  348. package/dist/extensions/agent-browser/lib/tool-surface.js +94 -24
  349. package/dist/extensions/agent-browser/lib/upstream-version.js +3 -2
  350. package/dist/extensions/agent-browser/lib/web-search-providers.js +229 -0
  351. package/dist/extensions/agent-browser/lib/web-search-request.js +108 -0
  352. package/dist/extensions/agent-browser/lib/web-search-results.js +281 -0
  353. package/dist/extensions/agent-browser/lib/web-search-schema.js +82 -0
  354. package/dist/extensions/agent-browser/lib/web-search.js +109 -617
  355. package/dist/extensions/agent-browser/lib/webmcp-observation.js +13 -6
  356. package/dist/extensions/agent-browser/lib/windows-stock-launcher.js +63 -37
  357. package/dist/extensions/agent-browser/script-worker.js +80 -43
  358. package/dist/scripts/agent-browser-target.mjs +4 -2
  359. package/docs/ARCHITECTURE.md +22 -10
  360. package/docs/CODE_QUALITY.md +242 -0
  361. package/docs/COMMAND_REFERENCE.md +264 -229
  362. package/docs/ELECTRON.md +53 -44
  363. package/docs/RELEASE.md +21 -17
  364. package/docs/REQUIREMENTS.md +2 -0
  365. package/docs/SESSION_STORAGE.md +1 -1
  366. package/docs/SUPPORT_MATRIX.md +84 -77
  367. package/docs/TOOL_CONTRACT.md +165 -130
  368. package/docs/platform-smoke.md +5 -5
  369. package/package.json +143 -120
  370. package/scripts/agent-browser-capability-baseline.mjs +361 -957
  371. package/scripts/agent-browser-target.mjs +6 -2
  372. package/scripts/build.mjs +37 -8
  373. package/scripts/capability-core-commands.mjs +193 -0
  374. package/scripts/capability-options.mjs +283 -0
  375. package/scripts/capability-samples.mjs +133 -0
  376. package/scripts/capability-section.mjs +11 -0
  377. package/scripts/config.mjs +213 -114
  378. package/scripts/convert-browser-session.mjs +30 -9
  379. package/scripts/doctor-sources.mjs +195 -0
  380. package/scripts/doctor.mjs +92 -247
  381. package/scripts/platform-smoke/artifacts.mjs +38 -11
  382. package/scripts/platform-smoke/commands.mjs +104 -0
  383. package/scripts/platform-smoke/crabbox-runner.mjs +167 -80
  384. package/scripts/platform-smoke/doctor-support.mjs +157 -0
  385. package/scripts/platform-smoke/doctor-windows.mjs +230 -0
  386. package/scripts/platform-smoke/doctor.mjs +212 -320
  387. package/scripts/platform-smoke/lease-evidence.mjs +134 -0
  388. package/scripts/platform-smoke/suite-checks.mjs +98 -0
  389. package/scripts/platform-smoke/suite-evidence.mjs +281 -0
  390. package/scripts/platform-smoke/targets.mjs +158 -472
  391. package/scripts/platform-smoke.mjs +55 -40
  392. package/scripts/prepare.mjs +16 -7
@@ -1,59 +1,162 @@
1
1
  import { extractUpstreamCommandTokens } from "./argv-descriptor.js";
2
- import { extractExplicitSessionName, getAgentBrowserSessionIdentityKey, resolveAgentBrowserNamespace, scanUpstreamGlobalFlagOccurrences } from "./argv-grammar.js";
2
+ import { extractExplicitSessionName, getAgentBrowserSessionIdentityKey, resolveAgentBrowserNamespace, scanUpstreamGlobalFlagOccurrences, } from "./argv-grammar.js";
3
3
  import { getExplicitReadUrl } from "./command-policy.js";
4
4
  import { isCloseCommand } from "./command-taxonomy.js";
5
- import { isRecord } from "./parsing.js";
6
- export function parseReadConfirmation(value) {
7
- if (!isRecord(value) || value.source !== "native-explicit-url-read" || (value.state !== "pending" && value.state !== "cleared"))
8
- return undefined;
9
- if (typeof value.id !== "string" || !value.id || typeof value.sessionName !== "string" || !value.sessionName || (value.namespace !== undefined && typeof value.namespace !== "string"))
10
- return undefined;
11
- return { ...(isRecord(value.capabilities) && value.capabilities.readRequiresConfirmation === true ? { capabilities: { readRequiresConfirmation: true } } : {}), id: value.id, sessionName: value.sessionName, namespace: value.namespace, source: "native-explicit-url-read", state: value.state };
5
+ import { getUpstreamEffectiveBatchSteps } from "./orchestration/batch-stdin.js";
6
+ import { getConfirmedNativeResult, getNativePendingControl, } from "./native-confirmation.js";
7
+ export { parseReadConfirmation, getNativeTabContinuationGuidance, isSuccessfulNativeConfirmedClose, } from "./native-confirmation.js";
8
+ export function isBrowserIndependentConfirmation(value) {
9
+ return (value?.source === "native-explicit-url-read" &&
10
+ value.capabilities?.readRequiresConfirmation === true);
11
+ }
12
+ export function suppressConfirmationPageHelpers(value) {
13
+ return (value?.state === "pending" &&
14
+ (value.source === "native-guarded-action" || isBrowserIndependentConfirmation(value)));
12
15
  }
13
- export function findReadConfirmation(args, confirmations, namespace) {
14
- const tokens = extractUpstreamCommandTokens(args);
15
- if (tokens.length !== 2 || !["confirm", "deny"].includes(tokens[0]))
16
+ export function findReadConfirmation(args,
17
+ // lib.es2015.iterable.d.ts exposes a mutable iterator cursor; only deeply readonly confirmation values are consumed.
18
+ // oxlint-disable-next-line typescript/prefer-readonly-parameter-types
19
+ confirmations, namespace, stdin) {
20
+ const command = extractUpstreamCommandTokens(args);
21
+ const tokens = command[0] === "batch" ? (getUpstreamEffectiveBatchSteps(command, stdin)[0] ?? []) : command;
22
+ if (tokens.length !== 2 || !["confirm", "deny"].includes(tokens[0])) {
16
23
  return undefined;
24
+ }
17
25
  const sessionName = extractExplicitSessionName(args);
18
26
  const effectiveNamespace = resolveAgentBrowserNamespace(args, namespace);
19
- const matches = [...confirmations].filter(value => value.state === "pending" && value.id === tokens[1]
20
- && (sessionName === undefined || getAgentBrowserSessionIdentityKey(sessionName, value.namespace) === getAgentBrowserSessionIdentityKey(value.sessionName, value.namespace))
21
- && (effectiveNamespace === undefined || getAgentBrowserSessionIdentityKey(value.sessionName, effectiveNamespace) === getAgentBrowserSessionIdentityKey(value.sessionName, value.namespace)));
27
+ const matches = [...confirmations].filter((value) => value.state === "pending" &&
28
+ value.id === tokens[1] &&
29
+ (command[0] !== "batch" || value.source === "native-guarded-action") &&
30
+ (sessionName === undefined ||
31
+ getAgentBrowserSessionIdentityKey(sessionName, value.namespace) ===
32
+ getAgentBrowserSessionIdentityKey(value.sessionName, value.namespace)) &&
33
+ (effectiveNamespace === undefined ||
34
+ getAgentBrowserSessionIdentityKey(value.sessionName, effectiveNamespace) ===
35
+ getAgentBrowserSessionIdentityKey(value.sessionName, value.namespace)));
22
36
  return matches.length === 1 ? matches[0] : undefined;
23
37
  }
24
38
  export function scopeReadConfirmationArgs(args, confirmation) {
25
39
  return [
26
- ...(scanUpstreamGlobalFlagOccurrences(args, "--namespace").length === 0 ? ["--namespace", confirmation.namespace ?? ""] : []),
27
- ...(extractExplicitSessionName(args) === undefined ? ["--session", confirmation.sessionName] : []),
40
+ ...(scanUpstreamGlobalFlagOccurrences(args, "--namespace").length === 0
41
+ ? ["--namespace", confirmation.namespace ?? ""]
42
+ : []),
43
+ ...(extractExplicitSessionName(args) === undefined
44
+ ? ["--session", confirmation.sessionName]
45
+ : []),
28
46
  ...args,
29
47
  ];
30
48
  }
49
+ function isExplicitReadProvenance(pending, tokens, confirmed) {
50
+ return (pending.action === "read" &&
51
+ (typeof getExplicitReadUrl(tokens) === "string" ||
52
+ confirmed?.source === "native-explicit-url-read"));
53
+ }
54
+ function isOriginalGuardedAction(command) {
55
+ return command !== undefined && command.length > 0 && !["confirm", "deny"].includes(command);
56
+ }
57
+ function pendingConfirmation(pending, tokens, identity) {
58
+ if (isExplicitReadProvenance(pending, tokens, identity.confirmed)) {
59
+ return {
60
+ ...(pending.capabilities !== undefined ? { capabilities: pending.capabilities } : {}),
61
+ id: pending.id,
62
+ namespace: identity.namespace,
63
+ sessionName: identity.sessionName,
64
+ source: "native-explicit-url-read",
65
+ state: "pending",
66
+ };
67
+ }
68
+ const command = tokens.at(0);
69
+ if (isOriginalGuardedAction(command) || identity.confirmed?.source === "native-guarded-action") {
70
+ return {
71
+ id: pending.id,
72
+ namespace: identity.namespace,
73
+ sessionName: identity.sessionName,
74
+ source: "native-guarded-action",
75
+ command: identity.confirmed !== undefined ? identity.confirmed.command : command,
76
+ action: pending.action,
77
+ state: "pending",
78
+ };
79
+ }
80
+ return undefined;
81
+ }
82
+ function settlesPendingConfirmation(tokens, current) {
83
+ return (current?.state === "pending" &&
84
+ tokens.length === 2 &&
85
+ ["confirm", "deny"].includes(tokens[0]) &&
86
+ tokens[1] === current.id);
87
+ }
88
+ function confirmedDecisionResult(tokens, current, data) {
89
+ if (tokens[0] !== "confirm" ||
90
+ current === undefined ||
91
+ !settlesPendingConfirmation(tokens, current)) {
92
+ return undefined;
93
+ }
94
+ return getConfirmedNativeResult(data, current);
95
+ }
96
+ function clearedConfirmation(current, command, succeeded, settles) {
97
+ return succeeded && current?.state === "pending" && (settles || isCloseCommand(command))
98
+ ? { ...current, state: "cleared" }
99
+ : undefined;
100
+ }
31
101
  export function nextReadConfirmation(options) {
32
102
  const { commandTokens: tokens, current } = options;
33
- const settlesRead = current?.state === "pending" && tokens.length === 2 && ["confirm", "deny"].includes(tokens[0]) && tokens[1] === current.id;
34
- const confirmedResult = settlesRead && tokens[0] === "confirm" && isRecord(options.data) && options.data.confirmed === true && options.data.action === "read" && isRecord(options.data.result)
35
- ? options.data.result.data : options.data;
36
- // Native control fields only. Never parse response content, snapshot text or nested page JSON as provenance.
37
- if (isRecord(confirmedResult) && confirmedResult.confirmation_required === true && typeof confirmedResult.confirmation_id === "string" && confirmedResult.confirmation_id && !("content" in confirmedResult)) {
38
- if (confirmedResult.action === "read" && (typeof getExplicitReadUrl(tokens) === "string" || settlesRead)) {
39
- return { ...(isRecord(confirmedResult.capabilities) && confirmedResult.capabilities.readRequiresConfirmation === true ? { capabilities: { readRequiresConfirmation: true } } : {}), id: confirmedResult.confirmation_id, namespace: options.namespace, sessionName: options.sessionName, source: "native-explicit-url-read", state: "pending" };
103
+ const settles = settlesPendingConfirmation(tokens, current);
104
+ const confirmedResult = confirmedDecisionResult(tokens, current, options.data);
105
+ const pending = options.succeeded
106
+ ? getNativePendingControl(tokens, confirmedResult !== undefined ? confirmedResult.data : options.data)
107
+ : undefined;
108
+ if (pending !== undefined) {
109
+ const next = pendingConfirmation(pending, tokens, {
110
+ namespace: options.namespace,
111
+ sessionName: options.sessionName,
112
+ confirmed: confirmedResult !== undefined ? current : undefined,
113
+ });
114
+ if (next !== undefined) {
115
+ return next;
40
116
  }
41
- if (current?.state === "pending")
117
+ if (current?.state === "pending") {
42
118
  return { ...current, state: "cleared" };
119
+ }
43
120
  }
44
- return options.succeeded && current?.state === "pending" && (settlesRead || isCloseCommand(tokens[0])) ? { ...current, state: "cleared" } : undefined;
121
+ return clearedConfirmation(current, tokens[0], options.succeeded, settles);
122
+ }
123
+ function confirmationSafety(confirmation) {
124
+ if (isBrowserIndependentConfirmation(confirmation)) {
125
+ return "Review the requested read first. The native capability proves ID matching; no DOM confirmation is implied.";
126
+ }
127
+ return confirmation.source === "native-guarded-action"
128
+ ? "Review the original guarded action. Exact wrapper observation preserves its session and avoids overwriting helpers; native ID validation is not implied."
129
+ : "Native ID matching/browser independence is unproven. The exact native session is preserved, but this confirmation retains normal page checks.";
45
130
  }
46
131
  export function buildReadConfirmationNextActions(confirmation, pendingResponse) {
47
- if (confirmation.state === "cleared")
132
+ if (confirmation.state === "cleared") {
48
133
  return [];
49
- const prefix = ["--namespace", confirmation.namespace ?? "", "--session", confirmation.sessionName];
50
- if (!pendingResponse)
51
- return [{ id: "inspect-read-confirmation-session", tool: "agent_browser", params: { args: [...prefix, "session", "info"] }, reason: "Inspect the exact native session after the read confirmation failed; rerun the original URL read if its ID expired.", safety: "Read-only status, without browser launch or tab changes. Do not substitute a different pending confirmation ID." }];
52
- return ["confirm", "deny"].map(command => ({
53
- id: command === "confirm" ? "approve-confirmation" : "deny-confirmation", tool: "agent_browser", params: { args: [...prefix, command, confirmation.id] },
54
- reason: `${command === "confirm" ? "Approve" : "Deny"} the native confirmation for this explicit URL read.`,
55
- safety: confirmation.capabilities?.readRequiresConfirmation === true
56
- ? "Review the requested read first. The native capability proves ID matching; no DOM confirmation is implied."
57
- : "Native ID matching/browser independence is unproven. The exact native session is preserved, but this confirmation retains normal page checks.",
134
+ }
135
+ const prefix = [
136
+ "--namespace",
137
+ confirmation.namespace ?? "",
138
+ "--session",
139
+ confirmation.sessionName,
140
+ ];
141
+ if (!pendingResponse) {
142
+ return [
143
+ {
144
+ id: "inspect-read-confirmation-session",
145
+ tool: "agent_browser",
146
+ params: { args: [...prefix, "session", "info"] },
147
+ reason: "Inspect the exact native session after the confirmation failed; rerun the original command if its ID expired.",
148
+ safety: "Read-only status, without browser launch or tab changes. Do not substitute a different pending confirmation ID.",
149
+ },
150
+ ];
151
+ }
152
+ const subject = confirmation.source === "native-explicit-url-read"
153
+ ? "this explicit URL read"
154
+ : `${confirmation.command ?? ""} (${confirmation.action ?? ""})`;
155
+ return ["confirm", "deny"].map((command) => ({
156
+ id: command === "confirm" ? "approve-confirmation" : "deny-confirmation",
157
+ tool: "agent_browser",
158
+ params: { args: [...prefix, command, confirmation.id] },
159
+ reason: `${command === "confirm" ? "Approve" : "Deny"} the native confirmation for ${subject}.`,
160
+ safety: confirmationSafety(confirmation),
58
161
  }));
59
162
  }
@@ -7,58 +7,96 @@ function getReservationKey(reservation) {
7
7
  return getAgentBrowserSessionIdentityKey(reservation.sessionName, reservation.namespace);
8
8
  }
9
9
  function getArtifactReservation(artifact) {
10
- if (!artifact.session || artifact.command !== "record" || artifact.kind !== "video")
10
+ if (artifact.session === undefined ||
11
+ artifact.session.length === 0 ||
12
+ artifact.command !== "record" ||
13
+ artifact.kind !== "video") {
11
14
  return undefined;
15
+ }
12
16
  return {
13
17
  absolutePath: artifact.absolutePath,
14
18
  cwd: artifact.cwd ?? process.cwd(),
15
19
  namespace: artifact.namespace,
16
20
  path: artifact.path,
17
- ...(artifact.recording?.recordingId ? { recordingId: artifact.recording.recordingId } : {}),
18
- ...(artifact.recordingStartedAtMs !== undefined ? { startedAtMs: artifact.recordingStartedAtMs } : {}),
21
+ ...(typeof artifact.recording?.recordingId === "string" &&
22
+ artifact.recording.recordingId.length > 0
23
+ ? { recordingId: artifact.recording.recordingId }
24
+ : {}),
25
+ ...(artifact.recordingStartedAtMs !== undefined
26
+ ? { startedAtMs: artifact.recordingStartedAtMs }
27
+ : {}),
19
28
  sessionName: artifact.session,
20
29
  };
21
30
  }
22
- export function applyRecordingArtifactsToReservations(reservations, artifacts) {
31
+ function artifactReservations(artifacts) {
23
32
  const pendingBySession = new Map();
24
33
  const terminalBySession = new Map();
25
34
  for (const artifact of artifacts) {
26
- const reservation = getArtifactReservation(artifact);
27
- if (!reservation)
35
+ let reservation = getArtifactReservation(artifact);
36
+ if (!reservation) {
28
37
  continue;
29
- const sheet = artifacts.find((candidate) => candidate.command === "record" && candidate.kind === "image" && candidate.session === artifact.session && candidate.namespace === artifact.namespace && isPendingRecordingArtifact(candidate));
30
- if (sheet)
31
- reservation.contactSheetPath = sheet.absolutePath;
38
+ }
39
+ const sheet = artifacts.find((candidate) => candidate.command === "record" &&
40
+ candidate.kind === "image" &&
41
+ candidate.session === artifact.session &&
42
+ candidate.namespace === artifact.namespace &&
43
+ isPendingRecordingArtifact(candidate));
44
+ if (sheet) {
45
+ reservation = { ...reservation, contactSheetPath: sheet.absolutePath };
46
+ }
32
47
  const key = getReservationKey(reservation);
33
- if (isPendingRecordingArtifact(artifact))
48
+ if (isPendingRecordingArtifact(artifact)) {
34
49
  pendingBySession.set(key, reservation);
35
- else
50
+ }
51
+ else {
36
52
  terminalBySession.set(key, reservation);
53
+ }
37
54
  }
55
+ return { pendingBySession, terminalBySession };
56
+ }
57
+ function reservationChanged(existing, pending) {
58
+ return (!existing ||
59
+ existing.absolutePath !== pending.absolutePath ||
60
+ existing.cwd !== pending.cwd ||
61
+ existing.recordingId !== pending.recordingId ||
62
+ existing.startedAtMs !== pending.startedAtMs ||
63
+ existing.contactSheetPath !== pending.contactSheetPath);
64
+ }
65
+ export function applyRecordingArtifactsToReservations(
66
+ // This mutator owns changes to the namespace/session reservation index, not to reservation values.
67
+ // oxlint-disable-next-line typescript/prefer-readonly-parameter-types
68
+ reservations, artifacts) {
69
+ const { pendingBySession, terminalBySession } = artifactReservations(artifacts);
38
70
  const transitions = [];
39
71
  for (const key of terminalBySession.keys()) {
40
- if (pendingBySession.has(key))
72
+ if (pendingBySession.has(key)) {
41
73
  continue;
74
+ }
42
75
  const existing = reservations.get(key);
43
- if (!existing)
76
+ if (!existing) {
44
77
  continue;
78
+ }
45
79
  reservations.delete(key);
46
80
  transitions.push({ reservation: existing, state: "closed" });
47
81
  }
48
82
  for (const [key, pending] of pendingBySession) {
49
83
  const existing = reservations.get(key);
50
84
  reservations.set(key, pending);
51
- if (!existing || existing.absolutePath !== pending.absolutePath || existing.cwd !== pending.cwd || existing.recordingId !== pending.recordingId || existing.startedAtMs !== pending.startedAtMs || existing.contactSheetPath !== pending.contactSheetPath) {
85
+ if (reservationChanged(existing, pending)) {
52
86
  transitions.push({ reservation: pending, state: "active" });
53
87
  }
54
88
  }
55
89
  return transitions;
56
90
  }
57
- export function retireRecordingReservation(reservations, sessionName, namespace) {
91
+ export function retireRecordingReservation(
92
+ // This mutator owns changes to the namespace/session reservation index, not to reservation values.
93
+ // oxlint-disable-next-line typescript/prefer-readonly-parameter-types
94
+ reservations, sessionName, namespace) {
58
95
  const key = getAgentBrowserSessionIdentityKey(sessionName, namespace);
59
96
  const reservation = reservations.get(key);
60
- if (reservation)
97
+ if (reservation) {
61
98
  reservations.delete(key);
99
+ }
62
100
  return reservation;
63
101
  }
64
102
  export function appendRecordingReservationTransition(pi, transition) {
@@ -76,51 +114,86 @@ export function appendRecordingReservationTransition(pi, transition) {
76
114
  version: 1,
77
115
  });
78
116
  }
79
- function parseReservationTransition(data) {
80
- if (!isRecord(data) || data.version !== 1 || (data.state !== "active" && data.state !== "closed"))
117
+ function optionalReservationMetadata(data) {
118
+ if (data.contactSheetPath !== undefined &&
119
+ (typeof data.contactSheetPath !== "string" || !isAbsolute(data.contactSheetPath))) {
120
+ return false;
121
+ }
122
+ if (data.recordingId !== undefined &&
123
+ (typeof data.recordingId !== "string" || data.recordingId.length === 0)) {
124
+ return false;
125
+ }
126
+ return (data.startedAtMs === undefined ||
127
+ (typeof data.startedAtMs === "number" && Number.isFinite(data.startedAtMs)));
128
+ }
129
+ function parseActiveReservation(data, identity) {
130
+ if (!optionalReservationMetadata(data)) {
131
+ return undefined;
132
+ }
133
+ if (typeof data.absolutePath !== "string" ||
134
+ !isAbsolute(data.absolutePath) ||
135
+ typeof data.cwd !== "string" ||
136
+ !isAbsolute(data.cwd) ||
137
+ typeof data.path !== "string") {
81
138
  return undefined;
82
- if (typeof data.sessionName !== "string" || data.sessionName.length === 0)
139
+ }
140
+ return {
141
+ ...identity,
142
+ absolutePath: data.absolutePath,
143
+ cwd: data.cwd,
144
+ path: data.path,
145
+ ...(typeof data.contactSheetPath === "string"
146
+ ? { contactSheetPath: data.contactSheetPath }
147
+ : {}),
148
+ ...(typeof data.recordingId === "string" ? { recordingId: data.recordingId } : {}),
149
+ ...(typeof data.startedAtMs === "number" ? { startedAtMs: data.startedAtMs } : {}),
150
+ };
151
+ }
152
+ function hasReservationIdentity(data) {
153
+ return (typeof data.sessionName === "string" &&
154
+ data.sessionName.length > 0 &&
155
+ (data.namespace === undefined || typeof data.namespace === "string"));
156
+ }
157
+ function parseReservationTransition(data) {
158
+ if (!isRecord(data) ||
159
+ data.version !== 1 ||
160
+ (data.state !== "active" && data.state !== "closed")) {
83
161
  return undefined;
84
- if (data.namespace !== undefined && typeof data.namespace !== "string")
162
+ }
163
+ if (!hasReservationIdentity(data)) {
85
164
  return undefined;
165
+ }
86
166
  if (data.state === "closed") {
87
167
  return {
88
- reservation: { absolutePath: "", cwd: "", namespace: data.namespace, path: "", sessionName: data.sessionName },
168
+ reservation: {
169
+ absolutePath: "",
170
+ cwd: "",
171
+ namespace: data.namespace,
172
+ path: "",
173
+ sessionName: data.sessionName,
174
+ },
89
175
  state: "closed",
90
176
  };
91
177
  }
92
- if (data.contactSheetPath !== undefined && (typeof data.contactSheetPath !== "string" || !isAbsolute(data.contactSheetPath)))
93
- return undefined;
94
- if (data.recordingId !== undefined && (typeof data.recordingId !== "string" || !data.recordingId))
95
- return undefined;
96
- if (data.startedAtMs !== undefined && (typeof data.startedAtMs !== "number" || !Number.isFinite(data.startedAtMs)))
97
- return undefined;
98
- if (typeof data.absolutePath !== "string" || !isAbsolute(data.absolutePath)
99
- || typeof data.cwd !== "string" || !isAbsolute(data.cwd) || typeof data.path !== "string")
100
- return undefined;
101
- return {
102
- reservation: {
103
- absolutePath: data.absolutePath,
104
- ...(typeof data.contactSheetPath === "string" ? { contactSheetPath: data.contactSheetPath } : {}),
105
- cwd: data.cwd,
106
- namespace: data.namespace,
107
- path: data.path,
108
- ...(typeof data.recordingId === "string" ? { recordingId: data.recordingId } : {}),
109
- ...(typeof data.startedAtMs === "number" ? { startedAtMs: data.startedAtMs } : {}),
110
- sessionName: data.sessionName,
111
- },
112
- state: "active",
113
- };
178
+ const reservation = parseActiveReservation(data, {
179
+ sessionName: data.sessionName,
180
+ namespace: data.namespace,
181
+ });
182
+ return reservation ? { reservation, state: "active" } : undefined;
114
183
  }
115
184
  export function restoreRecordingReservationStateFromBranch(branch) {
116
185
  const reservations = new Map();
117
186
  const terminal = new Map();
118
187
  for (const entry of branch) {
119
- if (!isRecord(entry) || entry.type !== "custom" || entry.customType !== RECORDING_RESERVATION_ENTRY_TYPE)
188
+ if (!isRecord(entry) ||
189
+ entry.type !== "custom" ||
190
+ entry.customType !== RECORDING_RESERVATION_ENTRY_TYPE) {
120
191
  continue;
192
+ }
121
193
  const transition = parseReservationTransition(entry.data);
122
- if (!transition)
194
+ if (!transition) {
123
195
  continue;
196
+ }
124
197
  const key = getReservationKey(transition.reservation);
125
198
  if (transition.state === "active") {
126
199
  reservations.set(key, transition.reservation);
@@ -0,0 +1,75 @@
1
+ const SENSITIVE_FIELD_NAME_PATTERN = /^(?:[A-Za-z0-9_-]*(?:api[_-]?key|access[_-]?key|private[_-]?key|secret(?:[_-]?(?:key|access[_-]?key))?|token|password|passwd|credentials?|database[_-]?url|db[_-]?url|connection[_-]?string|mongo(?:db)?[_-]?uri|redis[_-]?url)|[A-Za-z0-9]*(?:apiKey|ApiKey|apikey|privateKey|PrivateKey|databaseUrl|DatabaseUrl|dbUrl|DbUrl|connectionString|ConnectionString|mongoUri|MongoUri|mongodbUri|MongodbUri|mongoDbUri|MongoDbUri|redisUrl|RedisUrl|Token|Secret|Password|Credential|Credentials)|auth(?:orization)?|bearer|client(?:_|-)?secret|cookie|id(?:_|-)?token|pass(?:word)?|proxy(?:_|-)?authorization|refresh(?:_|-)?token|sentry(?:_|-)?key|session(?:_|-)?id|set(?:_|-)?cookie|sig(?:nature)?|write(?:_|-)?key|x(?:_|-)?api(?:_|-)?key)$/i;
2
+ const ENV_SECRET_ASSIGNMENT_PATTERN = /\b((?:export\s+)?([A-Za-z_][A-Za-z0-9_-]*)(\s*[:=]\s*))(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;]+)/g;
3
+ export function isSensitiveFieldName(key) {
4
+ SENSITIVE_FIELD_NAME_PATTERN.lastIndex = 0;
5
+ return SENSITIVE_FIELD_NAME_PATTERN.test(key);
6
+ }
7
+ function isEnvSecretAssignmentKey(key) {
8
+ if (!isSensitiveFieldName(key)) {
9
+ return false;
10
+ }
11
+ if (key === "password" || key.includes("_") || key.includes("-") || key === key.toUpperCase()) {
12
+ return true;
13
+ }
14
+ return /(?:apiKey|ApiKey|privateKey|PrivateKey|databaseUrl|DatabaseUrl|dbUrl|DbUrl|connectionString|ConnectionString|mongoUri|MongoUri|mongodbUri|MongodbUri|mongoDbUri|MongoDbUri|redisUrl|RedisUrl|Token|Secret|Password|Credential|Credentials)$/.test(key);
15
+ }
16
+ function isLineBoundary(text, index) {
17
+ return index < 0 || index >= text.length || text[index] === "\n" || text[index] === "\r";
18
+ }
19
+ function redactPasswordAssignment(text, match, prefix, offset) {
20
+ // The loose matcher cannot safely distinguish inline punctuation from password characters.
21
+ const end = offset + match.length;
22
+ if (!isLineBoundary(text, offset - 1) ||
23
+ !isLineBoundary(text, end) ||
24
+ /^(?:\[REDACTED\]|%5Bredacted%5D)/i.test(match.slice(prefix.length))) {
25
+ return match;
26
+ }
27
+ const value = match.slice(prefix.length);
28
+ const boundary = value[0] === '"' || value[0] === "'" ? -1 : value.search(/[&#](?=[A-Za-z_][A-Za-z0-9_-]*\s*=)/);
29
+ return `${prefix}[REDACTED]${boundary < 0 ? "" : value.slice(boundary)}`;
30
+ }
31
+ export function redactEnvSecretAssignments(text) {
32
+ return text.replace(ENV_SECRET_ASSIGNMENT_PATTERN,
33
+ // String.replace supplies match, three captures, then the source offset.
34
+ (match, prefix, key, _separator, offset) => {
35
+ if (!isEnvSecretAssignmentKey(key)) {
36
+ return match;
37
+ }
38
+ return key === "password"
39
+ ? redactPasswordAssignment(text, match, prefix, offset)
40
+ : `${prefix}[REDACTED]`;
41
+ });
42
+ }
43
+ function credentialTrailingPunctuation(credential) {
44
+ return credential.match(/[,.:;!?]+$/)?.[0] ?? "";
45
+ }
46
+ function formatRedactedCredential(label, credential, trailing = "") {
47
+ return `${label} [REDACTED]${credentialTrailingPunctuation(credential)}${trailing}`;
48
+ }
49
+ export function redactBearerCredentials(text) {
50
+ return text
51
+ .replace(/((?:\b([A-Za-z][A-Za-z0-9_-]*)\s*[:=]\s*|(?:^|\s)(?:-H\s*|--header(?:\s+|=)))["']?Bearer)\s+([^\s"',)[\]]+)([),.]?)/gi,
52
+ // String.replace supplies the match followed by this expression's four captures.
53
+ (match, label, field, credential, trailing) => {
54
+ if (field !== undefined && field.length > 0 && !isSensitiveFieldName(field)) {
55
+ return match;
56
+ }
57
+ return formatRedactedCredential(label, credential, trailing);
58
+ })
59
+ .replace(/\b(Bearer)\s+([^\s\\"',)[\]]+)([),.]?)/gi, (match, label, credential, trailing) => {
60
+ // Require a bearer-token shape without a credential field/header, not prose, HTML or a URL.
61
+ const token = credential.slice(0, credential.length - credentialTrailingPunctuation(credential).length);
62
+ if (!/^[A-Za-z0-9._~+/-]+=*$/.test(token) || !/[0-9._~+/=-]/.test(token)) {
63
+ return match;
64
+ }
65
+ return formatRedactedCredential(label, credential, trailing);
66
+ });
67
+ }
68
+ export function redactStandaloneBasicCredential(text) {
69
+ return text.replace(/\b(Basic)\s+([A-Za-z0-9+/=]{12,})/gi, (match, label, credential) => {
70
+ if (!/[0-9+/=]/.test(credential)) {
71
+ return match;
72
+ }
73
+ return `${label} [REDACTED]`;
74
+ });
75
+ }
@@ -0,0 +1,149 @@
1
+ import { isSensitiveFieldName } from "./redaction-fields.js";
2
+ function nextQuotePosition(options) {
3
+ // Inside a string, backslash skips one character; outside, it is ordinary text.
4
+ if (options.char === '"') {
5
+ return options.index;
6
+ }
7
+ return options.char === "\\" ? options.quoteAfterNext : options.quoteAtNext;
8
+ }
9
+ function buildJsonBoundaries(text) {
10
+ // Resolve each suffix once: skip strings and balanced groups to its first unmatched closer.
11
+ const boundaries = new Int32Array(text.length + 1).fill(-1);
12
+ let quoteAtNext = -1;
13
+ let quoteAfterNext = -1;
14
+ for (let index = text.length - 1; index >= 0; index -= 1) {
15
+ const char = text[index];
16
+ switch (char) {
17
+ case "}":
18
+ case "]":
19
+ boundaries[index] = index;
20
+ break;
21
+ case '"':
22
+ boundaries[index] = quoteAtNext < 0 ? -1 : boundaries[quoteAtNext + 1];
23
+ break;
24
+ case "{":
25
+ case "[": {
26
+ const end = boundaries[index + 1];
27
+ boundaries[index] =
28
+ end >= 0 && text[end] === (char === "{" ? "}" : "]") ? boundaries[end + 1] : -1;
29
+ break;
30
+ }
31
+ default:
32
+ boundaries[index] = boundaries[index + 1];
33
+ }
34
+ const quote = nextQuotePosition({ char, index, quoteAtNext, quoteAfterNext });
35
+ quoteAfterNext = quoteAtNext;
36
+ quoteAtNext = quote;
37
+ }
38
+ return boundaries;
39
+ }
40
+ function createBalancedJsonEndFinder(text) {
41
+ let boundaries;
42
+ return (startIndex) => {
43
+ const opener = text[startIndex];
44
+ if (opener !== "{" && opener !== "[") {
45
+ return;
46
+ }
47
+ boundaries ??= buildJsonBoundaries(text);
48
+ const end = boundaries[startIndex + 1];
49
+ return end >= 0 && text[end] === (opener === "{" ? "}" : "]") ? end : undefined;
50
+ };
51
+ }
52
+ function parseJsonString(token) {
53
+ const value = JSON.parse(token);
54
+ if (typeof value !== "string") {
55
+ throw new Error("Expected a JSON string token");
56
+ }
57
+ return value;
58
+ }
59
+ function isSerializedJson(text) {
60
+ if (text === "[REDACTED]" || !/^\s*[[{"\d\-tfn]/.test(text)) {
61
+ return false;
62
+ }
63
+ // Validate grammar only; rebuilding parsed values loses duplicates and numeric spelling.
64
+ try {
65
+ JSON.parse(text);
66
+ return true;
67
+ }
68
+ catch {
69
+ return false;
70
+ }
71
+ }
72
+ function findJsonValueEnd(text, start, findEnd) {
73
+ const balancedEnd = findEnd(start);
74
+ if (balancedEnd !== undefined) {
75
+ return balancedEnd + 1;
76
+ }
77
+ if (text[start] === '"') {
78
+ const strings = /"(?:\\.|[^"\\])*"/g;
79
+ strings.lastIndex = start;
80
+ const fieldValue = strings.exec(text);
81
+ if (fieldValue === null) {
82
+ throw new Error("Expected a validated JSON string field value");
83
+ }
84
+ return parseJsonString(fieldValue[0]) === "[REDACTED]" ? undefined : strings.lastIndex;
85
+ }
86
+ let end = start;
87
+ while (end < text.length && !/[\s,\]}]/.test(text[end])) {
88
+ end += 1;
89
+ }
90
+ return end;
91
+ }
92
+ export function redactSerializedJson(text, redact) {
93
+ if (!isSerializedJson(text)) {
94
+ return;
95
+ }
96
+ let output = "";
97
+ let cursor = 0;
98
+ const findEnd = createBalancedJsonEndFinder(text);
99
+ const strings = /"(?:\\.|[^"\\])*"/g;
100
+ let match;
101
+ while ((match = strings.exec(text)) !== null) {
102
+ const end = strings.lastIndex;
103
+ const value = parseJsonString(match[0]);
104
+ const redacted = redact(value);
105
+ if (redacted !== value) {
106
+ output += text.slice(cursor, match.index) + JSON.stringify(redacted);
107
+ cursor = end;
108
+ }
109
+ const separator = /^\s*:\s*/.exec(text.slice(end));
110
+ if (separator === null || !isSensitiveFieldName(value)) {
111
+ continue;
112
+ }
113
+ const valueStart = end + separator[0].length;
114
+ const valueEnd = findJsonValueEnd(text, valueStart, findEnd);
115
+ if (valueEnd === undefined) {
116
+ // Skip the already-redacted string as the original scanner did.
117
+ strings.lastIndex = valueStart;
118
+ strings.exec(text);
119
+ continue;
120
+ }
121
+ output += text.slice(cursor, valueStart) + '"[REDACTED]"';
122
+ cursor = valueEnd;
123
+ strings.lastIndex = valueEnd;
124
+ }
125
+ return output + text.slice(cursor);
126
+ }
127
+ export function redactEmbeddedStructuredText(text, redact) {
128
+ let output = "";
129
+ let cursor = 0;
130
+ const findEnd = createBalancedJsonEndFinder(text);
131
+ while (cursor < text.length) {
132
+ const char = text[cursor];
133
+ if (char !== "{" && char !== "[") {
134
+ output += char;
135
+ cursor += 1;
136
+ continue;
137
+ }
138
+ const endIndex = findEnd(cursor);
139
+ if (endIndex === undefined) {
140
+ output += char;
141
+ cursor += 1;
142
+ continue;
143
+ }
144
+ const candidate = text.slice(cursor, endIndex + 1);
145
+ output += redactSerializedJson(candidate, redact) ?? candidate;
146
+ cursor = endIndex + 1;
147
+ }
148
+ return output;
149
+ }