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
@@ -0,0 +1,167 @@
1
+ import { rm } from "node:fs/promises";
2
+ import { acquireManagedSessionPolicyLock, } from "../../managed-session-policy-lock.js";
3
+ import { pruneOwnedManagedSessionRestoreSnapshots, } from "../../managed-session-restore.js";
4
+ import { isManagedSessionRestoreKey } from "../../managed-session-storage.js";
5
+ import { isRecord } from "../../parsing.js";
6
+ import { withAgentBrowserProcessEnvironment } from "../../process-environment.js";
7
+ import { runAgentBrowserProcess } from "../../process.js";
8
+ import { getAgentBrowserErrorText, parseAgentBrowserEnvelope } from "../../results/envelope.js";
9
+ import { detectConfirmationRequired } from "../../results/confirmation.js";
10
+ import { stringifyUnknown } from "../../results/text.js";
11
+ import { redactInvocationArgs } from "../../runtime-redaction.js";
12
+ import { getHeadedManagedAutosaveEnv, inspectManagedSessionDaemon, } from "./managed-session-daemon-inspection.js";
13
+ function getCloseArgs(options) {
14
+ return [
15
+ ...(options.namespace !== undefined ? ["--namespace", options.namespace] : []),
16
+ "--session",
17
+ options.sessionName,
18
+ "close",
19
+ ];
20
+ }
21
+ async function inspectCloseRestoreKey(options, signal) {
22
+ const daemon = await inspectManagedSessionDaemon({
23
+ cwd: options.cwd,
24
+ headedManagedAutosaveInterval: options.headedManagedAutosaveInterval,
25
+ namespace: options.namespace,
26
+ preserveAttachedBrowserSession: options.preserveAttachedBrowserSession,
27
+ sessionName: options.sessionName,
28
+ signal,
29
+ timeoutMs: Math.min(options.timeoutMs, 2_000),
30
+ });
31
+ if (daemon.status === "active") {
32
+ options.restoreState.recordDaemonRestoreKey(options.sessionName, options.namespace, daemon.restoreKey);
33
+ }
34
+ const daemonRestoreKey = options.restoreState.getDaemonRestoreKey(options.sessionName, options.namespace);
35
+ return !options.restoreState.isDisabled(options.sessionName, options.namespace) &&
36
+ isManagedSessionRestoreKey(daemonRestoreKey)
37
+ ? daemonRestoreKey
38
+ : null;
39
+ }
40
+ function confirmedClosedData(processResult, envelope) {
41
+ return !processResult.aborted &&
42
+ !processResult.spawnError &&
43
+ processResult.exitCode === 0 &&
44
+ envelope?.success === true &&
45
+ isRecord(envelope.data) &&
46
+ envelope.data.closed === true
47
+ ? envelope.data
48
+ : undefined;
49
+ }
50
+ async function finishManagedClose(options, processResult, ownedRestoreKey) {
51
+ const parsed = await parseAgentBrowserEnvelope({
52
+ stdout: processResult.stdout,
53
+ stdoutPath: processResult.stdoutSpillPath,
54
+ });
55
+ const closedData = confirmedClosedData(processResult, parsed.envelope);
56
+ if (closedData) {
57
+ options.restoreState.clear(options.sessionName, options.namespace);
58
+ pruneOwnedManagedSessionRestoreSnapshots({
59
+ cwd: options.cwd,
60
+ namespace: options.namespace,
61
+ restoreKey: ownedRestoreKey,
62
+ statePath: typeof closedData.statePath === "string" ? closedData.statePath : undefined,
63
+ });
64
+ }
65
+ const pending = detectConfirmationRequired(parsed.envelope?.data);
66
+ if (pending) {
67
+ return `Native close requires confirmation (${pending.id}); the session remains wrapper-owned.`;
68
+ }
69
+ return getAgentBrowserErrorText({
70
+ aborted: processResult.aborted,
71
+ command: "close",
72
+ effectiveArgs: redactInvocationArgs(getCloseArgs(options)),
73
+ envelope: parsed.envelope,
74
+ exitCode: processResult.exitCode,
75
+ parseError: parsed.parseError,
76
+ plainTextInspection: false,
77
+ spawnError: processResult.spawnError,
78
+ stderr: processResult.stderr,
79
+ timedOut: processResult.timedOut,
80
+ timeoutMs: processResult.timeoutMs,
81
+ });
82
+ }
83
+ async function closeUnderPolicy(options, lifecycle) {
84
+ lifecycle.enterPhase("daemon inspection");
85
+ const ownedRestoreKey = await inspectCloseRestoreKey(options, lifecycle.signal);
86
+ lifecycle.enterPhase("native close");
87
+ const processResult = await runAgentBrowserProcess({
88
+ args: getCloseArgs(options),
89
+ cwd: options.cwd,
90
+ env: {
91
+ AGENT_BROWSER_JSON: "1",
92
+ ...getHeadedManagedAutosaveEnv(options.headedManagedAutosaveInterval),
93
+ },
94
+ managedSessionRestoreState: options.restoreState,
95
+ ownedManagedSession: true,
96
+ preserveAttachedBrowserSession: options.preserveAttachedBrowserSession,
97
+ signal: lifecycle.signal,
98
+ });
99
+ lifecycle.clearTimer();
100
+ try {
101
+ return await finishManagedClose(options, processResult, ownedRestoreKey);
102
+ }
103
+ finally {
104
+ if (processResult.stdoutSpillPath !== undefined && processResult.stdoutSpillPath !== "") {
105
+ await rm(processResult.stdoutSpillPath, { force: true }).catch(() => {
106
+ // A spill removal failure must not replace the native close result.
107
+ });
108
+ }
109
+ }
110
+ }
111
+ async function closeWithDeadline(options) {
112
+ const controller = new AbortController();
113
+ let phase = "policy coordination";
114
+ let phaseStartedAt = Date.now();
115
+ let timeoutError;
116
+ const timer = setTimeout(() => {
117
+ timeoutError = `Managed-session cleanup timed out after ${options.timeoutMs} ms during ${phase} (${Date.now() - phaseStartedAt} ms in this phase).`;
118
+ controller.abort();
119
+ }, options.timeoutMs);
120
+ const lifecycle = {
121
+ signal: controller.signal,
122
+ enterPhase: (nextPhase) => {
123
+ phase = nextPhase;
124
+ phaseStartedAt = Date.now();
125
+ },
126
+ clearTimer: () => {
127
+ clearTimeout(timer);
128
+ },
129
+ };
130
+ let policyLock;
131
+ try {
132
+ policyLock =
133
+ options.policyLock ??
134
+ (await acquireManagedSessionPolicyLock({
135
+ namespace: options.namespace,
136
+ sessionName: options.sessionName,
137
+ signal: controller.signal,
138
+ timeoutMs: Math.min(options.timeoutMs, 1_000),
139
+ }));
140
+ if (!policyLock) {
141
+ return (timeoutError ??
142
+ "Managed-session policy coordination is unavailable or busy; cleanup did not run. Retry after the current operation finishes or repair the private policy-lock directory.");
143
+ }
144
+ try {
145
+ const closeError = await closeUnderPolicy(options, lifecycle);
146
+ // The deadline callback can update timeoutError while any close phase is suspended.
147
+ return timeoutError ?? closeError;
148
+ }
149
+ catch (error) {
150
+ return timeoutError ?? (error instanceof Error ? error.message : stringifyUnknown(error));
151
+ }
152
+ }
153
+ finally {
154
+ clearTimeout(timer);
155
+ if (options.policyLock === undefined && policyLock) {
156
+ await policyLock.release();
157
+ }
158
+ }
159
+ }
160
+ export function closeManagedSession(options) {
161
+ return withAgentBrowserProcessEnvironment({
162
+ AGENT_BROWSER_CONFIRM_ACTIONS: options.confirmActions,
163
+ ...(options.socketDir !== undefined && options.socketDir !== ""
164
+ ? { PI_AGENT_BROWSER_SOCKET_DIR: options.socketDir }
165
+ : {}),
166
+ }, () => closeWithDeadline(options));
167
+ }
@@ -0,0 +1,108 @@
1
+ import { rm } from "node:fs/promises";
2
+ import { isRecord } from "../../parsing.js";
3
+ import { resolveExplicitAutosaveInterval } from "../../managed-session-restore.js";
4
+ import { getAgentBrowserProcessEnvironment } from "../../process-environment.js";
5
+ import { readProcessStartIdentity } from "../../process-identity.js";
6
+ import { runAgentBrowserProcess } from "../../process.js";
7
+ import { parseAgentBrowserEnvelope } from "../../results/envelope.js";
8
+ const MANAGED_SESSION_DAEMON_INSPECTION_TIMEOUT_MS = 35_000;
9
+ const RUNNING_HEADED_AUTOSAVE_POLICY_CHANGE_ERROR = 'AGENT_BROWSER_AUTOSAVE_INTERVAL_MS cannot change a running wrapper-owned headed session\'s launch-time periodic autosave interval. Close that session first, then retry with sessionMode: "fresh" so the new daemon starts with the requested interval.';
10
+ export function getRunningHeadedAutosavePolicyChangeError(recordedInterval, closeCommand = false) {
11
+ const explicitInterval = resolveExplicitAutosaveInterval(getAgentBrowserProcessEnvironment().AGENT_BROWSER_AUTOSAVE_INTERVAL_MS);
12
+ return recordedInterval !== undefined &&
13
+ !closeCommand &&
14
+ explicitInterval !== undefined &&
15
+ explicitInterval !== recordedInterval
16
+ ? RUNNING_HEADED_AUTOSAVE_POLICY_CHANGE_ERROR
17
+ : undefined;
18
+ }
19
+ export function getHeadedManagedAutosaveEnv(interval) {
20
+ return interval !== undefined ? { AGENT_BROWSER_AUTOSAVE_INTERVAL_MS: interval } : undefined;
21
+ }
22
+ async function readDaemonGeneration(runtime, options) {
23
+ if (options.includeGeneration !== true ||
24
+ typeof runtime.backgroundPid !== "number" ||
25
+ !Number.isSafeInteger(runtime.backgroundPid) ||
26
+ runtime.backgroundPid <= 0 ||
27
+ typeof runtime.socketDir !== "string" ||
28
+ runtime.browserLaunched === false) {
29
+ return undefined;
30
+ }
31
+ const start = await readProcessStartIdentity(runtime.backgroundPid, process.platform, {
32
+ signal: options.signal,
33
+ deadline: Date.now() + (options.timeoutMs ?? 5_000),
34
+ });
35
+ return start !== undefined && start !== ""
36
+ ? JSON.stringify({
37
+ pid: runtime.backgroundPid,
38
+ start,
39
+ socketDir: runtime.socketDir,
40
+ })
41
+ : undefined;
42
+ }
43
+ async function parseDaemonInspection(data, options) {
44
+ if (!isRecord(data) || typeof data.active !== "boolean") {
45
+ return { status: "unknown" };
46
+ }
47
+ if (!data.active) {
48
+ return { status: "inactive" };
49
+ }
50
+ if (!isRecord(data.runtime)) {
51
+ return { status: "unknown" };
52
+ }
53
+ const generation = await readDaemonGeneration(data.runtime, options);
54
+ if (typeof data.runtime.restoreKey === "string" && data.runtime.restoreKey.length > 0) {
55
+ return { restoreKey: data.runtime.restoreKey, status: "active", generation };
56
+ }
57
+ return data.runtime.restoreKey === null
58
+ ? { restoreKey: null, status: "active", generation }
59
+ : { status: "unknown" };
60
+ }
61
+ function daemonProcessFailure(processResult) {
62
+ if (processResult.spawnError &&
63
+ "code" in processResult.spawnError &&
64
+ processResult.spawnError.code === "ENOENT") {
65
+ return { status: "missing-binary" };
66
+ }
67
+ return processResult.aborted || processResult.spawnError || processResult.exitCode !== 0
68
+ ? { status: "unknown" }
69
+ : undefined;
70
+ }
71
+ async function readDaemonInfo(processResult) {
72
+ const parsed = await parseAgentBrowserEnvelope({
73
+ stdout: processResult.stdout,
74
+ stdoutPath: processResult.stdoutSpillPath,
75
+ });
76
+ return (parsed.parseError ?? "") !== "" || parsed.envelope?.success === false
77
+ ? undefined
78
+ : parsed.envelope?.data;
79
+ }
80
+ export async function inspectManagedSessionDaemon(options) {
81
+ const processResult = await runAgentBrowserProcess({
82
+ args: [
83
+ "--json",
84
+ "--namespace",
85
+ options.namespace ?? "",
86
+ "--session",
87
+ options.sessionName,
88
+ "session",
89
+ "info",
90
+ ],
91
+ cwd: options.cwd,
92
+ env: getHeadedManagedAutosaveEnv(options.headedManagedAutosaveInterval),
93
+ preserveAttachedBrowserSession: options.preserveAttachedBrowserSession,
94
+ signal: options.signal,
95
+ timeoutMs: options.timeoutMs ?? MANAGED_SESSION_DAEMON_INSPECTION_TIMEOUT_MS,
96
+ });
97
+ try {
98
+ const failure = daemonProcessFailure(processResult);
99
+ return failure ?? (await parseDaemonInspection(await readDaemonInfo(processResult), options));
100
+ }
101
+ finally {
102
+ if (processResult.stdoutSpillPath !== undefined && processResult.stdoutSpillPath !== "") {
103
+ await rm(processResult.stdoutSpillPath, { force: true }).catch(() => {
104
+ // Spill cleanup is best-effort and must not change the daemon inspection result.
105
+ });
106
+ }
107
+ }
108
+ }
@@ -1,93 +1,147 @@
1
- import { rm } from "node:fs/promises";
2
1
  import { getAgentBrowserSessionIdentityKey } from "../../argv-grammar.js";
3
2
  import { inspectElectronLaunchStatus } from "../../electron/cleanup.js";
4
- import { acquireManagedSessionPolicyLock } from "../../managed-session-policy-lock.js";
5
- import { pruneOwnedManagedSessionRestoreSnapshots, resolveExplicitAutosaveInterval, withOwnedManagedSessionContext, } from "../../managed-session-restore.js";
6
- import { isManagedSessionRestoreKey } from "../../managed-session-storage.js";
3
+ import { acquireManagedSessionPolicyLock, } from "../../managed-session-policy-lock.js";
4
+ import { withOwnedManagedSessionContext, } from "../../managed-session-restore.js";
7
5
  import { isRecord } from "../../parsing.js";
8
- import { readProcessStartIdentity } from "../../process-identity.js";
9
- import { getAgentBrowserProcessEnvironment, withAgentBrowserProcessEnvironment } from "../../process-environment.js";
10
- import { runAgentBrowserProcess, withAttachedBrowserSessionContext } from "../../process.js";
11
- import { getAgentBrowserErrorText, parseAgentBrowserEnvelope } from "../../results/envelope.js";
12
- import { redactInvocationArgs } from "../../runtime.js";
6
+ import { withAttachedBrowserSessionContext } from "../../process.js";
13
7
  import { runSessionCommandData } from "./session-state.js";
14
- const MANAGED_SESSION_DAEMON_INSPECTION_TIMEOUT_MS = 35_000;
15
- const RUNNING_HEADED_AUTOSAVE_POLICY_CHANGE_ERROR = "AGENT_BROWSER_AUTOSAVE_INTERVAL_MS cannot change a running wrapper-owned headed session's launch-time periodic autosave interval. Close that session first, then retry with sessionMode: \"fresh\" so the new daemon starts with the requested interval.";
16
- export function getRunningHeadedAutosavePolicyChangeError(recordedInterval, closeCommand = false) {
17
- const explicitInterval = resolveExplicitAutosaveInterval(getAgentBrowserProcessEnvironment().AGENT_BROWSER_AUTOSAVE_INTERVAL_MS);
18
- return recordedInterval !== undefined && !closeCommand && explicitInterval !== undefined && explicitInterval !== recordedInterval
19
- ? RUNNING_HEADED_AUTOSAVE_POLICY_CHANGE_ERROR
20
- : undefined;
8
+ import { getHeadedManagedAutosaveEnv, inspectManagedSessionDaemon, } from "./managed-session-daemon-inspection.js";
9
+ export { closeManagedSession } from "./managed-session-close.js";
10
+ export { getRunningHeadedAutosavePolicyChangeError, inspectManagedSessionDaemon, } from "./managed-session-daemon-inspection.js";
11
+ function hasElectronAttachmentIdentity(record) {
12
+ return (record.webSocketDebuggerUrl !== undefined &&
13
+ record.webSocketDebuggerUrl !== "" &&
14
+ record.sessionName !== undefined &&
15
+ record.sessionName !== "");
21
16
  }
22
- function getHeadedManagedAutosaveEnv(interval) {
23
- return interval !== undefined ? { AGENT_BROWSER_AUTOSAVE_INTERVAL_MS: interval } : undefined;
24
- }
25
- export async function inspectManagedSessionDaemon(options) {
26
- const processResult = await runAgentBrowserProcess({
27
- args: ["--json", "--namespace", options.namespace ?? "", "--session", options.sessionName, "session", "info"],
28
- cwd: options.cwd,
29
- env: getHeadedManagedAutosaveEnv(options.headedManagedAutosaveInterval),
30
- preserveAttachedBrowserSession: options.preserveAttachedBrowserSession,
31
- signal: options.signal,
32
- timeoutMs: options.timeoutMs ?? MANAGED_SESSION_DAEMON_INSPECTION_TIMEOUT_MS,
33
- });
34
- try {
35
- if (processResult.spawnError?.code === "ENOENT")
36
- return { status: "missing-binary" };
37
- if (processResult.aborted || processResult.spawnError || processResult.exitCode !== 0)
38
- return { status: "unknown" };
39
- const parsed = await parseAgentBrowserEnvelope({ stdout: processResult.stdout, stdoutPath: processResult.stdoutSpillPath });
40
- const data = parsed.parseError || parsed.envelope?.success === false ? undefined : parsed.envelope?.data;
41
- if (!isRecord(data) || typeof data.active !== "boolean")
42
- return { status: "unknown" };
43
- if (!data.active)
44
- return { status: "inactive" };
45
- if (!isRecord(data.runtime))
46
- return { status: "unknown" };
47
- let generation;
48
- if (options.includeGeneration && Number.isSafeInteger(data.runtime.backgroundPid) && Number(data.runtime.backgroundPid) > 0
49
- && typeof data.runtime.socketDir === "string" && data.runtime.browserLaunched !== false) {
50
- const start = await readProcessStartIdentity(Number(data.runtime.backgroundPid), process.platform, { signal: options.signal, deadline: Date.now() + (options.timeoutMs ?? 5_000) });
51
- if (start)
52
- generation = JSON.stringify({ pid: data.runtime.backgroundPid, start, socketDir: data.runtime.socketDir });
53
- }
54
- if (typeof data.runtime.restoreKey === "string" && data.runtime.restoreKey.length > 0)
55
- return { restoreKey: data.runtime.restoreKey, status: "active", generation };
56
- return data.runtime.restoreKey === null ? { restoreKey: null, status: "active", generation } : { status: "unknown" };
17
+ function restoredAttachmentTarget(context, record) {
18
+ const cwd = context.cwd;
19
+ if (cwd === undefined || cwd === "" || !record || !hasElectronAttachmentIdentity(record)) {
20
+ return undefined;
57
21
  }
58
- finally {
59
- if (processResult.stdoutSpillPath)
60
- await rm(processResult.stdoutSpillPath, { force: true }).catch(() => undefined);
22
+ if (record.cleanupState === "cleaned" ||
23
+ getAgentBrowserSessionIdentityKey(record.sessionName ?? "", record.namespace) !==
24
+ getAgentBrowserSessionIdentityKey(context.sessionName, context.namespace)) {
25
+ return undefined;
61
26
  }
27
+ return { cwd, record };
62
28
  }
63
- async function verifyRestoredElectronAttachment(context, record, signal, timeoutMs) {
64
- const cwd = context.cwd;
65
- if (!cwd || !record?.webSocketDebuggerUrl || !record.sessionName || record.cleanupState === "cleaned"
66
- || getAgentBrowserSessionIdentityKey(record.sessionName, record.namespace) !== getAgentBrowserSessionIdentityKey(context.sessionName, context.namespace))
29
+ function attachmentStatusMatches(record, status) {
30
+ return (status.pidAlive === true &&
31
+ status.userDataDirState === "present" &&
32
+ status.version?.webSocketDebuggerUrl === record.webSocketDebuggerUrl);
33
+ }
34
+ function attachmentConnectionMatches(connection, record, status) {
35
+ return (isRecord(connection) &&
36
+ typeof connection.cdpUrl === "string" &&
37
+ (connection.cdpUrl === record.webSocketDebuggerUrl ||
38
+ status.targets.some((target) => target.webSocketDebuggerUrl === connection.cdpUrl)));
39
+ }
40
+ async function verifyRestoredElectronAttachment(options) {
41
+ const { context, signal } = options;
42
+ const attachment = restoredAttachmentTarget(context, options.electronLaunchRecord);
43
+ if (!attachment) {
67
44
  return false;
68
- const status = await inspectElectronLaunchStatus(record, signal);
69
- if (signal?.aborted || status.pidAlive !== true || status.userDataDirState !== "present"
70
- || status.version?.webSocketDebuggerUrl !== record.webSocketDebuggerUrl)
45
+ }
46
+ const status = await inspectElectronLaunchStatus(attachment.record, signal);
47
+ if (signal?.aborted === true || !attachmentStatusMatches(attachment.record, status)) {
71
48
  return false;
49
+ }
72
50
  // This metadata probe must not grant daemon provenance just by spawning.
73
51
  const connection = await withAttachedBrowserSessionContext(true, () => withOwnedManagedSessionContext(undefined, () => runSessionCommandData({
74
- args: ["get", "cdp-url"], cwd, env: getHeadedManagedAutosaveEnv(context.headedManagedAutosaveInterval), namespace: context.namespace, pinNamespace: true,
75
- sessionName: context.sessionName, signal, timeoutMs,
52
+ args: ["get", "cdp-url"],
53
+ cwd: attachment.cwd,
54
+ env: getHeadedManagedAutosaveEnv(context.headedManagedAutosaveInterval),
55
+ namespace: context.namespace,
56
+ pinNamespace: true,
57
+ sessionName: context.sessionName,
58
+ signal,
59
+ timeoutMs: options.electronVerificationTimeoutMs,
76
60
  })));
77
- return !signal?.aborted && isRecord(connection) && typeof connection.cdpUrl === "string"
78
- && (connection.cdpUrl === record.webSocketDebuggerUrl || status.targets.some((target) => target.webSocketDebuggerUrl === connection.cdpUrl));
61
+ return (
62
+ // The abort callback can change this signal during the awaited CDP read; static narrowing does not model it.
63
+ // oxlint-disable-next-line typescript/no-unnecessary-condition
64
+ !(signal?.aborted ?? false) &&
65
+ attachmentConnectionMatches(connection, attachment.record, status));
66
+ }
67
+ function reconcileDaemonReceipt(context, daemon, receipt) {
68
+ if (daemon.status === "inactive") {
69
+ context.restoreState.forgetDaemonRestoreKey(context.sessionName, context.namespace);
70
+ }
71
+ if (daemon.status !== "active" ||
72
+ receipt === undefined ||
73
+ context.restoreState.hasDaemonRestoreKey(context.sessionName, context.namespace)) {
74
+ return;
75
+ }
76
+ if (daemon.generation === receipt.generation && daemon.restoreKey === receipt.restoreKey) {
77
+ context.restoreState.recordDaemonRestoreKey(context.sessionName, context.namespace, daemon.restoreKey, daemon.generation);
78
+ }
79
+ else {
80
+ context.restoreState.forgetDaemonRestoreKey(context.sessionName, context.namespace);
81
+ }
82
+ }
83
+ function daemonPolicyMismatch(daemon, restoreDisabledPolicyNeedsProvenance, hasKnownDaemonRestoreKey) {
84
+ return {
85
+ cleanupOnlyReason: daemon.status === "active" &&
86
+ restoreDisabledPolicyNeedsProvenance &&
87
+ !hasKnownDaemonRestoreKey
88
+ ? "restore-disabled-daemon-without-provenance"
89
+ : undefined,
90
+ daemonStatus: daemon.status,
91
+ error: [
92
+ "This wrapper-owned session's live daemon does not match the requested managed-restore policy.",
93
+ 'Close that session first, retry with sessionMode: "fresh", or use a distinct explicit --session.',
94
+ ].join(" "),
95
+ };
96
+ }
97
+ async function validateReusableDaemonPolicy(options, daemon) {
98
+ const { context } = options;
99
+ const stickyDisabled = context.restoreState.isDisabled(context.sessionName, context.namespace);
100
+ let hasKnownDaemonRestoreKey = context.restoreState.hasDaemonRestoreKey(context.sessionName, context.namespace);
101
+ const knownDaemonRestoreKey = context.restoreState.getDaemonRestoreKey(context.sessionName, context.namespace);
102
+ const requestedDaemonRestoreKey = context.restoreDecision === "enabled" && stickyDisabled
103
+ ? (knownDaemonRestoreKey ?? null)
104
+ : context.expectedDaemonRestoreKey;
105
+ if (daemon.status === "unknown") {
106
+ return {
107
+ error: 'The wrapper could not verify this managed session\'s live daemon restore policy. Retry, close that session, or use sessionMode: "fresh".',
108
+ };
109
+ }
110
+ const restoreDisabledPolicyNeedsProvenance = stickyDisabled || context.restoreDecision !== "enabled";
111
+ if (daemon.status === "active" &&
112
+ restoreDisabledPolicyNeedsProvenance &&
113
+ !hasKnownDaemonRestoreKey &&
114
+ daemon.restoreKey === requestedDaemonRestoreKey) {
115
+ hasKnownDaemonRestoreKey = await verifyRestoredElectronAttachment(options);
116
+ }
117
+ return finishReusableDaemonPolicy(context, daemon, {
118
+ restoreDisabledPolicyNeedsProvenance,
119
+ requestedDaemonRestoreKey,
120
+ }, hasKnownDaemonRestoreKey);
121
+ }
122
+ function finishReusableDaemonPolicy(context, daemon, policy, hasKnownDaemonRestoreKey) {
123
+ const activePolicyMatches = daemon.status === "active" &&
124
+ (!policy.restoreDisabledPolicyNeedsProvenance || hasKnownDaemonRestoreKey) &&
125
+ daemon.restoreKey === policy.requestedDaemonRestoreKey;
126
+ if (activePolicyMatches) {
127
+ context.restoreState.recordDaemonRestoreKey(context.sessionName, context.namespace, daemon.restoreKey);
128
+ }
129
+ return !["inactive", "missing-binary"].includes(daemon.status) && !activePolicyMatches
130
+ ? daemonPolicyMismatch(daemon, policy.restoreDisabledPolicyNeedsProvenance, hasKnownDaemonRestoreKey)
131
+ : { daemonStatus: daemon.status };
79
132
  }
80
133
  export async function acquireOwnedManagedSessionDaemonPolicy(options) {
81
134
  const { context, signal } = options;
82
- if (!context.cwd)
135
+ if (context.cwd === undefined || context.cwd === "") {
83
136
  return { error: "Managed-session policy validation requires the wrapper-owned session cwd." };
137
+ }
84
138
  const lock = await acquireManagedSessionPolicyLock({
85
139
  namespace: context.namespace,
86
140
  sessionName: context.sessionName,
87
141
  signal,
88
142
  });
89
143
  if (!lock) {
90
- return signal?.aborted
144
+ return signal?.aborted === true
91
145
  ? {}
92
146
  : {
93
147
  error: "Managed-session policy coordination is unavailable or busy. Retry after the current operation finishes, repair the private policy-lock directory, and on POSIX verify that /bin/ps, /usr/bin/ps, or ps through PATH is available.",
@@ -97,150 +151,24 @@ export async function acquireOwnedManagedSessionDaemonPolicy(options) {
97
151
  const receipt = context.restoreState.getDaemonReceipt(context.sessionName, context.namespace);
98
152
  const daemon = await inspectManagedSessionDaemon({
99
153
  cwd: context.cwd,
100
- includeGeneration: receipt !== undefined && !context.restoreState.hasDaemonRestoreKey(context.sessionName, context.namespace),
154
+ includeGeneration: receipt !== undefined &&
155
+ !context.restoreState.hasDaemonRestoreKey(context.sessionName, context.namespace),
101
156
  headedManagedAutosaveInterval: context.headedManagedAutosaveInterval,
102
157
  namespace: context.namespace,
103
158
  sessionName: context.sessionName,
104
159
  signal,
105
160
  });
106
- if (daemon.status === "inactive")
107
- context.restoreState.forgetDaemonRestoreKey(context.sessionName, context.namespace);
108
- if (daemon.status === "active" && receipt && !context.restoreState.hasDaemonRestoreKey(context.sessionName, context.namespace)) {
109
- if (daemon.generation === receipt.generation && daemon.restoreKey === receipt.restoreKey) {
110
- context.restoreState.recordDaemonRestoreKey(context.sessionName, context.namespace, daemon.restoreKey, daemon.generation);
111
- }
112
- else
113
- context.restoreState.forgetDaemonRestoreKey(context.sessionName, context.namespace);
114
- }
161
+ reconcileDaemonReceipt(context, daemon, receipt);
115
162
  if (options.mode === "close") {
116
- if (daemon.status === "active")
163
+ if (daemon.status === "active") {
117
164
  context.restoreState.recordDaemonRestoreKey(context.sessionName, context.namespace, daemon.restoreKey);
165
+ }
118
166
  return { daemonStatus: daemon.status, lock };
119
167
  }
120
- const stickyDisabled = context.restoreState.isDisabled(context.sessionName, context.namespace);
121
- let hasKnownDaemonRestoreKey = context.restoreState.hasDaemonRestoreKey(context.sessionName, context.namespace);
122
- const knownDaemonRestoreKey = context.restoreState.getDaemonRestoreKey(context.sessionName, context.namespace);
123
- const requestedDaemonRestoreKey = context.restoreDecision === "enabled" && stickyDisabled
124
- ? knownDaemonRestoreKey ?? null
125
- : context.expectedDaemonRestoreKey;
126
- if (daemon.status === "unknown") {
127
- return {
128
- error: "The wrapper could not verify this managed session's live daemon restore policy. Retry, close that session, or use sessionMode: \"fresh\".",
129
- lock,
130
- };
131
- }
132
- const restoreDisabledPolicyNeedsProvenance = stickyDisabled || context.restoreDecision !== "enabled";
133
- if (daemon.status === "active" && restoreDisabledPolicyNeedsProvenance && !hasKnownDaemonRestoreKey && daemon.restoreKey === requestedDaemonRestoreKey) {
134
- hasKnownDaemonRestoreKey = await verifyRestoredElectronAttachment(context, options.electronLaunchRecord, signal, options.electronVerificationTimeoutMs);
135
- }
136
- const activePolicyMatches = daemon.status === "active"
137
- && (!restoreDisabledPolicyNeedsProvenance || hasKnownDaemonRestoreKey)
138
- && daemon.restoreKey === requestedDaemonRestoreKey;
139
- if (activePolicyMatches)
140
- context.restoreState.recordDaemonRestoreKey(context.sessionName, context.namespace, daemon.restoreKey);
141
- return !["inactive", "missing-binary"].includes(daemon.status) && !activePolicyMatches
142
- ? {
143
- cleanupOnlyReason: daemon.status === "active" && restoreDisabledPolicyNeedsProvenance && !hasKnownDaemonRestoreKey
144
- ? "restore-disabled-daemon-without-provenance"
145
- : undefined,
146
- daemonStatus: daemon.status,
147
- error: [
148
- "This wrapper-owned session's live daemon does not match the requested managed-restore policy.",
149
- "Close that session first, retry with sessionMode: \"fresh\", or use a distinct explicit --session.",
150
- ].join(" "),
151
- lock,
152
- }
153
- : { daemonStatus: daemon.status, lock };
168
+ return { ...(await validateReusableDaemonPolicy(options, daemon)), lock };
154
169
  }
155
170
  catch (error) {
156
171
  await lock.release();
157
172
  throw error;
158
173
  }
159
174
  }
160
- export async function closeManagedSession(options) {
161
- return withAgentBrowserProcessEnvironment(options.socketDir ? { PI_AGENT_BROWSER_SOCKET_DIR: options.socketDir } : {}, async () => {
162
- const controller = new AbortController();
163
- let phase = "policy coordination";
164
- let phaseStartedAt = Date.now();
165
- let timeoutError;
166
- const timer = setTimeout(() => {
167
- timeoutError = `Managed-session cleanup timed out after ${options.timeoutMs} ms during ${phase} (${Date.now() - phaseStartedAt} ms in this phase).`;
168
- controller.abort();
169
- }, options.timeoutMs);
170
- let stdoutSpillPath;
171
- const closeArgs = [...(options.namespace !== undefined ? ["--namespace", options.namespace] : []), "--session", options.sessionName, "close"];
172
- const policyLock = options.policyLock ?? await acquireManagedSessionPolicyLock({
173
- namespace: options.namespace,
174
- sessionName: options.sessionName,
175
- signal: controller.signal,
176
- timeoutMs: Math.min(options.timeoutMs, 1_000),
177
- });
178
- if (!policyLock) {
179
- clearTimeout(timer);
180
- return timeoutError ?? "Managed-session policy coordination is unavailable or busy; cleanup did not run. Retry after the current operation finishes or repair the private policy-lock directory.";
181
- }
182
- try {
183
- phase = "daemon inspection";
184
- phaseStartedAt = Date.now();
185
- const daemon = await inspectManagedSessionDaemon({
186
- cwd: options.cwd,
187
- headedManagedAutosaveInterval: options.headedManagedAutosaveInterval,
188
- namespace: options.namespace,
189
- preserveAttachedBrowserSession: options.preserveAttachedBrowserSession,
190
- sessionName: options.sessionName,
191
- signal: controller.signal,
192
- timeoutMs: Math.min(options.timeoutMs, 2_000),
193
- });
194
- if (daemon.status === "active")
195
- options.restoreState.recordDaemonRestoreKey(options.sessionName, options.namespace, daemon.restoreKey);
196
- const daemonRestoreKey = options.restoreState.getDaemonRestoreKey(options.sessionName, options.namespace);
197
- const ownedRestoreKey = !options.restoreState.isDisabled(options.sessionName, options.namespace)
198
- && isManagedSessionRestoreKey(daemonRestoreKey) ? daemonRestoreKey : null;
199
- phase = "native close";
200
- phaseStartedAt = Date.now();
201
- const processResult = await runAgentBrowserProcess({
202
- args: closeArgs,
203
- cwd: options.cwd,
204
- env: { AGENT_BROWSER_JSON: "1", ...getHeadedManagedAutosaveEnv(options.headedManagedAutosaveInterval) },
205
- managedSessionRestoreState: options.restoreState,
206
- ownedManagedSession: true,
207
- preserveAttachedBrowserSession: options.preserveAttachedBrowserSession,
208
- signal: controller.signal,
209
- });
210
- clearTimeout(timer);
211
- stdoutSpillPath = processResult.stdoutSpillPath;
212
- if (!processResult.aborted && !processResult.spawnError && processResult.exitCode === 0) {
213
- const parsed = await parseAgentBrowserEnvelope({ stdout: processResult.stdout, stdoutPath: processResult.stdoutSpillPath });
214
- const data = parsed.envelope?.success === true && isRecord(parsed.envelope.data) ? parsed.envelope.data : undefined;
215
- options.restoreState.clear(options.sessionName, options.namespace);
216
- pruneOwnedManagedSessionRestoreSnapshots({
217
- cwd: options.cwd,
218
- namespace: options.namespace,
219
- restoreKey: ownedRestoreKey,
220
- statePath: typeof data?.statePath === "string" ? data.statePath : undefined,
221
- });
222
- }
223
- return timeoutError ?? getAgentBrowserErrorText({
224
- aborted: processResult.aborted,
225
- command: "close",
226
- effectiveArgs: redactInvocationArgs(closeArgs),
227
- exitCode: processResult.exitCode,
228
- plainTextInspection: false,
229
- spawnError: processResult.spawnError,
230
- stderr: processResult.stderr,
231
- timedOut: processResult.timedOut,
232
- timeoutMs: processResult.timeoutMs,
233
- });
234
- }
235
- catch (error) {
236
- return timeoutError ?? (error instanceof Error ? error.message : String(error));
237
- }
238
- finally {
239
- clearTimeout(timer);
240
- if (stdoutSpillPath)
241
- await rm(stdoutSpillPath, { force: true }).catch(() => undefined);
242
- if (!options.policyLock)
243
- await policyLock.release();
244
- }
245
- });
246
- }