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,323 +1,31 @@
1
1
  import { constants, openSync, closeSync, fstatSync } from "node:fs";
2
2
  import { open, stat } from "node:fs/promises";
3
- import { Readable, Writable } from "node:stream";
4
- import { pipeline } from "node:stream/promises";
5
- import parser from "stream-json/parser.js";
6
- import { BROWSER_TRANSITION_ENTRY, BROWSER_RESULT_TOOLS, applyArtifactChanges, getBrowserRecord, snapshotFromDefinition } from "./browser-transcript.js";
3
+ import { BROWSER_TRANSITION_ENTRY } from "./browser-transcript-contracts.js";
7
4
  import { isRecord } from "./parsing.js";
8
- const CHUNK_BYTES = 64 * 1024;
9
- const ENVELOPE_MAX_BYTES = 16 * 1024 * 1024;
10
- function selectedPath(path, fields) {
11
- const matches = (field, key) => field === key || field === "*" && typeof key === "number";
12
- return fields.some(field => field.every((key, index) => matches(key, path[index])) || path.every((key, index) => matches(field[index], key)));
13
- }
14
- /** Validate discarded values too; the parser never packs their strings or numbers. */
15
- export async function projectJson(input, fields, maxBytes = ENVELOPE_MAX_BYTES) {
16
- async function* decode() {
17
- const decoder = new TextDecoder("utf-8", { fatal: true });
18
- for await (const chunk of input)
19
- yield decoder.decode(chunk, { stream: true });
20
- const tail = decoder.decode();
21
- if (tail)
22
- yield tail;
23
- }
24
- const stack = [];
25
- let root;
26
- let literal;
27
- let inKey = false;
28
- let keyText = "";
29
- let bytes = 0;
30
- const reserve = (size) => {
31
- bytes += size;
32
- if (bytes > maxBytes)
33
- throw new Error("Selected journal envelope exceeds its bounded read size.");
34
- };
35
- const path = () => stack.length ? [...stack.at(-1).path, stack.at(-1).key ?? stack.at(-1).index] : [];
36
- const excluded = () => stack.length > 0 && stack.at(-1).value === undefined;
37
- const put = (value) => {
38
- const parent = stack.at(-1);
39
- if (!parent)
40
- root = value;
41
- else {
42
- if (parent.value && value !== undefined) {
43
- if (Array.isArray(parent.value))
44
- parent.value[parent.index] = value;
45
- else
46
- Object.defineProperty(parent.value, parent.key, { value, writable: true, enumerable: true, configurable: true });
47
- }
48
- parent.key = undefined;
49
- parent.index += 1;
50
- }
51
- };
52
- const consume = (token) => {
53
- if (token.name === "startKey") {
54
- inKey = true;
55
- keyText = "";
56
- return;
57
- }
58
- if (token.name === "endKey") {
59
- inKey = false;
60
- stack.at(-1).key = keyText;
61
- return;
62
- }
63
- if (inKey) {
64
- if (token.name === "stringChunk" && !excluded()) {
65
- const wholeContainer = fields.some(field => field.every((key, index) => stack.at(-1).path[index] === key || key === "*" && typeof stack.at(-1).path[index] === "number"));
66
- if (wholeContainer || keyText.length <= 1024) {
67
- if (wholeContainer)
68
- reserve(Buffer.byteLength(token.value));
69
- keyText += token.value;
70
- }
71
- }
72
- return;
73
- }
74
- if (token.name === "startObject" || token.name === "startArray") {
75
- if (stack.length >= 1024)
76
- throw new Error("Journal JSON nesting exceeds 1024 levels.");
77
- // Excluded containers cannot contain a requested descendant. Validate their tokens
78
- // without allocating a path/key for each ref in an old repeated map.
79
- const currentPath = excluded() ? [] : path();
80
- const selected = !excluded() && selectedPath(currentPath, fields);
81
- if (selected)
82
- reserve(32);
83
- stack.push({ path: currentPath, index: 0, value: selected ? token.name === "startObject" ? {} : [] : undefined });
84
- }
85
- else if (token.name === "endObject" || token.name === "endArray")
86
- put(stack.pop().value);
87
- else if (token.name === "startString" || token.name === "startNumber")
88
- literal = { value: "", selected: !excluded() && selectedPath(path(), fields), number: token.name === "startNumber" };
89
- else if (token.name === "stringChunk" || token.name === "numberChunk") {
90
- if (literal?.selected) {
91
- reserve(Buffer.byteLength(token.value));
92
- literal.value += token.value;
93
- }
94
- }
95
- else if (token.name === "endString" || token.name === "endNumber") {
96
- put(literal?.selected ? literal.number ? Number(literal.value) : literal.value : undefined);
97
- literal = undefined;
98
- }
99
- else if (token.name === "trueValue" || token.name === "falseValue" || token.name === "nullValue") {
100
- const selected = !excluded() && selectedPath(path(), fields);
101
- if (selected)
102
- reserve(8);
103
- put(selected ? token.name === "nullValue" ? null : token.name === "trueValue" : undefined);
104
- }
105
- };
106
- const sink = new Writable({ objectMode: true, write(token, _encoding, done) {
107
- try {
108
- consume(token);
109
- done();
110
- }
111
- catch (error) {
112
- done(error);
113
- }
114
- } });
115
- await pipeline(Readable.from(decode()), parser.asStream({ packValues: false, streamValues: true }), sink);
116
- return isRecord(root) ? root : undefined;
117
- }
118
- export async function* readRange(file, range) {
119
- let position = range.offset;
120
- const end = range.offset + range.length;
121
- while (position < end) {
122
- const buffer = Buffer.allocUnsafe(Math.min(CHUNK_BYTES, end - position));
123
- const { bytesRead } = await file.read(buffer, 0, buffer.length, position);
124
- if (!bytesRead)
125
- throw new Error("Journal changed or truncated during read.");
126
- position += bytesRead;
127
- yield buffer.subarray(0, bytesRead);
128
- }
129
- }
130
- /** Byte framing, not readline: even a single discarded value may exceed V8's string limit. */
131
- export async function* journalRanges(file, end, sealed = false, offset = 0) {
132
- let position = offset;
133
- let start = offset;
134
- let nonblank = false;
135
- while (position < end) {
136
- const buffer = Buffer.allocUnsafe(Math.min(CHUNK_BYTES, end - position));
137
- const { bytesRead } = await file.read(buffer, 0, buffer.length, position);
138
- if (!bytesRead)
139
- throw new Error("Journal truncated during read.");
140
- for (let index = 0; index < bytesRead; index++) {
141
- const byte = buffer[index];
142
- if (byte === 10) {
143
- if (nonblank)
144
- yield { offset: start, length: position + index + 1 - start };
145
- start = position + index + 1;
146
- nonblank = false;
147
- }
148
- else if (![9, 13, 32].includes(byte))
149
- nonblank = true;
150
- }
151
- position += bytesRead;
152
- }
153
- if (nonblank && sealed)
154
- yield { offset: start, length: end - start };
155
- }
156
- const STRUCTURAL_FIELDS = [["type"], ["id"], ["parentId"], ["timestamp"], ["version"], ["customType"], ["data", "event", "version"], ["data", "snapshot", "id"], ["message", "toolName"], ["message", "details", "browserEventVersion"], ["message", "details", "sessionName"], ["message", "details", "artifactManifest", "version"], ["message", "details", "electron", "action"]];
157
- const REPLAY_CUSTOM_TYPES = new Set([BROWSER_TRANSITION_ENTRY, "agent-browser-recording-reservation", "agent-browser-script-session"]);
158
- export async function scanJournalMetadata(file, end, sealed = false) {
159
- const entries = [];
160
- for await (const range of journalRanges(file, end, sealed)) {
161
- const value = await projectJson(readRange(file, range), STRUCTURAL_FIELDS);
162
- if (!value)
163
- throw new Error(`Expected a journal object at byte ${range.offset}.`);
164
- entries.push({ ...range, value });
165
- }
166
- return entries;
167
- }
168
- function branchEntries(entries, leaf) {
169
- const byId = new Map();
170
- for (const entry of entries) {
171
- const id = entry.value.id;
172
- if (typeof id !== "string" || byId.has(id))
173
- throw new Error("Journal has a missing or duplicate native entry identity.");
174
- byId.set(id, entry);
175
- }
176
- const branch = [];
177
- const seen = new Set();
178
- while (leaf !== null) {
179
- if (seen.has(leaf))
180
- throw new Error("Journal ancestry contains a cycle.");
181
- seen.add(leaf);
182
- const entry = byId.get(leaf);
183
- if (!entry)
184
- throw new Error(`Selected journal entry ${leaf} is not persisted; browser work requires a committed conversation.`);
185
- branch.push(entry);
186
- if (entry.value.parentId !== null && typeof entry.value.parentId !== "string")
187
- throw new Error("Invalid journal parent identity.");
188
- leaf = entry.value.parentId;
189
- }
190
- return branch.reverse();
191
- }
192
- export async function readBrowserEntries(manager, physical = false) {
193
- const inMemory = () => {
194
- const entries = physical ? manager.getEntries() : [];
195
- if (!physical) {
196
- const seen = new Set();
197
- let leaf = manager.getLeafId();
198
- while (leaf !== null) {
199
- if (seen.has(leaf))
200
- throw new Error("In-memory journal ancestry contains a cycle.");
201
- seen.add(leaf);
202
- const entry = manager.getEntry(leaf);
203
- if (!entry || entry.parentId !== null && typeof entry.parentId !== "string")
204
- throw new Error("In-memory journal ancestry is incomplete.");
205
- entries.push(entry);
206
- leaf = entry.parentId;
207
- }
208
- entries.reverse();
209
- }
210
- for (const entry of entries) {
211
- if (isRecord(entry) && entry.type === "custom" && [BROWSER_TRANSITION_ENTRY, "agent-browser-script-session"].includes(String(entry.customType)) && !getBrowserRecord(entry)) {
212
- throw new Error("Legacy browser records require stopped separate-copy conversion before replay.");
213
- }
214
- if (isRecord(entry) && entry.type === "message" && isRecord(entry.message) && BROWSER_RESULT_TOOLS.has(String(entry.message.toolName))
215
- && isRecord(entry.message.details) && entry.message.details.browserEventVersion !== 1 && !getBrowserRecord(entry)) {
216
- throw new Error("Legacy browser observations require stopped separate-copy conversion before replay.");
217
- }
218
- }
219
- return entries;
220
- };
221
- const path = manager.getSessionFile();
222
- if (!path) {
223
- // Public in-memory ancestry is the only fallback. No writable SessionManager is constructed.
224
- return inMemory();
225
- }
226
- const leaf = physical ? null : manager.getLeafId();
227
- let file;
228
- try {
229
- file = await open(path, constants.O_RDONLY);
230
- }
231
- catch (error) {
232
- if (error.code === "ENOENT")
233
- return inMemory();
234
- throw error;
235
- }
236
- try {
237
- const captured = await file.stat();
238
- if (!captured.isFile())
239
- throw new Error("Pi session journal is not a regular file.");
240
- const metadata = await scanJournalMetadata(file, captured.size);
241
- const header = metadata.find(entry => entry.value.type === "session");
242
- if (header?.value.id !== (manager.getHeader()?.id ?? manager.getSessionId()))
243
- throw new Error("Pi session journal identity does not match the active session.");
244
- const selected = physical ? metadata.filter(entry => entry.value.type !== "session") : branchEntries(metadata.filter(entry => entry.value.type !== "session"), leaf);
245
- const projected = [];
246
- const definitions = new Map();
247
- for (const entry of selected) {
248
- const { value } = entry;
249
- const definition = isRecord(value.data) && isRecord(value.data.snapshot) ? value.data.snapshot.id : undefined;
250
- if (typeof definition === "string") {
251
- if (definitions.has(definition))
252
- throw new Error("Browser snapshot identity is defined more than once on this ancestry.");
253
- definitions.set(definition, entry);
254
- }
255
- const legacy = value.type === "custom" && (value.customType === BROWSER_TRANSITION_ENTRY || value.customType === "agent-browser-script-session")
256
- && !(isRecord(value.data) && isRecord(value.data.event) && value.data.event.version === 1);
257
- const message = isRecord(value.message) ? value.message : undefined;
258
- const legacyResult = message && typeof message.toolName === "string" && BROWSER_RESULT_TOOLS.has(message.toolName)
259
- && (!isRecord(message.details) || message.details.browserEventVersion !== 1)
260
- && !(isRecord(value.data) && isRecord(value.data.event) && value.data.event.version === 1)
261
- && isRecord(message.details) && (message.details.sessionName !== undefined || message.details.artifactManifest !== undefined || message.details.electron !== undefined);
262
- if (legacy || legacyResult)
263
- throw new Error("This session contains legacy browser records. Convert a stopped separate copy with npm exec --package pi-agent-browser-native -- pi-agent-browser-convert before resuming browser work; the original journal is retained.");
264
- if (value.type === "custom" && REPLAY_CUSTOM_TYPES.has(String(value.customType)) || isRecord(value.data) && isRecord(value.data.event) || definition !== undefined) {
265
- const fields = value.customType === BROWSER_TRANSITION_ENTRY || value.type === "message" ? [["data", "event"], ["data", "snapshot", "id"]] : [["data"]];
266
- const body = await projectJson(readRange(file, entry), fields);
267
- projected.push({ ...value, ...body });
268
- }
269
- }
270
- // Resolve only the definitions that actually win on this ancestry. An unresolved begin
271
- // retains an inaccessible candidate ID; it does not request historical ref payloads.
272
- const { SessionPageState } = await import("./session-page-state.js");
273
- const reduced = SessionPageState.fromBranch(projected);
274
- const winners = new Set((physical ? [] : [...reduced.views().values()]).flatMap(page => page.refSnapshot?.snapshotId ? [page.refSnapshot.snapshotId] : []));
275
- for (const id of winners) {
276
- const entry = definitions.get(id);
277
- if (!entry)
278
- throw new Error(`Browser snapshot ${id} has no ancestral definition; inspect and take a fresh snapshot.`);
279
- // ponytail: a requested individual snapshot must fit its consumer's memory. Metadata
280
- // scans skip unlimited unrelated values; upgrade with native per-value paging if needed.
281
- const body = await projectJson(readRange(file, entry), [["data", "snapshot"]], Infinity);
282
- const destination = projected.find(candidate => isRecord(candidate) && candidate.id === entry.value.id);
283
- if (!isRecord(destination) || !isRecord(destination.data) || !isRecord(body?.data))
284
- throw new Error("Winning browser snapshot could not be read.");
285
- destination.data.snapshot = body.data.snapshot;
286
- if (!isRecord(body.data.snapshot) || body.data.snapshot.id !== id)
287
- throw new Error("Winning browser snapshot identity is invalid.");
288
- snapshotFromDefinition(body.data.snapshot);
289
- }
290
- let manifest;
291
- for (const entry of projected)
292
- manifest = applyArtifactChanges(manifest, getBrowserRecord(entry)?.event.artifacts);
293
- const current = await file.stat();
294
- const currentPath = await stat(path);
295
- if (current.dev !== captured.dev || current.ino !== captured.ino || current.size < captured.size || currentPath.dev !== captured.dev || currentPath.ino !== captured.ino)
296
- throw new Error("Pi journal replaced or truncated during replay.");
297
- return projected;
298
- }
299
- finally {
300
- await file.close();
301
- }
302
- }
5
+ import { journalRanges, projectJson, readRange } from "./browser-journal-reader.js";
6
+ export { journalRanges, projectJson, readRange, scanJournalMetadata, } from "./browser-journal-reader.js";
7
+ export { readBrowserEntries } from "./browser-journal-replay.js";
303
8
  /** A filename is not durability evidence on official Pi before its first conversation. */
304
9
  export function requirePublishedBrowserJournal(manager) {
305
10
  const path = manager.getSessionFile();
306
- if (!path)
11
+ if (path === undefined || path.length === 0) {
307
12
  throw new Error("Browser code requires a published Pi conversation; relaunch without --no-session.");
13
+ }
308
14
  let fd;
309
15
  try {
310
16
  fd = openSync(path, constants.O_RDONLY);
311
- const stat = fstatSync(fd);
312
- if (!stat.isFile() || stat.size === 0)
17
+ const entry = fstatSync(fd);
18
+ if (!entry.isFile() || entry.size === 0) {
313
19
  throw new Error("Pi conversation has not been published yet.");
20
+ }
314
21
  }
315
22
  catch (error) {
316
23
  throw new Error("Browser work requires an actually published Pi conversation before dispatch; send a user message first.", { cause: error });
317
24
  }
318
25
  finally {
319
- if (fd !== undefined)
26
+ if (fd !== undefined) {
320
27
  closeSync(fd);
28
+ }
321
29
  }
322
30
  }
323
31
  /** Observation-only artifact receipts are optional until Pi publishes its journal. */
@@ -330,110 +38,111 @@ export function hasPublishedBrowserJournal(manager) {
330
38
  return false;
331
39
  }
332
40
  }
333
- /** Capture before waiting: native selection precedes sequential session_tree handlers. */
334
- export function captureBrowserBranch(manager, isGenerationCurrent) {
335
- const sessionId = manager.getSessionId();
336
- let anchorId = manager.getLeafId();
337
- let validatedAnchor;
338
- let validatedLeaf;
339
- const branch = { sessionId, anchorId, isCurrent() {
340
- if (!isGenerationCurrent() || manager.getSessionId() !== sessionId)
341
- return false;
342
- if (branch.anchorId !== anchorId) {
343
- validatedAnchor = validatedLeaf = undefined;
344
- anchorId = branch.anchorId;
345
- }
346
- let leaf = manager.getLeafId();
347
- // Empty selection is not a universal ancestor of other independent roots.
348
- let current = branch.anchorId === null && leaf === null;
349
- const seen = new Set();
350
- let selected;
351
- let anchor;
352
- while (leaf !== null) {
353
- if (typeof leaf !== "string" || seen.has(leaf))
354
- throw new Error("Selected Pi journal ancestry is invalid or cyclic.");
355
- seen.add(leaf);
356
- const entry = manager.getEntry(leaf);
357
- if (!entry || entry.id !== leaf || entry.parentId !== null && typeof entry.parentId !== "string")
358
- throw new Error("Selected Pi journal ancestry is incomplete.");
359
- selected ??= { entry, parentId: entry.parentId };
360
- const cached = leaf === branch.anchorId ? validatedAnchor : leaf === validatedLeaf?.entry.id ? validatedLeaf : undefined;
361
- if (cached) {
362
- // Keep the native indexed lookup: it also refreshes fork journal identity.
363
- if (cached.entry === entry && cached.parentId === entry.parentId) {
364
- current = true;
365
- break;
366
- }
367
- validatedAnchor = validatedLeaf = undefined;
368
- }
369
- if (leaf === branch.anchorId) {
370
- current = true;
371
- anchor = { entry, parentId: entry.parentId };
372
- }
373
- leaf = entry.parentId;
374
- }
375
- // Native entries/parents are append-only. Cache only after validating through
376
- // the root (or an already validated endpoint), never merely on leaf === anchor.
377
- // ponytail: behind-host mutation of an old ancestor without native reseed or
378
- // generation change is outside this contract; durable file proofs
379
- // remain in replay/append. Upgrade if Pi exposes a separate ancestry revision.
380
- if (current && selected) {
381
- validatedAnchor = anchor ?? validatedAnchor;
382
- validatedLeaf = selected;
383
- }
384
- return current;
385
- } };
386
- return branch;
41
+ export { captureBrowserBranch } from "./browser-journal-branch.js";
42
+ const RECEIPT_FIELDS = [
43
+ ["type"],
44
+ ["id"],
45
+ ["customType"],
46
+ ...["version", "operationId", "phase", "toolCallId", "commandIndex"].map((field) => [
47
+ "data",
48
+ "event",
49
+ field,
50
+ ]),
51
+ ];
52
+ function matchesReceipt(value, receipt) {
53
+ if (value.id !== receipt.nativeId ||
54
+ value.type !== "custom" ||
55
+ value.customType !== BROWSER_TRANSITION_ENTRY ||
56
+ !isRecord(value.data) ||
57
+ !isRecord(value.data.event)) {
58
+ return false;
59
+ }
60
+ const event = value.data.event;
61
+ const expected = receipt.expected.event;
62
+ const identity = {
63
+ operationId: expected.operationId,
64
+ phase: expected.phase,
65
+ toolCallId: expected.toolCallId,
66
+ commandIndex: expected.commandIndex,
67
+ };
68
+ return (event.version === 1 &&
69
+ Object.entries(identity).every(([key, fieldValue]) => event[key] === fieldValue));
387
70
  }
388
- /** A withdrawn branch returns false; required publication faults still throw. */
389
- export async function appendBrowserRecord(manager, append, expected, branch) {
390
- if (!manager.getSessionFile()) {
391
- if (!branch.isCurrent())
392
- return false;
393
- append();
394
- if (branch.anchorId === null)
395
- branch.anchorId = manager.getLeafId();
396
- return branch.isCurrent();
71
+ async function countPublishedReceipts(file, journal, receipt) {
72
+ let matches = 0;
73
+ for await (const range of journalRanges(file, journal.after.size, false, journal.start)) {
74
+ const value = await projectJson(readRange(file, range), RECEIPT_FIELDS);
75
+ if (!value) {
76
+ continue;
77
+ }
78
+ if (value.type === "session" && value.id !== journal.sessionId) {
79
+ throw new Error("Pi repaired journal identity differs from the active session.");
80
+ }
81
+ if (matchesReceipt(value, receipt)) {
82
+ matches++;
83
+ }
397
84
  }
398
- requirePublishedBrowserJournal(manager);
399
- const path = manager.getSessionFile();
85
+ return matches;
86
+ }
87
+ function appendToBranch(manager, append, branch) {
88
+ append();
89
+ if (branch.anchorId === null) {
90
+ branch.anchorId = manager.getLeafId();
91
+ }
92
+ }
93
+ async function verifyAppend(file, path, before, receipt) {
94
+ const after = await file.stat();
95
+ const sameFile = after.dev === before.dev && after.ino === before.ino;
96
+ if (!after.isFile() || (sameFile && after.size <= before.size)) {
97
+ throw new Error("Pi did not publish the browser event.");
98
+ }
99
+ const matches = await countPublishedReceipts(file, { after, start: sameFile ? before.size : 0, sessionId: receipt.sessionId }, receipt);
100
+ const current = await stat(path);
101
+ if (matches !== 1 ||
102
+ current.dev !== after.dev ||
103
+ current.ino !== after.ino ||
104
+ current.size < after.size) {
105
+ throw new Error("Pi browser append has no matching published journal receipt.");
106
+ }
107
+ }
108
+ async function appendPublishedRecord(manager, path, operation) {
400
109
  const beforeFile = await open(path, constants.O_RDONLY);
401
110
  let file;
402
111
  try {
403
112
  const before = await beforeFile.stat();
404
113
  // Native navigation changes the leaf before its awaited session_tree handlers.
405
- if (!branch.isCurrent())
114
+ if (!operation.branch.isCurrent()) {
406
115
  return false;
407
- append();
116
+ }
117
+ appendToBranch(manager, operation.append, operation.branch);
408
118
  const nativeId = manager.getLeafId();
409
- if (branch.anchorId === null)
410
- branch.anchorId = nativeId;
411
- // Native repair can flush several accepted records or replace the journal.
412
- // Reopen its published locator and frame records instead of parsing the suffix as one value.
119
+ // Native repair may flush several records or replace the file. Reopen and frame the actual journal.
413
120
  file = await open(path, constants.O_RDONLY);
414
- const after = await file.stat();
415
- const sameFile = after.dev === before.dev && after.ino === before.ino;
416
- if (!after.isFile() || sameFile && after.size <= before.size)
417
- throw new Error("Pi did not publish the browser event.");
418
- let matches = 0;
419
- const fields = [["type"], ["id"], ["customType"], ["data", "event", "version"], ["data", "event", "operationId"], ["data", "event", "phase"], ["data", "event", "toolCallId"], ["data", "event", "commandIndex"]];
420
- for await (const range of journalRanges(file, after.size, false, sameFile ? before.size : 0)) {
421
- const value = await projectJson(readRange(file, range), fields);
422
- const event = isRecord(value?.data) && isRecord(value.data.event) ? value.data.event : undefined;
423
- if (value?.type === "session" && value.id !== (manager.getHeader()?.id ?? manager.getSessionId()))
424
- throw new Error("Pi repaired journal identity differs from the active session.");
425
- if (value?.id === nativeId && value?.type === "custom" && value.customType === BROWSER_TRANSITION_ENTRY
426
- && event?.version === 1 && event.operationId === expected.event.operationId && event.phase === expected.event.phase
427
- && event.toolCallId === expected.event.toolCallId && event.commandIndex === expected.event.commandIndex)
428
- matches += 1;
429
- }
430
- const current = await stat(path);
431
- if (matches !== 1 || current.dev !== after.dev || current.ino !== after.ino || current.size < after.size)
432
- throw new Error("Pi browser append has no matching published journal receipt.");
121
+ await verifyAppend(file, path, before, {
122
+ nativeId,
123
+ expected: operation.expected,
124
+ sessionId: manager.getHeader()?.id ?? manager.getSessionId(),
125
+ });
433
126
  }
434
127
  finally {
435
128
  await file?.close();
436
129
  await beforeFile.close();
437
130
  }
438
- return branch.isCurrent();
131
+ return operation.branch.isCurrent();
132
+ }
133
+ /** A withdrawn branch returns false; required publication faults still throw. */
134
+ export async function appendBrowserRecord(manager, append, expected, branch) {
135
+ if ((manager.getSessionFile() ?? "").length === 0) {
136
+ if (!branch.isCurrent()) {
137
+ return false;
138
+ }
139
+ appendToBranch(manager, append, branch);
140
+ return branch.isCurrent();
141
+ }
142
+ requirePublishedBrowserJournal(manager);
143
+ const path = manager.getSessionFile();
144
+ if (path === undefined || path.length === 0) {
145
+ throw new Error("Pi conversation has no published journal locator.");
146
+ }
147
+ return appendPublishedRecord(manager, path, { append, expected, branch });
439
148
  }