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,6 +1,7 @@
1
1
  # Architecture
2
2
 
3
3
  Related docs:
4
+
4
5
  - [`../README.md`](../README.md)
5
6
  - [`../AGENTS.md`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/AGENTS.md) (maintainer workflows, including upstream capability baseline)
6
7
  - [`REQUIREMENTS.md`](REQUIREMENTS.md)
@@ -13,6 +14,8 @@ Build this as a **thin `pi` extension/package** that exposes native commands and
13
14
 
14
15
  The package install path is the primary product path. Local checkout development should use explicit CLI loading for isolated smoke tests and configured-source plain `pi` runs for lifecycle validation, while package-manifest behavior and packaged contents matter more.
15
16
 
17
+ Runtime graphs that use Pi host APIs are statically imported through Pi's extension loader, which supplies the host-peer mapping. Native ESM lazy imports must not bypass that mapping: a runtime-only global package does not install its optional Pi peers. The browser runner and observation/image publication retain Pi's native image primitives without a package-owned resolver or bundled host.
18
+
16
19
  ## Chosen shape
17
20
 
18
21
  ### Compact tools and native discovery
@@ -30,10 +33,11 @@ The collector's dynamic `isManaged()` decides ownership. Managed Pi delivers ful
30
33
  ### Direct subprocess execution
31
34
 
32
35
  The extension should:
36
+
33
37
  - resolve `agent-browser` from `PATH`
34
38
  - invoke it with native Node `spawn` on POSIX and `cross-spawn` on Windows. For the recognized global npm CMD template, public `which`/`path-key` resolution selects the same launcher and Node invokes its exact adjacent native executable directly, preserving literal CR/LF. Recognition requires the stock template, package identity and executable; custom launchers, other layouts, ambiguous search environments and worker-thread calls retain `cross-spawn`. No later installation is substituted. Custom or unrecognized batch files can still truncate literal newlines. Caller commands and helper probes retain empty operands, literal doublequotes, command/subcommand adjacency and explicit default `--namespace ""`. Keep piped stdin/stdout/stderr and await full Windows process-tree termination with `taskkill /T /F` on timeout or abort before falling back to the direct child signal. Missing commands use the spawner's `ENOENT`
35
39
  - bound native process-identity queries at ten seconds on Windows, including PowerShell startup, and five seconds on POSIX. These probes preserve PID/start-time comparison and fail closed when identity is unavailable; their budget is separate from lock contention and browser command watchdogs
36
- - inject `--json`; caller-requested JSON also uses the existing `buildJsonVisibleContent` envelope for early snapshot/network filters, scroll results, and preparation failures, retaining metadata in `details` and keeping output-file notices out of visible JSON. Help/version stays native text
40
+ - inject `--json` only when no caller output mode is selected; explicit `--json false` retains opaque redacted native text and process outcomes without interpreting page text as trusted receipts or a session target. Optional booleans follow upstream last-wins semantics; structured helpers stay strict JSON. Nonzero exits with stderr retain the native error ahead of parse diagnostics, while zero-exit malformed machine output remains a strict failure. Empty stdin batch rows pass validation and native execution skips them without rewriting caller input. Caller-requested JSON also uses the existing `buildJsonVisibleContent` envelope for early snapshot/network filters, scroll results, and preparation failures, retaining metadata in `details` and keeping output-file notices out of visible JSON. Help/version stays native text
37
41
  - complete each upstream invocation when the direct `agent-browser` child exits even if Node delays `"close"`: piped stdio can stay referenced by longer-lived descendant processes, so `runAgentBrowserProcess` watches `exit` and `close` together, leaves stdio intact during a short post-`exit` grace so normal `close` can still win, destroys streams only when the post-`exit` fallback fires, and prefers `close` codes then wrapper timeout (`124`) over signal-shaped `exit` codes (`watchSpawnedChildCompletion` / `resolveSpawnedChildExitCode` in `extensions/agent-browser/lib/process.ts`) so the tool cannot hang after the CLI process has already terminated
38
42
  - support optional stdin only for `eval --stdin`, `batch`, `auth save --password-stdin`, and internally generated QA/source batch plans, rejecting other command/stdin combinations before launch; Electron manages its own input
39
43
  - support optional top-level `outputPath` for successful browser results and failed/pending/recovered recording receipts. Recording exports retain success/error, original attempt, native data, artifacts and recovery provenance; they do not treat a written receipt as a successful video. Other successful results write `details.data` (or model-facing text when no structured data exists) to a caller-requested local file and reporting `details.outputFile`, without changing upstream argv semantics or overwriting a browser artifact when both destinations resolve to the same file. If presentation compacted direct data, a batch result row, or a whole batch, apply the relevant command-specific redactor before spilling and rehydrate each full pre-compaction value only from its matching live wrapper-manifest spill; fail without writing compact metadata when any required spill is unavailable or untrusted
@@ -42,7 +46,7 @@ The extension should:
42
46
 
43
47
  ### Persistent browser code
44
48
 
45
- `lib/input-modes/script.ts` and compiled `script-worker.js` retain the fresh permissioned Node child/VM and JSON-lines bridge. The internal filenames are not a public `script` input. `index.ts` selects the ordinary browser identity in the parent, holds its shared execution lock for the whole cell, serializes inner requests through the same executor, and reaps the child on completion, timeout, abort, branch change, or shutdown. The browser survives cell completion according to existing ownership. Native auth, profiles, state, connect, batch, and local commands retain ordinary parent-side configuration/environment; only changing the fixed session/namespace and namespace-wide close are excluded from an inner call.
49
+ `lib/input-modes/script.ts` and compiled `script-worker.js` retain the fresh permissioned Node child/VM and JSON-lines bridge. The internal filenames are not a public `script` input. `orchestration/extension-code.ts` selects the ordinary browser identity in the parent, holds its shared execution lock for the whole cell, serializes inner requests through the same executor, and reaps the child on completion, timeout, abort, branch change, or shutdown. The browser survives cell completion according to existing ownership. Native auth, profiles, state, connect, batch, and local commands retain ordinary parent-side configuration/environment; only changing the fixed session/namespace and namespace-wide close are excluded from an inner call.
46
50
 
47
51
  The child has an empty environment, Node permission mode without host capability allowlists, a 64 MiB heap ceiling, and a VM with string/WebAssembly code generation disabled. Null-prototype `browser`, `emit`, and `emitImage` functions use JSON-only IPC; parent promises/objects/functions are not exposed. There are no imports or host filesystem/network/process/timer APIs. Node's VM alone is not a security boundary. The retained child isolation is distinct from the selected browser's persistent authentication and native capabilities; no QuickJS, broker, second driver, or provider payload injection is involved.
48
52
 
@@ -73,6 +77,7 @@ Artifact directory preparation has one filesystem-error boundary inside the exis
73
77
  The primary UX is the agent calling the tool directly.
74
78
 
75
79
  That means:
80
+
76
81
  - no command-heavy slash-command interface
77
82
  - no manual user orchestration as the main workflow
78
83
  - any future slash commands should be minimal and secondary
@@ -119,6 +124,7 @@ Local checkout validation has two intentional modes:
119
124
  The repo should not add a repo-local `.pi/extensions/` autoload shim as the documented checkout path.
120
125
 
121
126
  Why:
127
+
122
128
  - avoids duplicate `agent_browser` registrations when the package is also installed globally
123
129
  - keeps the product contract centered on the package manifest instead of repo-local autoload wiring
124
130
  - keeps reload and exact-session relaunch validation tied to Pi's configured-source lifecycle instead of an explicit-extension quick-test path, while `session_tree` state changes stay covered by focused extension harness tests
@@ -128,7 +134,7 @@ The published package should exclude agent-only and internal planning materials
128
134
 
129
135
  ## Host execution hook
130
136
 
131
- The default extension factory optionally accepts `{ beforeExecute }`. `index.ts` awaits this host callback after input resolution and before ordinary dispatch, forwarding the original outer Pi tool-call ID through inner code calls and supplying each dispatch's signal. Configured hosts use Pi's native sequential tool scheduling; inner code calls retain the existing serial queue. No separate controller, persistence store, retry policy, or timeout is introduced. Ordinary installation, internal helper probes, cleanup, batch-row execution, and web search are unchanged. See [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#host-execution-hook) for cancellation and error behavior; `test/agent-browser.pi-pipeline.test.ts` exercises the registered factory through real Pi with a fake upstream executable.
137
+ The default extension factory optionally accepts `{ beforeExecute }`. `orchestration/extension-command-admission.ts` awaits this host callback after input resolution and before ordinary dispatch, forwarding the original outer Pi tool-call ID through inner code calls and supplying each dispatch's signal. Configured hosts use Pi's native sequential tool scheduling; inner code calls retain the existing serial queue. No separate controller, persistence store, retry policy, or timeout is introduced. Ordinary installation, internal helper probes, cleanup, batch-row execution, and web search are unchanged. See [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#host-execution-hook) for cancellation and error behavior; `test/agent-browser.pi-pipeline.test.ts` exercises the registered factory through real Pi with a fake upstream executable.
132
138
 
133
139
  ## Session model
134
140
 
@@ -136,11 +142,12 @@ The optional `pi-change-working-dir` event protocol supplies one invocation exec
136
142
 
137
143
  ### Default
138
144
 
139
- An explicit native `session` default (user/project JSON or `AGENT_BROWSER_SESSION`) selects a caller-owned browser across Pi sessions. Per-call session/namespace flags win. `lib/orchestration/native-session-defaults.ts` reads session/namespace and contributing launch defaults from native config paths and uses sessionless native `--config <path> --json session` to validate each contributing file and resolve its session. Native config continues to own launch/profile/storage settings; the adapter does not duplicate its schema. Explicit config and per-call idle settings are scoped to helpers through `lib/process-environment.ts`. No startup probe, persistent config cache, or new lifecycle service is added.
145
+ An explicit native `session` default (user/project JSON or `AGENT_BROWSER_SESSION`) selects a caller-owned browser across Pi sessions. Per-call session/namespace flags win. `lib/orchestration/native-session-defaults.ts` reads session/namespace and contributing launch defaults from native config paths and uses sessionless native `--config <path> --json session` to validate each contributing file and resolve its session. Native config continues to own launch/profile/storage settings; the adapter does not duplicate its schema. Explicit config, per-call idle settings, `--action-policy`, `--confirm-actions`, `--debug` and `--no-auto-dialog` are scoped to helpers through `lib/process-environment.ts`. Boolean selections also supply CLI operands to helpers lacking an explicit selection, because native ORs environment/config booleans and only CLI `false` overrides true defaults. Explicit debug false removes the debug environment variable because native daemon logging tests its presence; no-auto-dialog false retains native `0`. Caller argv stays intact and the environment scope ends with the call. The effective confirmation setting is retained in existing `SessionPageState` and canonical page events, resolved inside the identity queue before daemon inspection and helpers. First launch and new explicit `--confirm-actions` / `--config` selections use native argv → environment → config precedence; bare follow-ups retain selected strings, including explicit `""`, over ambient environment/discovered-config edits. Native unset is not retained and continues native default resolution; no config freezing or ambient-change detector is needed. Successful session/namespace close and successfully closed managed replacements clear it. Cleanup scopes every probe and close to the old identity's setting; failed close retains its page/policy continuity. Off-branch live owners keep their selected strings in the same page state until cleanup; an ordered post-close relaunch retains the new daemon's setting. Resume and branch restore use the same reducer. Native still owns policy changes and pending confirmations; there is no policy hot-reload, pending-command store, persistent config cache, or new lifecycle service. Electron launch and host probes retain the same selected confirmation setting. Begin records preserve interrupted intent; a definite no-dispatch/native CLI parse/config/local-inspection rejection restores the previous setting only when no earlier browser helper could have established the request. Other policy flags remain call-scoped.
140
146
 
141
147
  When no native session, attachment, or explicit fresh launch is selected, `sessionMode: "auto"` uses `pi-root-<sha256(root Pi ID)[0:24]>` through the existing caller-owned named-session path. Descendants receive `PI_SUBAGENT_ROOT_SESSION_ID` from pi-subagents; root processes use `ctx.sessionManager.getSessionId()`. No cwd, human fork ancestry, run registry, or process-global assignment participates. The same name is the default native restore key. Existing native daemon inspection runs inside the existing identity queue: inactive roots receive bootstrap defaults, while active roots retain native launch settings and their current restore key. Scoped subprocess environment keeps helper settings consistent; no launch-settings journal is added. Root-name explicit follow-ups retain those defaults; unrelated explicit names do not. Global/override package `browser.defaultProfile` with `policy: "always"` supplies native Chrome profile names only, plus the configured executable, only when the effective engine is Chrome. Paths and project-only profile settings stay advisory. Native config/environment and explicit launch settings win. The communal source is copied by native Chrome launch, never by the wrapper, and each root's restore writes remain separate. Native JSON restore omits IndexedDB, service workers, and page-memory credentials; application-level restart verification is required. Parent and child quit leave the root browser alive; shared execution locks coordinate updated cooperating processes without a broker. An active older/fresh managed session keeps its existing lifecycle. A configured session has the same precedence over `fresh` as a literal `--session`; code follows the selected ordinary browser lifecycle; Electron launch retains its owned lifecycle. Electron launch suppresses the native session environment default only while allocating its generated session; ordinary browser follow-ups still honor the configured native default, so use the returned Electron session explicitly.
142
148
 
143
149
  Why:
150
+
144
151
  - works out of the box
145
152
  - gives continuity across calls
146
153
  - avoids forcing the agent to invent session names for basic browsing
@@ -151,7 +158,7 @@ Browser-independent calls to an already-owned session reuse its idle timeout, na
151
158
 
152
159
  An explicit native `session info` call is the preflight: daemon activity/PID is separate from `runtime.browser` liveness, Chrome PID, exact profile, tabs and launched/attached ownership. Pi adds its own cleanup ownership from existing ownership records. Unknown native fields stay unknown; the wrapper does not infer the browser from daemon/config state or add a host process scan. Native `runtime.recording.current` / `last` receipts and protocol capabilities remain visible. Full fields require companion native support; receipts retained by the native daemon are not durable after it exits.
153
160
 
154
- `lib/read-confirmation.ts` recognizes only native structured control responses for actual explicit URL reads. Ordered pending/cleared `readConfirmation` markers live in the existing `SessionPageState` and tool-result transcript, including resume/branch replay. They preserve actual session/default routing even for legacy prompts. Only native `capabilities.readRequiresConfirmation: true`, which promises exact ID validation, allows matching confirm/deny to skip page helpers and managed replacement. Explicit caller identities win, DOM/unknown-origin confirmations keep their prior checks, and response content cannot manufacture provenance. There is no separate confirmation store or wrapper authorization system.
161
+ `lib/read-confirmation.ts` recognizes strict native control envelopes with actual command provenance. Ordered pending/cleared `readConfirmation` markers in the existing `SessionPageState` and transcript preserve exact ID, canonical identity and compact originating command/native action across resume and branch replay; they never store argv or command blobs. For originating `tab new` commands, the same decoder and presentation validator also recognize paired `after_confirmation: ["open", <original URL>]` / nonempty `guidance` transport metadata, using the existing navigation operand reader and retaining strict control keys. It preserves conditional, redacted prose without persisting or executing continuation arguments; page/eval/HTTP data never acquires that provenance. Exact matching guarded decisions suppress only page/pinning helpers that could overwrite the native pending slot. For native batch this applies only when its first effective row is that matching decision, using native raw-argv-over-stdin selection; remaining page/ref checks stay intact. Completed browser-backed decisions still reconcile page/ref state, report inner failures and retire confirmed close normally; native ID validation is not implied. Explicit URL-read provenance remains separate: only `capabilities.readRequiresConfirmation: true` grants browser independence with native ID matching. Legacy URL reads keep normal checks; unrelated or forged/page-shaped observations gain no exemption. A per-call helper observer updates this same marker and stops later same-identity page helpers after a new pending control. Cold reopen exposes that helper decision without dispatching the original getter or replaying open. Confirmed full snapshots feed the existing ordered ref fold, while pending captures cannot replace completed refs. The existing cleared marker records one-use freshness only for a final successful complete confirmed capture; the next same-identity call consumes it in live state and replay. The semantic visible-ref resolver uses the same eligible capture for role click/check/fill and unique role/label select, preserving editable evidence and action payloads. This avoids gated semantic/freshness-snapshot retry loops without bypassing target, membership, invalidation or native generation checks. Pending snapshots use the common confirmation renderer rather than the empty-snapshot formatter. Required live URL verification replaces the call's remembered target before semantic resolution and direct-ref preflight, dropping old title/target identity when the complete URL changes. The existing stale-ref guard compares the complete approved URL, including fragments, only on one-use confirmed-capture calls; ordinary ref/tab URL comparisons remain fragment-insensitive. Caller-owned, attached and wrapper-owned managed sessions therefore reject refs from a different approved route without requiring resume, restore pinning or another gated snapshot. DOM-only renames on the same page after that sample are not resampled on this one use; ordinary checks resume afterward. Attachment replay honors realized compact close commands, including confirmed closes. There is no second confirmation store or wrapper authorization system. Click-dispatch probes keep their ordinary diagnostic window but self-clean their page listeners and marker after the per-call process timeout plus the existing two-second cleanup grace. Normal cleanup cancels that timer; expiry never needs a browser helper that could overwrite the pending slot.
155
162
 
156
163
  ### Native observation state
157
164
 
@@ -168,6 +175,7 @@ The tool should also expose a first-class `sessionMode: "fresh"` escape hatch so
168
175
  ### Ownership
169
176
 
170
177
  Ownership rule:
178
+
171
179
  - automatic root sessions use native caller-owned lifecycle; group members coordinate and close them explicitly
172
180
  - older implicit auto-generated sessions are extension-managed convenience sessions
173
181
  - unnamed `sessionMode: "fresh"` launches rotate that extension-managed session to a new upstream browser
@@ -175,6 +183,7 @@ Ownership rule:
175
183
  - extension-managed sessions should be reusable during an active `pi` session and across `/reload`, exact-session relaunch, `/resume`, and Pi branch-tree transitions, while still being cleaned up predictably
176
184
 
177
185
  Practical policy:
186
+
178
187
  - preserve the current branch-visible extension-managed session across `/reload`, exact-session relaunch, `/resume`, and Pi 1.0.0+ `session_tree` branch transitions so persisted sessions can keep following the live browser after lifecycle changes
179
188
  - close the active extension-managed session when the originating `pi` process quits, while leaving explicit caller-provided sessions alone
180
189
  - after branch restore, use the existing locked daemon inspection to distinguish a confirmed inactive wrapper-owned daemon from a live, unknown, or unavailable one. For compatible automatic managed restore only, keep the pending reopen in ordered session page state and persist it as `sessionTabReopenPending`. Non-page calls such as `tab list` can start a daemon without fulfilling it; explicit HTTP reads leave the managed browser and pending reopen untouched, including across branch/reload replay. Before the first current-page operation (`get url`, history commands and relative `pushstate` included), reopen the complete recorded URL with native `open`, invalidate old refs with the existing `page-transition` state, and verify the actual tab. Explicit URL reads and all-read batches skip managed ownership changes and browser helpers entirely; native owns their HTTP fetch and validation. Native `open` resets frame scope. Consume the obligation on that attempt or an executed explicit context/navigation/close command, not an unreached batch row; a failed open does not permit repeated navigation of a now-live browser. After the reopen CLI starts, cancellation returns a structured `aborted` result through the ordinary result path with the exact namespace/session, consumed marker and ref invalidation; it does not throw away replay state or run later browser helpers. Cancellation before the CLI starts does not consume the pending reopen. Internal URLs retain their fragments while tab/ref comparisons remain fragment-insensitive and presentation keeps normal redaction. Older transcripts cannot recover a fragment they did not record. Caller-owned/attached browsers and restore-disabled sessions do not take this path; live wrong-tab recovery still only selects an existing target. Reopening reloads the URL, not unsaved forms, JavaScript memory, or history. There is no second restore store or lifecycle lock.
@@ -183,7 +192,7 @@ Practical policy:
183
192
  - redact snapshot spill payloads before writing them, clean up process-private temp spill artifacts on shutdown, and keep persisted-session spill files in a private session-scoped artifact directory for `details.fullOutputPath` after reload/resume, with a 32 MiB per-session budget by default; `PI_AGENT_BROWSER_SESSION_ARTIFACT_MAX_BYTES=0` skips persistent-spill enumeration and eviction without changing temporary spill cleanup
184
193
  - keep explicit screenshots, downloads, PDFs, traces, HAR captures, and recordings written to caller-chosen paths on disk after a successful upstream close command (`close`, `quit`, or `exit`); before artifact-producing commands run, create missing parent directories for requested host paths, while native download always owns the click and download, including loopback links, generated Blob exports, and redirects; never substitute an anchor-href fetch. When the internal recent artifact view has entries, successful close commands also surface `details.artifactCleanup` and a compact `Artifact lifecycle` note pointing to structured explicit paths so operators remove files with normal host tools—the native tool does not delete arbitrary user paths (`extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts`, `getArtifactCleanupGuidance`); contract in [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details), checklist `RQ-0079` in [`SUPPORT_MATRIX.md`](SUPPORT_MATRIX.md)
185
194
  - reconstruct the current branch-visible extension-managed session, every transcript-proven still-active wrapper-owned managed identity, page-scoped refs, journal-ordered artifact-row changes, unbounded active-recording reservation events, and Electron launch records from the active transcript branch on `session_start` and `session_tree` so later default and explicit off-current calls keep following owned browsers after resume/reload or branch switching; restore also honors successful explicit `--session <wrapper-owned> close` rows, terminal nested-batch close outcomes even when aggregate artifact verification failed, and `electron.cleanup` managed-session steps so closed wrapper-owned sessions are not resurrected; a nested close invalidates the pre-close page target so a lifecycle-proven relaunch at `about:blank` is not treated as stale focus drift; explicit lifecycle evidence that a later diagnostic did not launch a browser preserves the terminal close, while any later row—including a failed row—whose lifecycle reports a browser launch keeps active/attached provenance; failed-step presentation persists only that bounded launch boolean so transcript replay reaches the same decision, missing lifecycle evidence remains conservatively active even on the first managed call, successful closes clear wrapper trace/profiler ownership before ordered later successful rows can rebuild it, namespace-scoped `close --all` clears all matching managed/attached/page/ref/route/trace/recording ownership, and recording starts after close are rejected before spawn
186
- - keep active recording destination reservations separate from the bounded metadata-only artifact manifest. The same journal retains native recording IDs and start windows; native receipts, including failures, flow through existing artifact metadata and verification. A stop timeout/no-recording result gets one two-second native `session info` query matching namespace/session, ID/path or effective batch start window. Recovery needs terminal native encoder success plus a matching verified file; filesystem presence alone is insufficient, old same-path receipts cannot verify a new take, and freshness starts at capture rather than status-query time. Original attempts and unrelated batch failures remain visible. No second ledger, recorder, sidecar or runtime ffprobe is added. The process-wide map is keyed by canonical namespace/session identity, rebuilt from append-only branch events, and retained for still-live process-owned recordings across branch switches. Shutdown/reload appends both terminal tombstones and still-live reservations onto the current branch so restart cannot resurrect a cross-branch close or lose a live-daemon reservation. One artifact lifecycle/output queue makes global destination preflight and reservation updates atomic across otherwise-concurrent caller-owned session queues. Every successful direct, ordered nested-batch, managed replacement, code, Electron, or shutdown close retires its exact identity at that lifecycle point; only the newest pending recording path remains authoritative across current transition replay (including same-timestamp restart rows), and recording starts after a nested close are rejected because upstream can falsely report success. Existing and dangling symlink ancestry, hardlink inode identity, full Unicode/platform case folding, and same-call `outputPath` comparison prevent alias reuse. One shared command-token projection mirrors upstream's full-argv global cleanup before artifact, recording, and presentation parsing; wait-download detection removes only the first timeout pair, follows upstream long/short mode precedence, and accepts both `--download` and `-d` wherever download mode wins; screenshot destinations use upstream's exact-flag, selector-prefix, case-sensitive extension, slash-path, and second-positional rules, while retaining the wrapper's intentional slash-bearing hidden-workspace path normalization. Recording path/URL consumers share a command-local reader that skips complete numeric `--fps` pairs, cursor/contact-sheet switches, and contact-sheet threshold values without rewriting argv or treating them as outer globals; native owns rate, format and extra-argument validation. Current recording transitions are replayed directly; artifact manifests are not treated as reservation events
195
+ - keep active recording destination reservations separate from the bounded metadata-only artifact manifest. The same journal retains native recording IDs and start windows; native receipts, including failures, flow through existing artifact metadata and verification. A restart without a terminal previous-take receipt retires the prior pending artifact only when native acknowledges `restarted: true`; rejected or pending restarts retain its reservation and stop action. A stop timeout/no-recording result gets one two-second native `session info` query matching namespace/session, ID/path or effective batch start window. Recovery needs terminal native encoder success plus a matching verified file; filesystem presence alone is insufficient, old same-path receipts cannot verify a new take, and freshness starts at capture rather than status-query time. Original attempts and unrelated batch failures remain visible. No second ledger, recorder, sidecar or runtime ffprobe is added. The process-wide map is keyed by canonical namespace/session identity, rebuilt from append-only branch events, and retained for still-live process-owned recordings across branch switches. Shutdown/reload appends both terminal tombstones and still-live reservations onto the current branch so restart cannot resurrect a cross-branch close or lose a live-daemon reservation. One artifact lifecycle/output queue makes global destination preflight and reservation updates atomic across otherwise-concurrent caller-owned session queues. Every successful direct, ordered nested-batch, managed replacement, code, Electron, or shutdown close retires its exact identity at that lifecycle point; only the newest pending recording path remains authoritative across current transition replay (including same-timestamp restart rows), and recording starts after a nested close are rejected because upstream can falsely report success. Existing and dangling symlink ancestry, hardlink inode identity, full Unicode/platform case folding, and same-call `outputPath` comparison prevent alias reuse. One shared command-token projection mirrors upstream's full-argv global cleanup before artifact, recording, and presentation parsing; wait-download detection removes only the first timeout pair, follows upstream long/short mode precedence, and accepts both `--download` and `-d` wherever download mode wins; screenshot destinations use upstream's exact-flag, selector-prefix, case-sensitive extension, slash-path, and second-positional rules, while retaining the wrapper's intentional slash-bearing hidden-workspace path normalization. Recording path/URL consumers share a command-local reader that skips complete numeric `--fps` pairs, cursor/contact-sheet switches, and contact-sheet threshold values without rewriting argv or treating them as outer globals; native owns rate, format and extra-argument validation. Current recording transitions are replayed directly; artifact manifests are not treated as reservation events
187
196
  - keep process-owned cleanup registries for extension-managed sessions and wrapper-launched Electron records separate from the current branch-visible view; `session_tree` restore and wrapper-owned browser commands are serialized with managed-session work, while caller-owned explicit-session commands use local queues and shared execution locks keyed to actual socket context and effective canonical namespace/session across prepare helpers (explicit namespace argv overrides inherited `AGENT_BROWSER_NAMESPACE`, including an explicit empty default) and main execution. macOS and Windows additionally normalize and case-fold namespace and session components to match case-insensitive daemon identity. Different caller-owned identities remain concurrent, except namespace-scoped `close --all` drains and exclusively barriers managed plus matching caller-owned work before clearing global namespace state; nested helpers never re-enter the outer queue, policy/route/artifact deltas merge across unrelated managed-state commits, and a separate branch-restore generation guard prevents stale completions from overwriting newer branch-visible state; artifact-row changes use the existing artifact queue and journal order so replay retains concurrently completed entries. Branch switches still must not drop resources the current Pi process owns and must keep fresh-session allocation monotonic
188
197
  - record successful `connect`, `--cdp`, enabled `--auto-connect`, environment-configured CDP/auto-connect, and wrapper Electron attachment identities in branch-visible state. First-use and later content-bearing calls live-check `get url` because attached targets can drift outside Pi. Caller config, file access, launch arguments, and environment pass through unchanged; only wrapper-injected compatibility launch arguments are omitted on active attachments. A terminal successful close removes the marker; a close followed by a later step whose lifecycle reports a browser launch preserves it, while a non-launching diagnostic such as `stream status` leaves the close terminal
189
198
  - when a successful close targets the current extension-managed session, including an explicit `--session <current> close` or an `electron.cleanup` managed-session step, clear page/ref state, mark that session inactive, untrack cleanup ownership, and rotate the next default auto call to a fresh wrapper-generated session name rather than reusing the closed name
@@ -196,10 +205,10 @@ Practical policy:
196
205
  - once the wrapper observes tab-drift risk for a session (profile restore correction, overlapping stale opens, or restored session state), later active-tab commands verify the intended tab under the existing session queue before semantic/ref helpers and user commands. Targets retain native CDP `targetId` across transcript replay; exact identity distinguishes duplicate URL/title tabs, while older targets without an ID keep URL-based matching. A cold managed reopen replaces the old ID. Native selection runs only when the intended tab is not already active, because upstream selection clears refs and frame scope even on same-tab reselection. Missing targets, failed selection, and post-selection target mismatches fail before user commands. Caller argv/stdin and native `--pin-tab` / `--no-pin-tab` preferences remain unchanged. Local commands, live `get url`, explicit HTTP `read <url>` (including its flags), URL `a11y`/`vitals`/`web-vitals`, `diff url`, `window new`, URL-bearing recording commands, and explicit tab/navigation/`connect`/`state load` recovery do not require the old target; history back/forward/reload, `pushstate`, and page-content operations still do. The same classifier scans effective batch rows past non-page prefixes until a page dependency or explicit context change, without rewriting user rows or changing bail behavior. For `window new` and `diff url`, observe the resulting URL instead of retaining the old target or treating the requested second URL as redirect evidence. Fold only reached native batch rows when available, discard targets before failed navigation/context transitions and live-verify the final page, discard observations and refs from before window/diff transitions, and let later successful snapshots rebuild refs even when another batch row fails. Retain an observed blank destination after either command instead of recovering the old page; if no final target is observed, use the existing unknown-target state. Caller batch arguments, stdin and bail behavior stay unchanged. Successful batches containing navigation-observable actions use the same final live page/identity observation as direct actions, so same-address popup tabs replace the pre-batch target before later pinning. Terminal batch closes do not trigger a page probe, and pending WebMCP targets remain unknown. Routine same-session commands avoid `tab list` preflights
197
206
  - for sessions with observed tab-drift risk, after a successful command on a known tab target, the wrapper may best-effort restore that same target again if restored/background tabs steal focus after the command returns; routine same-session commands skip focus correction, while observed pages without a returned native ID use `tab list` to establish current identity rather than inheriting an earlier tab's ID
198
207
  - after successful tab creation, selection, or close, including dispatched native batch rows, read the now-active URL and fresh non-blank title—even when two tabs share a URL—before updating per-session page state; retain the deliberate blank target instead of treating it as accidental drift
199
- - keep a per-session `refSnapshot` aligned with the last successful `snapshot` (including refs merged from a successful `batch` by taking the last successful `snapshot` step in batch result order): restore its once-stored ancestral definition when reloading, resuming, or moving to a different Pi session-tree branch, retain full membership and accessible metadata from that capture for wrapper-side diagnostics, drop it on successful close commands (`close`, `quit`, or `exit`), replace it with a persisted `page-transition` invalidation after any upstream-executed `record start` attempt (direct or batch; older supported natives can swap the page before their already-active check, so failed starts count; the warning and persisted summary explicitly describe conservative ref invalidation, not an observed page change), a `record restart` with a URL operand, `window new`, `diff url`, or WebMCP `invoke` / `result` / `cancel` (these page-provided tools can mutate, rerender, or navigate; when a spawned `batch` yields no parseable result rows, for example after a wrapper timeout, planned transition steps still record the invalidation), or after a failed transition command (`eval`, `back`, `forward`, `reload`, `connect`, `state load`, `tab` selection), including reached batch transitions and failed batch `open` rows whose live URL re-verification probe observed the page (a failed transition can still have mutated or replaced the document before throwing, so keeping the verified URL must not keep the prior refs; transcript replay preserves the persisted invalidation summary), and refuse page-scoped `@e…` argv before spawn when the active tab URL no longer matches the snapshot URL, when a ref id was never in that snapshot, when the snapshot state is invalidated, or when a `batch` step would reuse `@e…` on a guarded getter or mutation step after an earlier invalidating step (including `record start`, URL-bearing `record restart`, and WebMCP `invoke` / `result` / `cancel`) without a later `snapshot` step in the same plan; batch steps come from the source upstream actually executes (raw batch argument strings exclusively when any exist — filtering only the exact `--bail` token like upstream — stdin only otherwise, via `getUpstreamEffectiveBatchSteps` in `extensions/agent-browser/lib/orchestration/batch-stdin.ts`); tab recovery (which leaves user argv/stdin and continue-on-error control flow unchanged), artifact/recording preflight, batch screenshot path preparation (parent directories are created for effective raw rows too, without rewriting raw strings), and stale-ref echo args use that same selection so pinning and preflights cannot act on upstream-ignored stdin, while the pre-spawn state-policy validator deliberately keeps scanning parseable stdin alongside argv as a fail-closed content superset and treats stdin parse failures as fatal only when upstream would actually read stdin (its raw-token filter also uses the exact `--bail` token only). Same-snapshot `fill @e…` rows are guarded but do not themselves set that invalidation latch, so ordinary form fills can precede a click/submit row in one batch—see [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details) for the agent-visible contract and failure text; typed per-session tab/ref/pinning state lives in `extensions/agent-browser/lib/session-page-state.ts` and is updated from `extensions/agent-browser/index.ts` after each tool result
208
+ - keep a per-session `refSnapshot` aligned with the last successful `snapshot` (including refs merged from a successful `batch` by taking the last successful `snapshot` step in batch result order): restore its once-stored ancestral definition when reloading, resuming, or moving to a different Pi session-tree branch, retain full membership and accessible metadata from that capture for wrapper-side diagnostics, drop it on successful close commands (`close`, `quit`, or `exit`), replace it with a persisted `page-transition` invalidation after any upstream-executed `record start` attempt (direct or batch; older supported natives can swap the page before their already-active check, so failed starts count; the warning and persisted summary explicitly describe conservative ref invalidation, not an observed page change), a `record restart` with a URL operand, `window new`, `diff url`, or WebMCP `invoke` / `result` / `cancel` (these page-provided tools can mutate, rerender, or navigate; when a spawned `batch` yields no parseable result rows, for example after a wrapper timeout, planned transition steps still record the invalidation), or after a failed transition command (`eval`, `back`, `forward`, `reload`, `connect`, `state load`, `tab` selection), including reached batch transitions and failed batch `open` rows whose live URL re-verification probe observed the page (a failed transition can still have mutated or replaced the document before throwing, so keeping the verified URL must not keep the prior refs; transcript replay preserves the persisted invalidation summary), and refuse page-scoped `@e…` argv before spawn when the active tab URL no longer matches the snapshot URL, when a ref id was never in that snapshot, when the snapshot state is invalidated, or when a `batch` step would reuse `@e…` on a guarded getter or mutation step after an earlier invalidating step (including `record start`, URL-bearing `record restart`, and WebMCP `invoke` / `result` / `cancel`) without a later `snapshot` step in the same plan; batch steps come from the source upstream actually executes (raw batch argument strings exclusively when any exist — filtering only the exact `--bail` token like upstream — stdin only otherwise, via `getUpstreamEffectiveBatchSteps` in `extensions/agent-browser/lib/orchestration/batch-stdin.ts`); tab recovery (which leaves user argv/stdin and continue-on-error control flow unchanged), artifact/recording preflight, batch screenshot path preparation (parent directories are created for effective raw rows too, without rewriting raw strings), and stale-ref echo args use that same selection so pinning and preflights cannot act on upstream-ignored stdin, while the pre-spawn state-policy validator deliberately keeps scanning parseable stdin alongside argv as a fail-closed content superset and treats stdin parse failures as fatal only when upstream would actually read stdin (its raw-token filter also uses the exact `--bail` token only). Same-snapshot `fill @e…` rows are guarded but do not themselves set that invalidation latch, so ordinary form fills can precede a click/submit row in one batch—see [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details) for the agent-visible contract and failure text; typed per-session tab/ref/pinning state lives in `extensions/agent-browser/lib/session-page-state.ts` and is updated by `orchestration/extension-observation.ts` after each tool result
200
209
  - native 0.37 owns first-document setup inheritance for new tabs; the wrapper does not copy headers, user agents or other browser setup itself. The page-summary formatter displays native positive WebMCP availability while retaining raw details; it adds no discovery probe
201
210
  - when a direct or batched WebMCP call returns `status: "pending"`, or `result` / `cancel` fails while that target is unknown, keep its tab target unknown and discard same-call snapshot evidence instead of treating an immediate post-dispatch URL probe as stable; `webmcp result` / `cancel`, `get url`, and explicit navigation remain available while unknown; replace the generic blocked snapshot action with `verify-page-target-after-pending-webmcp` (`get url`), and let a completed `batch --bail` use that verification before `snapshot -i` to re-establish both target and refs
202
- - for top-level non-Electron direct `click` commands with an eligible target, install a bounded in-page target-specific event probe before upstream runs; if upstream reports success but no trusted pointer/mouse/click event reached the resolved target, fail the tool and report `details.clickDispatch` with explicit retry/inspect next actions (the wrapper does not replay clicks in-page). The probe covers `xpath=` targets and current `@e…` / `ref=` refs whose latest stored `refSnapshot.refs` role is `button`, `checkbox`, `menuitem`, `radio`, `switch`, or `tab`; it requires a unique role/name in the saved snapshot and the live candidates instead of taking a fresh pre-click snapshot that could recycle upstream refs. Ref and XPath candidates must additionally prove identity through a per-probe temporary DOM attribute read back by native `get attr <original-selector> <marker>`. Missing or mismatched identity, including XPath/frame scope mismatches, cleans up the probe and lets native click run without dispatch verification; candidate naming heuristics alone are never proof. Duplicate-name refs pass through without a probe: their old ordinal is not target identity. The probe is intentionally skipped for CSS selector clicks, unresolved `find … click` locators, and `batch`/`qa` click steps
211
+ - for top-level non-Electron direct `click` commands with an eligible target, install a bounded in-page target-specific event probe before upstream runs; if upstream reports success but no trusted pointer/mouse/click event reached the resolved target, fail the tool and report `details.clickDispatch` with explicit retry/inspect next actions (the wrapper does not replay clicks in-page). The probe covers `xpath=` targets and current `@e…` / `ref=` refs whose latest stored `refSnapshot.refs` role is `button`, `checkbox`, `menuitem`, `radio`, `switch`, or `tab`; it requires a unique role/name in the saved snapshot and the live candidates instead of taking a fresh pre-click snapshot that could recycle upstream refs. Ref and XPath candidates must additionally prove identity through a per-probe temporary DOM attribute read back by native `get attr <original-selector> <marker>`. Missing or mismatched identity, including XPath/frame scope mismatches, cleans up the probe and lets native click run without dispatch verification; candidate naming heuristics alone are never proof. Duplicate-name refs pass through without a probe: their old ordinal is not target identity. The probe is intentionally skipped when the effective native confirmation list guards `evaluate`, avoiding an optional-eval approval loop without bypassing native click policy. Dynamic action-policy files stay native-owned. It is also skipped for CSS selector clicks, unresolved `find … click` locators, and `batch`/`qa` click steps
203
212
  - skip unrelated tools and harmless Bash inspections before building prompt policy. Seed the latest raw user message on start/tree, update it on user `message_end`, and re-read its current content before parsing policy so native content replacement cannot leave stale intent. Capture that policy at queued admission without a whole-branch scan on every event. Derive narrow prompt guards only for concrete evidence invariants: explicitly requested screenshot/recording output paths block browser close until the artifact manifest verifies those paths, while bare inbound attachment paths remain inputs. The wrapper intentionally does not infer broad business/user intent from prompt text such as order/payment/post boundaries; agents must follow those instructions themselves. The artifact guard is bounded preflight policy (`details.promptGuard`, `failureCategory: "policy-blocked"`), not a reusable browser recipe layer
204
213
  - keep the existing page/selector scroll API; explicit CSS-container movement uses `Element.scrollBy` with `behavior: "instant"` before measuring offsets so smooth-scroll CSS cannot cause a premature no-movement failure
205
214
  - reject direct and effective batch `scrollintoview text=...` / `scrollinto text=...` before dispatch because current upstream can falsely report success without movement, while leaving help forms untouched; return only native recovery (`find text ... hover` or fresh snapshot/ref), leaving CSS, XPath, and current-ref behavior upstream-owned
@@ -217,7 +226,7 @@ Native close/save and explicit URL reopen remain the persistence path, not a liv
217
226
 
218
227
  ### Launch flags
219
228
 
220
- `native-session-defaults.ts` reads launch-argument/engine fields through its existing native-validated config discovery. Local Chrome composes `--no-startup-window` with the highest-priority caller arguments. Root bootstrap retains its existing helper scope; owned/fresh preparation reuses daemon-policy inspection, while explicit local callers use the same session-info probe. `process.ts` applies the scoped arguments after managed restore-policy checks, composing the existing compatibility user agent without overriding caller Chrome arguments. Configured environment/file arguments remain consistent across helpers; ordinary active calls do not receive a new launch configuration. This adds no browser launcher, profile mutation, tab cleanup, binary distribution, or persistent launch-settings state. Older custom-argument browsers can undergo native's normal hash-change restart on first use of the new default.
229
+ `native-session-defaults.ts` reads launch-argument/engine fields through its existing native-validated config discovery. Local Chrome composes `--no-startup-window` with caller CLI arguments only when native environment/config does not supply local launch defaults. Otherwise it leaves startup arguments entirely native-owned so browser, local auth, and helper calls do not alternate launch configurations. Callers wanting a single headed window with native launch defaults include `--no-startup-window` in their own `args`. Root bootstrap retains its existing helper scope; owned/fresh preparation reuses daemon-policy inspection, while explicit local callers use the same session-info probe. `process.ts` applies scoped arguments after managed restore-policy checks, composing the existing compatibility user agent without overriding caller Chrome arguments. Ordinary active calls do not receive new wrapper bootstrap settings. Native still owns CLI → environment → config precedence and hash-change restarts. This adds no browser launcher, profile mutation, tab cleanup, binary distribution, or persistent launch-settings state.
221
230
 
222
231
  Input resolution replaces URL-less `open` with native `get url` before planning, retaining requested argv separately. Effective raw/stdin batch rows use the existing native argument parser and raw-over-stdin precedence; only changed rows are rewritten. Native URL reads provide lazy launch and real lifecycle/URL output without navigating an existing page. Explicit navigation and help/version input are unchanged.
223
232
 
@@ -252,6 +261,7 @@ When a managed implicit or fresh `--session` plan reaches process execution, `de
252
261
  ## Preferring the native tool
253
262
 
254
263
  Keep the handling simple:
264
+
255
265
  - prefer the native tool through extension guidance and tool-call guards
256
266
  - do not rely on package skill overrides as the primary solution
257
267
 
@@ -268,7 +278,7 @@ Upstream restore-state persistence remains upstream-owned. The wrapper passes an
268
278
  - clear missing-binary errors
269
279
  - filtered `network requests --current-page` / `--current-origin` / `--current-url` preparation results use the same `redactPresentationData` credential redactor as ordinary diagnostics before populating `details.data` or writing `outputPath`
270
280
  - compact result summaries, including presentation-time redaction: stateful browser-context commands (`auth`, `cookies`, `storage`, `dialog`, `frame`, `state`) use field-aware value redaction and compact formatters, while other structured upstream JSON (for example `network`, `diff`, `trace` / `profiler` / `record`, `console` / `errors` / `highlight` / `inspect` / `clipboard`, `stream`, `dashboard`, and `chat`) is passed through `redactPresentationData` in `extensions/agent-browser/lib/results/presentation.ts` so model-facing `details.data` and batch roll-ups stay compact and do not echo bearer tokens, proxy passwords, or similar fields verbatim; `redactInvocationArgs` in `extensions/agent-browser/lib/runtime.ts` masks trailing values for sensitive global flags such as `--body`, `--headers`, `--password`, and `--proxy`, preserves positional rules for `cookies set` and `storage local|session set` while distinguishing native `--curl` file-import operands from inline cookie values (including failed batch diagnostics), and nested `batch` steps use the same argv and error-body scrubbing before echoing commands or errors. Shared URL redaction covers SAMLRequest/SAMLResponse/RelayState and auth-context-only state/nonce at model/persisted-artifact boundaries while retaining exact internal page-target URLs; snapshot spills are redacted before disk writes
271
- - bounded machine-readable outcome metadata on tool `details` (`resultCategory`, `successCategory`, `failureCategory`, optional `nextActions`, optional `pageChangeSummary` with observed-vs-dispatched evidence and per-step summaries on `batch`, optional `artifactVerification` with the same shape on each successful `batchSteps[]` row) so agents can branch without parsing prose; enums, classifier precedence, and generic follow-up payloads are implemented under `extensions/agent-browser/lib/results/` in focused modules (`contracts.ts` for shared types, `categories.ts` for `classifyAgentBrowserSuccessCategory` / `classifyAgentBrowserFailureCategory` / `buildAgentBrowserResultCategoryDetails`, `action-recommendations.ts` for `buildAgentBrowserNextActions`, `next-actions.ts` for the `AgentBrowserNextAction` shape and merge helpers, `recovery-actions.ts` for recovery id registries and `buildRecoveryNextActions`, `network.ts` for `classifyNetworkRequestFailure` / `summarizeNetworkFailures`, and related helpers). Per-session tab target, `refSnapshot` alignment, invalidation, and tab pinning observations flow through `extensions/agent-browser/lib/session-page-state.ts` from `extensions/agent-browser/index.ts`. Compact page-change summaries and artifact verification rollups are built in `extensions/agent-browser/lib/results/presentation.ts` (`buildPageChangeSummary`, `buildArtifactVerificationSummary`), and the human contract lives in [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details). Final public results return native `isError` after all wrapper reclassifications, without a `tool_result` repair hook. Prose retains the visible category notice; explicit parseable JSON stays unchanged. `lib/native-output.ts` and `finalizeAgentBrowserFailure` in `lib/pi-tool-rendering.ts` keep structured observations, transcript status and TUI affordances aligned (transcript semantics in the same contract doc)
281
+ - bounded machine-readable outcome metadata on tool `details` (`resultCategory`, `successCategory`, `failureCategory`, optional `nextActions`, optional `pageChangeSummary` with observed-vs-dispatched evidence and per-step summaries on `batch`, optional `artifactVerification` with the same shape on each successful `batchSteps[]` row) so agents can branch without parsing prose; enums, classifier precedence, and generic follow-up payloads are implemented under `extensions/agent-browser/lib/results/` in focused modules (`contracts.ts` for shared types, `categories.ts` for `classifyAgentBrowserSuccessCategory` / `classifyAgentBrowserFailureCategory` / `buildAgentBrowserResultCategoryDetails`, `action-recommendations.ts` for `buildAgentBrowserNextActions`, `action-contracts.ts` for the `AgentBrowserNextAction` shape and `next-actions.ts` for merge helpers, `recovery-actions.ts` for recovery id registries and `buildRecoveryNextActions`, `network.ts` for `classifyNetworkRequestFailure` / `summarizeNetworkFailures`, and related helpers). Per-session tab target, `refSnapshot` alignment, invalidation, and tab pinning observations flow through `extensions/agent-browser/lib/session-page-state.ts` through `orchestration/extension-observation.ts` and branch restore. Compact page-change summaries and artifact verification rollups are built in `results/presentation/navigation.ts` and `artifact-verification.ts` (`buildPageChangeSummary`, `buildArtifactVerificationSummary`), and the human contract lives in [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details). Final public results return native `isError` after all wrapper reclassifications, without a `tool_result` repair hook. Prose retains the visible category notice; explicit parseable JSON stays unchanged. `lib/native-output.ts` and `finalizeAgentBrowserFailure` in `lib/pi-tool-rendering.ts` keep structured observations, transcript status and TUI affordances aligned (transcript semantics in the same contract doc)
272
282
  - inline screenshots/images for the plain `screenshot` command; other image-like saves (for example `diff screenshot`) still appear in `details.artifacts` and summaries but are not auto-inlined as Pi image attachments (see [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details))
273
283
  - lightweight session convenience
274
284
  - docs, including a repo-readable command reference that mirrors the blocked direct-binary help path closely enough for normal agent work
@@ -296,6 +306,7 @@ This mirrors the playbook contract pattern described in [`TOOL_CONTRACT.md`](TOO
296
306
  ## Not the right design
297
307
 
298
308
  Avoid:
309
+
299
310
  - duplicating native CLI semantics in bespoke tools
300
311
  - compatibility layers for old `agent-browser` versions
301
312
  - deep embedded SDK-style integration
@@ -322,6 +333,7 @@ Avoid:
322
333
  ## Summary
323
334
 
324
335
  The architecture should stay:
336
+
325
337
  - thin
326
338
  - aligned to the recommended upstream release and stable support floor
327
339
  - close to upstream
@@ -0,0 +1,242 @@
1
+ # Code quality
2
+
3
+ Oxlint owns maintained-code linting, Oxfmt owns supported formatting, and TypeScript,
4
+ tests, builds, and generated-document checks remain independent gates. Use the pinned
5
+ Node runtime and npm version in `package.json`, then `npm ci --ignore-scripts`.
6
+
7
+ Correctness, long-term maintainability, and reliable enforcement are equal
8
+ requirements. Keep production complexity, size, readonly, and safety checks even
9
+ when satisfying them requires substantial restructuring. A maintainability finding
10
+ does not need to identify a current runtime bug. Refactors must improve responsibility
11
+ boundaries, explicit ownership, failure/cancellation flow, and localized changes—not
12
+ just move lines, add forwarding layers, or pass a giant mutable context everywhere.
13
+ Use already authorized exceptions when their conditions are demonstrated; further
14
+ relaxations require concrete evidence and explicit approval.
15
+
16
+ ## Commands
17
+
18
+ | Command | Purpose |
19
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
20
+ | `npm run quality` | Canonical non-modifying acceptance: clean build, checker preparation, scope/suppression policy, lint, formatting, compiler checks, tests with real-tool probes, and generated-doc/upstream-help checks |
21
+ | `npm run lint` | Policy checks followed by strict Oxlint over the complete maintained-code inventory |
22
+ | `npm run lint:agent` | Identical coverage with Oxlint agent diagnostics |
23
+ | `npm run lint:fix` | Identical policy and coverage; apply ordinary safe Oxlint fixes |
24
+ | `npm run format` | Format supported maintained files using Oxfmt |
25
+ | `npm run format:check` | Check formatting without modifying files |
26
+ | `npm run quality:policy` | Validate language coverage and parsed suppression comments; emit the current exception inventory |
27
+ | `npm run quality:scope -- --write` | Regenerate the final exact unchecked-JavaScript override after an intentional scope/tool change |
28
+ | `npm run quality:probes` | Run the focused `node:test` real-CLI regression suite |
29
+ | `npm run quality:mutations` | Require clean acceptance, then prove the real workflow rejects syntax, semantic, compiler, formatting, and allowance-isolation mutations in disposable copies |
30
+
31
+ Review fixes before committing; dangerous fixes and suggestion fixes are not part of
32
+ `lint:fix`. Run formatting after reviewed lint fixes and rerun acceptance. Failures
33
+ are never converted to success by these commands.
34
+
35
+ ## Language and role scope
36
+
37
+ The root `.oxlintrc.json` enables type-aware rules and compiler diagnostics. The
38
+ canonical `tsconfig.json` includes maintained extension TypeScript, TypeScript
39
+ scripts, tests, and explicitly checked configuration-policy JavaScript; build configuration
40
+ continues to own emitted extension files.
41
+
42
+ `scripts/code-quality-policy.mjs` discovers maintained code and effective compiler
43
+ projects using the installed TypeScript CLI. It reads inherited settings with
44
+ `tsc --showConfig` and actual project/import membership with `tsc --listFilesOnly`.
45
+ Oxc's parser identifies genuine leading `@ts-check` comments without mistaking
46
+ strings or documentation for directives.
47
+
48
+ | Source | Syntactic lint | Semantic lint | Compiler | Formatting/tests |
49
+ | --------------------------------- | -------------- | ------------- | -------- | ---------------- |
50
+ | TypeScript | Yes | Yes | Yes | Yes |
51
+ | JS with effective `checkJs: true` | Yes | Yes | Yes | Yes |
52
+ | JS with leading `@ts-check` | Yes | Yes | Yes | Yes |
53
+ | Other maintained JS | Yes | No | No | Yes |
54
+
55
+ Unchecked JavaScript is **not ignored**. The final root override lists its exact
56
+ paths and disables only the installed metadata's type-dependent rules plus the
57
+ TypeScript-only module-boundary annotation requirement. It is generated explicitly,
58
+ not dynamically weakened during a lint run. The policy gate rejects drift in files,
59
+ projects, checking directives, metadata, or root lint inventory. Checked files must
60
+ be explicit compiler-project inputs: imported-only checked JS can otherwise fall
61
+ through Oxlint's compiler project assignment. Imported unchecked JS remains available for resolution
62
+ and its TypeScript consumers retain safety checks.
63
+
64
+ There are no extra lint-only JavaScript semantic opt-ins. Test role and language
65
+ scope are separate: unchecked JS tests keep ordinary lint and test checks without
66
+ accidentally inheriting type-dependent test rules. Production limits are complexity
67
+ 10, depth 3, four parameters, 40 statements, 80 nonblank/noncomment function lines,
68
+ and 500 nonblank/noncomment file lines. Tests and verified `test/helpers` use
69
+ complexity 15, depth 4, six parameters, and no size/statement limits. Handwritten
70
+ declarations retain type/API checks without structural metrics.
71
+
72
+ ## Responsibility and ownership changes
73
+
74
+ The major decompositions preserve the tool surface and lifecycle contracts; they
75
+ separate operations and owners rather than creating a new execution framework.
76
+
77
+ | Before | After and change locality |
78
+ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
79
+ | `index.ts` combined registration, prompt caching, command execution, branch replay, and browser/recording/Electron cleanup in one closure. | The entrypoint composes registration. `extension-command-run.ts` makes preparation, durable admission, dispatch, reconciliation, and finish publication explicit. Prompt, artifacts, recording reservations, Electron resources, managed identities, page resources, branch generations, and in-flight code have distinct owners. `BrowserRuntime` is readonly composition, not an exempt mutable bag; leaf helpers receive operations, readonly views, or primitives. |
80
+ | Browser preparation and output mixed input guards, observations, native lifecycle state, artifact handling, and presentation. | `prepare.ts` orders focused validation and preparation. `process-output.ts` exposes native observation, page observation, lifecycle commit, and publication, with owned stdout-spool cleanup in `finally`. Readonly phase results carry evidence; only the existing command, page, restore, probe, and presentation owners receive exact mutation allowances. |
81
+ | Presentation assembled diagnostics, artifact verification/images, notices, output compaction, and redaction together. | `results/presentation.ts` retains the visible assembly order; diagnostic families and artifact verification, image handling, and compaction live at their respective boundaries. Mutable presentation identity is retained only at assembly operations; successful data still passes through redaction. |
82
+ | `runtime.ts` combined argv planning, identity/replay, launch compatibility, timeout rules, and credential redaction. Storage conversion combined decoding, streaming, and publication. | Planning remains pre-spawn and filesystem-free, with focused planning/replay/redaction modules and preserved exports. Journal read/replay/projection and legacy conversion are separate responsibilities; conversion still verifies the unchanged source before exclusive separate-copy publication and releases only its owned resources. |
83
+
84
+ Ordering, branch-generation guards, cancellation, append-failure behavior, native
85
+ argument presence, and cleanup ownership remain independent behavioral contracts.
86
+ The real-CLI probes also reject mutable additions to qualified owners and verify
87
+ that ordinary runtime records and parameter-property writes remain checked.
88
+
89
+ ## Corrected checker and allowance integrity
90
+
91
+ The locked baseline is Oxlint **1.87.0**, `oxlint-tsgolint` **7.0.2003**, Oxfmt
92
+ **0.72.0**, TypeScript **7.0.2**, and `oxc-parser` **0.153.0**. Framework rules use
93
+ `eslint-node-test` **1.0.1** through Oxlint's supported JS-plugin mechanism; ESLint
94
+ is its required runtime API dependency, not another configured lint owner.
95
+
96
+ The original backend has reproduced file-safe-call origin and readonly
97
+ intersection/container defects. `scripts/prepare-quality-checker.mjs` builds the
98
+ pinned backend revision `eb9339115edde6811ca94c3433adf69ea9852880` and compiler
99
+ submodule `2bd066d87f5bafd315be9f40889d0a60b9e58e0b`, applies
100
+ `patches/oxlint-tsgolint.patch`, and verifies the cached binary's fingerprint/hash.
101
+ It selects Go **1.27.1**. A clean install needs Git, Go, and network access for this
102
+ first build; no manual installed-package edits or install lifecycle hooks are needed.
103
+
104
+ All semantic lint goes through `scripts/oxlint.mjs`, which forces the verified
105
+ binary through upstream's `OXLINT_TSGOLINT_PATH`. CLI, probes, fixes, and the editor
106
+ must use this same launcher. The checked-in VS Code setting `oxc.path.oxlint` points
107
+ to `./scripts/oxlint.mjs`; the Oxc extension starts `.mjs` launchers with Node.
108
+ Keep Node 24.21.0+ available to the editor. Oxc normally resolves `node` from its
109
+ environment; an editor launched without that PATH can use its user-level
110
+ `oxc.path.node` setting to select the supported executable. Oxc 1.63+ also supports
111
+ `oxc.useExecPath: true` when the editor's bundled Node meets that floor. Do not
112
+ enable it blindly on an editor with an older bundled runtime.
113
+ For another editor, start the language server with `node scripts/oxlint.mjs --lsp`
114
+ using its documented executable mechanism. Do not substitute an independently
115
+ installed global Oxlint or the uncorrected raw backend. Root configuration is shared,
116
+ including JS scope and the actual Node test rules.
117
+
118
+ Oxlint 1.87's language server reports lint diagnostics but does not expose its CLI
119
+ compiler-diagnostic pass. Keep the editor's native TypeScript/JavaScript validation
120
+ enabled (the workspace settings do so), and retain `npm run typecheck` and the
121
+ canonical CLI as independent compiler gates. A successful lint-server handshake
122
+ does not establish compiler coverage. Oxlint 1.87 also does not merge unsaved
123
+ cross-file editor overlays into a dependent file's semantic project. Save referenced
124
+ files and reanalyze the dependent document; the canonical launcher diagnoses and
125
+ clears cross-module ownership at that save/re-pull boundary. This is an upstream
126
+ limitation shared by the unpatched backend, not a persistent native-checker cache.
127
+
128
+ `allowForKnownSafePromises` stays empty. The only safe-call registration group is
129
+ the declaration-qualified `node:test` package's `test`, `it`, `describe`, and `suite`.
130
+ Ordinary floating work, local shadows, and unrelated exports/packages retain
131
+ floating-Promise checking. The complete policy also requires owned native `t.test`
132
+ subtests; do not assume a diagnostic came from `no-floating-promises` when it came
133
+ from `node-test/no-unawaited-subtest`. `node-test/no-nested-tests` additionally rejects
134
+ imported test registration inside a test body; use an owned `t.test` subtest instead.
135
+ The repository uses direct imports, not custom registration reexports; requalify
136
+ framework scope before adopting a different registration pattern. Suite callbacks
137
+ receive an exemption only when their value uses establish exclusive native suite
138
+ ownership. Borrowing a native callable or namespace type does not establish native
139
+ value identity. Opaque module loading or native VM code execution withholds that
140
+ claim for exported callbacks, including when module resolution supplies only a
141
+ declaration or external-library target instead of maintained runtime code. The
142
+ Require analysis uses a precise target only for an explicit relative file operand
143
+ whose native resolved path equals the runtime operand; package conditions and
144
+ extension substitution remain opaque. The checker does not interpret code strings
145
+ or promise a runtime security boundary.
146
+
147
+ Native readonly allowances are declaration-qualified, not shape/name-only. They
148
+ accept the actual native contract, not mutable application additions or runtime
149
+ freezing. Generic `Map`, `Record`, `Readonly`, and callable shapes are not blanket
150
+ allowances. The correction checks native readonly map/set elements recursively
151
+ while preserving mutable-container and mutable-nested-value counterexamples.
152
+ Non-generic TS/JSDoc array aliases retain exact declared identity without introducing
153
+ wrapper types. Built-in browser `URL` and Node's `node:url` `URL` have distinct
154
+ origins; the filesystem `PathLike` contract requires the Node-qualified allowance.
155
+
156
+ `test/code-quality.test.ts` exercises actual language/compiler scope, consumer
157
+ resolution, test-role boundaries, framework diagnostics, declaration isolation,
158
+ mutable intersections, suppression policy, and formatting idempotence. Probes
159
+ check expected rule identities; setup/configuration/parser failures are not valid
160
+ negative evidence. Keep minimal unsuppressed checker reproductions when upgrading
161
+ the backend and retire the patch only after the same controls pass.
162
+
163
+ ## Semantic exceptions
164
+
165
+ Native directives must be exact, single-rule `oxlint-disable-next-line` comments
166
+ with a specific adjacent explanation. Supported semantic rules are:
167
+
168
+ - `no-await-in-loop`: journals, dependency ordering, retries, backpressure, locks,
169
+ and ordered cleanup.
170
+ - `no-control-regex`: intentionally escaped field/protocol control-character
171
+ validation.
172
+ - `typescript/no-unnecessary-condition`: necessary live lifecycle checks whose
173
+ state can change during an awaited operation.
174
+ - `typescript/prefer-readonly-parameter-types`: reproduced plain generic callback
175
+ false positives, never mutable callable properties.
176
+ - `node-test/no-conditional-assertion`, **only in tests/test helpers**: exhaustive
177
+ variant validation or independently proven fail-closed narrowing.
178
+
179
+ An explanation is not semantic proof. Review the actual ownership/ordering/guard
180
+ contract and retain boundary tests, including interrupted and uninterrupted paths.
181
+ Do not suppress floating-Promise protection to compensate for a matcher defect.
182
+ Blanket disables, multi-rule disables, ESLint directives, `@ts-ignore`, and
183
+ `@ts-nocheck` are forbidden. Described `@ts-expect-error` is accepted only in
184
+ dedicated `*.test-d.ts` negative type tests with at least ten explanation characters.
185
+ Unused native disables remain errors.
186
+
187
+ The policy command prints current paths, locations, rules, and reasons for every
188
+ comment exception. Exact configuration exceptions are reviewable in root config:
189
+
190
+ `scripts/code-quality-boundaries.mjs` is the canonical inventory of exact local
191
+ declaration and mutation boundaries, including their reasons. `quality:scope -- --write`
192
+ generates their complete rule options immediately before the final JS override;
193
+ overlapping boundaries retain all allowed declarations and the entire strict native
194
+ baseline. Never hand-edit those generated overrides or turn generic maps/sets into
195
+ blanket allowances. The inventory covers diagnostics collectors, next-action
196
+ accumulators, replay fixtures, canonical runtime/resource owners, presentation
197
+ assembly, and the browser-run reducer—not arbitrary input records or read-only views.
198
+
199
+ Reviewed native-resource readonly exceptions remain single-site directives:
200
+ `browser-journal-projection.ts` receives its native async cursor in `projectJson`;
201
+ `browser-session-conversion-stream.ts` receives native async cursors in `writeBytes`
202
+ and `inject`; `recording-reservations.ts` deliberately mutates its existing index
203
+ only in `applyRecordingArtifactsToReservations` and `retireRecordingReservation`.
204
+ These contracts do not exempt generic `AsyncIterable` or `Map` inputs elsewhere.
205
+
206
+ The exact site-policy map in `code-quality-policy.mjs` additionally permits only
207
+ the reviewed native `promisify` callback contracts, sanitized secret-error propagation,
208
+ native cancellation reason identity, and the private numeric generation-token
209
+ constructor. Their unused directives remain errors and their actual locations and
210
+ reasons appear in the emitted inventory.
211
+
212
+ | Scope | Exception | Contract/verification |
213
+ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
214
+ | Tests and test-only helpers | `no-useless-undefined.checkArguments: false` | Preserve argument presence and negative input fixtures; other rule checks remain active |
215
+ | `test/agent-browser.tool-surface.test.ts`, `test/verify-package.test.ts`, `test/doctor.test.ts` | Additionally `checkArrowFunctionBody: false` | Preserve required undefined-returning fixture callbacks |
216
+ | `managed-session-policy-lock.ts`, `browser-execution-claims.ts`, `browser-execution-claim-storage.ts`, `temp-mutation-queue.ts`, `temp-artifact-budget.ts`, `temp-root-ownership.ts`, `temp-root.ts` under the extension library | `checkArrowFunctionBody: false` only | Required undefined-returning release/error callbacks; argument checking remains active |
217
+ | `test/agent-browser.batch-fidelity.test.ts`, `test/agent-browser.native-lifecycle.test.mjs` | `no-await-in-loop: off` | Cohesive inherently ordered native lifecycle suites; original behavior tests retained |
218
+ | `scripts/verify-recording-native.mjs`, `scripts/verify-agent-browser-dogfood.ts` | Exact test role, including `checkTypePredicates: false` | Actual nonpackaged assertion harnesses, not production helpers |
219
+ | `tool-surface.ts`, `web-search.ts`, `orchestration/extension-tool-boundary.ts`, `config-validation.js`, `redaction-fields.ts` under the extension library | `max-params: 5` | Fixed SDK/public config/regex replacement callback arity; other production limits remain active |
220
+
221
+ ## Formatting, generation, and CI
222
+
223
+ Oxfmt preserves the repository's tabs, LF endings, semicolons, and existing import
224
+ order. Optional sorting and JSDoc rewriting remain off. The package manager owns
225
+ `package-lock.json`; compiled output and task artifact directories are excluded.
226
+ Generator-owned documentation must converge with Oxfmt through its generator,
227
+ not by hand-editing generated blocks or ignoring maintained documents.
228
+
229
+ `.github/workflows/code-quality.yml` installs locked dependencies, the selected Go
230
+ toolchain, and the separately installed command-reference upstream target. It runs
231
+ the real acceptance and mutation controls without modifying maintained artifacts.
232
+ The release workflow requires this job before publishing. Existing official/fork
233
+ Pi qualification and lifecycle checks remain separate and are not replaced by
234
+ quality acceptance.
235
+
236
+ Classify findings accurately: scope/configuration reductions, checker-integrity
237
+ fixes, genuine source improvements, fixture corrections, and production runtime
238
+ bugs are different outcomes. Zero diagnostics is meaningful only with scope,
239
+ suppression, allowance, typecheck, test, build, generation, and formatting gates
240
+ all passing on the exact integrated revision. Major refactors also require review
241
+ of their resulting responsibilities, ownership, API surface, asynchronous phases,
242
+ and before/after change locality. Green checks do not substitute for that review.