pi-agent-browser-native 0.9.3 → 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 (391) hide show
  1. package/CHANGELOG.md +77 -5
  2. package/README.md +103 -81
  3. package/dist/extensions/agent-browser/index.js +43057 -2031
  4. package/dist/extensions/agent-browser/lib/argv-descriptor.js +49 -26
  5. package/dist/extensions/agent-browser/lib/argv-grammar.js +82 -93
  6. package/dist/extensions/agent-browser/lib/bash-guard.js +129 -126
  7. package/dist/extensions/agent-browser/lib/batch-lifecycle.js +112 -51
  8. package/dist/extensions/agent-browser/lib/browser-execution-claim-codec.js +61 -0
  9. package/dist/extensions/agent-browser/lib/browser-execution-claim-storage.js +232 -0
  10. package/dist/extensions/agent-browser/lib/browser-execution-claims.js +202 -0
  11. package/dist/extensions/agent-browser/lib/browser-execution-identity.js +77 -0
  12. package/dist/extensions/agent-browser/lib/browser-journal-branch.js +98 -0
  13. package/dist/extensions/agent-browser/lib/browser-journal-contracts.js +1 -0
  14. package/dist/extensions/agent-browser/lib/browser-journal-projection.js +221 -0
  15. package/dist/extensions/agent-browser/lib/browser-journal-reader.js +89 -0
  16. package/dist/extensions/agent-browser/lib/browser-journal-replay.js +246 -0
  17. package/dist/extensions/agent-browser/lib/browser-journal.js +103 -394
  18. package/dist/extensions/agent-browser/lib/browser-legacy-pages.js +220 -0
  19. package/dist/extensions/agent-browser/lib/browser-legacy-projection.js +282 -0
  20. package/dist/extensions/agent-browser/lib/browser-legacy-types.js +1 -0
  21. package/dist/extensions/agent-browser/lib/browser-session-conversion-stream.js +217 -0
  22. package/dist/extensions/agent-browser/lib/browser-session-conversion.js +80 -335
  23. package/dist/extensions/agent-browser/lib/browser-transcript-contracts.js +35 -0
  24. package/dist/extensions/agent-browser/lib/browser-transcript-validation.js +166 -0
  25. package/dist/extensions/agent-browser/lib/browser-transcript.js +137 -82
  26. package/dist/extensions/agent-browser/lib/browser-value-parsing.js +15 -0
  27. package/dist/extensions/agent-browser/lib/command-capabilities.js +340 -0
  28. package/dist/extensions/agent-browser/lib/command-policy.js +107 -88
  29. package/dist/extensions/agent-browser/lib/command-taxonomy.js +49 -322
  30. package/dist/extensions/agent-browser/lib/config-policy.js +138 -343
  31. package/dist/extensions/agent-browser/lib/config-providers.js +71 -0
  32. package/dist/extensions/agent-browser/lib/config-validation.js +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 +43 -9
  82. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +106 -59
  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 +164 -60
  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 +199 -154
  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 -205
  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 -1123
  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 -968
  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 -765
  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 -821
  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 -157
  228. package/dist/extensions/agent-browser/lib/orchestration/operation-paths.js +124 -58
  229. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +197 -99
  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 +55 -246
  236. package/dist/extensions/agent-browser/lib/parsing.js +13 -4
  237. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +133 -68
  238. package/dist/extensions/agent-browser/lib/playbook.js +16 -12
  239. package/dist/extensions/agent-browser/lib/process-child.js +284 -0
  240. package/dist/extensions/agent-browser/lib/process-environment.js +13 -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 +145 -536
  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 +131 -68
  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 -13
  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 +90 -67
  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 -555
  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 -1052
  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 +116 -240
  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 -261
  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 +119 -119
  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 -1041
  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 +178 -333
  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 +17 -5
  360. package/docs/CODE_QUALITY.md +242 -0
  361. package/docs/COMMAND_REFERENCE.md +251 -220
  362. package/docs/ELECTRON.md +53 -44
  363. package/docs/RELEASE.md +18 -15
  364. package/docs/REQUIREMENTS.md +1 -0
  365. package/docs/SUPPORT_MATRIX.md +76 -75
  366. package/docs/TOOL_CONTRACT.md +145 -116
  367. package/docs/platform-smoke.md +5 -5
  368. package/package.json +143 -120
  369. package/scripts/agent-browser-capability-baseline.mjs +361 -957
  370. package/scripts/agent-browser-target.mjs +6 -2
  371. package/scripts/build.mjs +37 -8
  372. package/scripts/capability-core-commands.mjs +193 -0
  373. package/scripts/capability-options.mjs +283 -0
  374. package/scripts/capability-samples.mjs +133 -0
  375. package/scripts/capability-section.mjs +11 -0
  376. package/scripts/config.mjs +213 -114
  377. package/scripts/convert-browser-session.mjs +30 -9
  378. package/scripts/doctor-sources.mjs +195 -0
  379. package/scripts/doctor.mjs +92 -247
  380. package/scripts/platform-smoke/artifacts.mjs +38 -11
  381. package/scripts/platform-smoke/commands.mjs +104 -0
  382. package/scripts/platform-smoke/crabbox-runner.mjs +167 -80
  383. package/scripts/platform-smoke/doctor-support.mjs +157 -0
  384. package/scripts/platform-smoke/doctor-windows.mjs +230 -0
  385. package/scripts/platform-smoke/doctor.mjs +212 -320
  386. package/scripts/platform-smoke/lease-evidence.mjs +134 -0
  387. package/scripts/platform-smoke/suite-checks.mjs +98 -0
  388. package/scripts/platform-smoke/suite-evidence.mjs +281 -0
  389. package/scripts/platform-smoke/targets.mjs +158 -472
  390. package/scripts/platform-smoke.mjs +55 -40
  391. package/scripts/prepare.mjs +16 -7
@@ -1,387 +1,279 @@
1
1
  /** Platform smoke doctor. Fails before target runs when Crabbox/platform setup is missing. */
2
-
3
- import { execFileSync, execSync } from "node:child_process";
4
- import { accessSync, constants, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
5
- import { resolve } from "node:path";
6
-
2
+ import { accessSync, constants } from "node:fs";
7
3
  import { CAPABILITY_BASELINE } from "../agent-browser-capability-baseline.mjs";
8
- import { buildTargetBaseArgs } from "./crabbox-runner.mjs";
4
+ import {
5
+ checkAgentBrowserVersion,
6
+ checkArtifactRoot,
7
+ checkForbiddenProjectFiles,
8
+ commandPath,
9
+ createReporter,
10
+ env,
11
+ setting,
12
+ shell,
13
+ silent,
14
+ versionAtLeast,
15
+ } from "./doctor-support.mjs";
16
+ import { checkWindows } from "./doctor-windows.mjs";
17
+ export { disposableWindowsAgentBrowserProbe } from "./doctor-windows.mjs";
9
18
 
10
19
  const DEFAULT_UBUNTU_IMAGE = `pi-agent-browser-native-platform:node24-agent-browser${CAPABILITY_BASELINE.targetVersion}`;
11
20
 
12
- function env(name) {
13
- return process.env[name] ?? "";
14
- }
15
-
16
- function ok(label) {
17
- console.log(` ✓ ${label}`);
18
- }
19
-
20
- function warn(label) {
21
- console.log(` ⚠ ${label}`);
22
- }
23
-
24
- function fail(label, failures) {
25
- console.error(` ✗ ${label}`);
26
- failures.count += 1;
27
- }
28
-
29
- function silent(cmd, args, options = {}) {
30
- try {
31
- return execFileSync(cmd, args, { timeout: 20_000, stdio: "pipe", ...options }).toString().trim();
32
- } catch {
33
- return null;
34
- }
35
- }
36
-
37
- function shell(command, options = {}) {
38
- try {
39
- return execSync(command, { timeout: 20_000, stdio: "pipe", ...options }).toString().trim();
40
- } catch {
41
- return null;
42
- }
43
- }
44
-
45
- function hasCommand(name) {
46
- return silent("which", [name]) !== null;
47
- }
48
-
49
- function commandPath(name) {
50
- return silent("which", [name]);
51
- }
52
-
53
- function parseVersion(version) {
54
- const match = String(version).match(/\d+(?:\.\d+){0,2}/);
55
- return match ? match[0].split(".").map((part) => Number(part)) : null;
56
- }
57
-
58
- function versionAtLeast(actual, minimum) {
59
- const parsedActual = parseVersion(actual);
60
- const parsedMinimum = parseVersion(minimum);
61
- if (!parsedActual || !parsedMinimum) return false;
62
- for (let index = 0; index < Math.max(parsedActual.length, parsedMinimum.length); index += 1) {
63
- const a = parsedActual[index] ?? 0;
64
- const b = parsedMinimum[index] ?? 0;
65
- if (a > b) return true;
66
- if (a < b) return false;
67
- }
68
- return true;
69
- }
70
-
71
- function isForbiddenProjectPath(path) {
72
- return /(^|\/)\.env(?:\..*)?$/.test(path)
73
- || /(^|\/)[^/]+\.tgz$/.test(path)
74
- || /(^|\/)\.artifacts(?:\/|$)/.test(path)
75
- || /(^|\/)\.crabbox(?:\/|$)/.test(path)
76
- || /(^|\/)\.debug(?:\/|$)/.test(path)
77
- || /(^|\/)\.platform-smoke-runs(?:\/|$)/.test(path);
78
- }
79
-
80
- function npmPackFiles() {
81
- const output = silent("npm", ["pack", "--dry-run", "--json"]);
82
- if (!output) return null;
83
- try {
84
- const parsed = JSON.parse(output);
85
- return parsed[0]?.files?.map((file) => file.path) ?? [];
86
- } catch {
87
- return null;
88
- }
89
- }
90
-
91
- function checkForbiddenProjectFiles(failures) {
92
- const tracked = shell("git ls-files")?.split(/\r?\n/).filter(Boolean) ?? [];
93
- const trackedForbidden = tracked.filter(isForbiddenProjectPath);
94
- if (trackedForbidden.length === 0) ok("tracked source files exclude forbidden local artifacts");
95
- else fail(`forbidden tracked source path(s): ${trackedForbidden.join(", ")}`, failures);
96
-
97
- const localForbidden = shell("find . -maxdepth 2 \\( -name '.env' -o -name '.env.*' -o -name '*.tgz' \\) -not -path './node_modules/*' 2>/dev/null")
98
- ?.split(/\r?\n/).filter(Boolean) ?? [];
99
- if (localForbidden.length === 0) ok("no local .env or package tarball artifacts at repo top level");
100
- else fail(`forbidden local artifact(s): ${localForbidden.join(", ")}`, failures);
101
-
102
- const packFiles = npmPackFiles();
103
- if (!packFiles) {
104
- fail("could not inspect npm pack contents", failures);
105
- return;
106
- }
107
- const packedForbidden = packFiles.filter(isForbiddenProjectPath);
108
- if (packedForbidden.length === 0) ok("npm package excludes forbidden local artifacts");
109
- else fail(`forbidden npm package path(s): ${packedForbidden.join(", ")}`, failures);
110
- }
111
-
112
21
  function crabboxProviders(cbox) {
113
22
  const jsonOutput = silent(cbox, ["providers", "--json"]);
114
23
  if (jsonOutput) {
115
24
  try {
116
25
  const parsed = JSON.parse(jsonOutput);
117
- if (Array.isArray(parsed)) return parsed.map((provider) => provider.name ?? provider.id ?? provider.provider).filter(Boolean);
118
- if (Array.isArray(parsed.providers)) return parsed.providers.map((provider) => provider.name ?? provider.id ?? provider.provider).filter(Boolean);
119
- if (typeof parsed === "object" && parsed) return Object.keys(parsed.providers ?? parsed);
26
+ if (Array.isArray(parsed)) {
27
+ return parsed
28
+ .map((provider) => provider.name ?? provider.id ?? provider.provider)
29
+ .filter(Boolean);
30
+ }
31
+ if (Array.isArray(parsed.providers)) {
32
+ return parsed.providers
33
+ .map((provider) => provider.name ?? provider.id ?? provider.provider)
34
+ .filter(Boolean);
35
+ }
36
+ if (typeof parsed === "object" && parsed) {
37
+ return Object.keys(parsed.providers ?? parsed);
38
+ }
120
39
  } catch {
121
40
  // Fall through to text parsing for older or non-JSON provider output.
122
41
  }
123
42
  }
124
43
  const output = silent(cbox, ["providers"]);
125
- if (!output) return [];
126
- return output.split(/\r?\n/)
44
+ if (!output) {
45
+ return [];
46
+ }
47
+ return output
48
+ .split(/\r?\n/)
127
49
  .filter((line) => /^\S/.test(line))
128
50
  .map((line) => line.trim().split(/\s+/)[0])
129
51
  .filter(Boolean);
130
52
  }
131
53
 
132
- function checkRequiredProviders(cbox, failures) {
54
+ function checkRequiredProviders(cbox, report) {
133
55
  const providers = crabboxProviders(cbox);
134
56
  if (providers.length === 0) {
135
- fail("could not read crabbox providers", failures);
57
+ report.fail("could not read crabbox providers");
136
58
  return;
137
59
  }
138
60
  for (const provider of ["ssh", "local-container", "parallels"]) {
139
- if (providers.includes(provider)) ok(`crabbox provider available: ${provider}`);
140
- else fail(`crabbox provider missing: ${provider}`, failures);
61
+ if (providers.includes(provider)) {
62
+ report.ok(`crabbox provider available: ${provider}`);
63
+ } else {
64
+ report.fail(`crabbox provider missing: ${provider}`);
65
+ }
141
66
  }
142
67
  }
143
68
 
144
- function checkCrabboxProvider(cbox, args, label, failures) {
69
+ function checkCrabboxProvider(cbox, args, label, report) {
145
70
  const output = silent(cbox, ["doctor", ...args, "--json"]);
146
71
  if (!output) {
147
- fail(`${label} crabbox doctor failed`, failures);
72
+ report.fail(`${label} crabbox doctor failed`);
148
73
  return;
149
74
  }
150
75
  try {
151
76
  const parsed = JSON.parse(output);
152
- if (parsed.ok) ok(`${label} provider OK`);
153
- else fail(`${label} provider not ready: ${parsed.error ?? "unknown error"}`, failures);
154
- } catch {
155
- warn(`${label} provider returned non-JSON doctor output`);
156
- }
157
- }
158
-
159
- function crabbox(cbox, args, timeout = 300_000) {
160
- try {
161
- return {
162
- ok: true,
163
- stdout: execFileSync(cbox, args, { timeout, stdio: "pipe", env: { ...process.env, CRABBOX_SYNC_GIT_SEED: "false" } }).toString(),
164
- stderr: "",
165
- };
166
- } catch (error) {
167
- return {
168
- ok: false,
169
- stdout: error.stdout?.toString?.() ?? "",
170
- stderr: error.stderr?.toString?.() ?? error.message,
171
- };
172
- }
173
- }
174
-
175
- function parseLeaseId(text) {
176
- return text.match(/\bleased\s+(\S+)/)?.[1]
177
- ?? text.match(/\blease=(\S+)/)?.[1]
178
- ?? null;
179
- }
180
-
181
- export function disposableWindowsAgentBrowserProbe(cbox, config, expectedVersion) {
182
- const slug = "piab-doctor-agent-browser";
183
- const baseArgs = buildTargetBaseArgs("windows-native", config);
184
- const warm = crabbox(cbox, ["warmup", ...baseArgs, "--slug", slug, "--keep", "--reclaim"], 300_000);
185
- const leaseId = parseLeaseId(`${warm.stdout}\n${warm.stderr}`) ?? slug;
186
- if (!warm.ok) return { ok: false, message: `warmup failed: ${(warm.stderr || warm.stdout).slice(-500)}` };
187
-
188
- let outcome;
189
- try {
190
- const probeScript = `$ErrorActionPreference = "Stop"
191
- $cmd = Get-Command "agent-browser.cmd" -ErrorAction SilentlyContinue | Select-Object -First 1
192
- if (-not $cmd) { throw "agent-browser.cmd missing" }
193
- $version = & $cmd.Source --version
194
- Write-Output "PLATFORM_DOCTOR_AGENT_BROWSER_PATH=$($cmd.Source)"
195
- Write-Output "PLATFORM_DOCTOR_AGENT_BROWSER_VERSION=$version"
196
- $roots = @((Join-Path $env:USERPROFILE ".agent-browser\\browsers"), "C:\\WINDOWS\\system32\\config\\systemprofile\\.agent-browser\\browsers")
197
- $chrome = Get-ChildItem -Path $roots -Recurse -Filter chrome.exe -ErrorAction SilentlyContinue | Select-Object -First 1
198
- if (-not $chrome) { throw "agent-browser browser cache missing chrome.exe" }
199
- Write-Output "PLATFORM_DOCTOR_AGENT_BROWSER_CHROME=$($chrome.FullName)"`;
200
- const probeCommand = `powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -EncodedCommand ${Buffer.from(probeScript, "utf16le").toString("base64")}`;
201
- const run = crabbox(cbox, ["run", ...baseArgs, "--id", leaseId, "--no-sync", "--shell", probeCommand], 180_000);
202
- if (!run.ok) outcome = { ok: false, message: `probe failed: ${(run.stderr || run.stdout).slice(-700)}` };
203
- else {
204
- const output = run.stdout;
205
- const versionLine = output.match(/^PLATFORM_DOCTOR_AGENT_BROWSER_VERSION=(.*)$/m)?.[1]?.trim() ?? "";
206
- const pathLine = output.match(/^PLATFORM_DOCTOR_AGENT_BROWSER_PATH=(.*)$/m)?.[1]?.trim() ?? "";
207
- const chromeLine = output.match(/^PLATFORM_DOCTOR_AGENT_BROWSER_CHROME=(.*)$/m)?.[1]?.trim() ?? "";
208
- if (versionLine !== `agent-browser ${expectedVersion}`) outcome = { ok: false, message: `expected agent-browser ${expectedVersion}, got ${versionLine || "missing version"}` };
209
- else if (!pathLine || !chromeLine) outcome = { ok: false, message: "agent-browser path or browser cache marker missing" };
210
- else outcome = { ok: true, message: `${versionLine} | ${pathLine} | ${chromeLine}` };
211
- }
212
- } finally {
213
- const stop = crabbox(cbox, ["stop", ...baseArgs, "--id", leaseId], 90_000);
214
- if (!stop.ok) {
215
- const prior = outcome?.ok === false ? `; prior result: ${outcome.message}` : "";
216
- outcome = { ok: false, message: `cleanup failed: ${(stop.stderr || stop.stdout).slice(-500)}${prior}` };
77
+ if (parsed.ok) {
78
+ report.ok(`${label} provider OK`);
79
+ } else {
80
+ report.fail(`${label} provider not ready: ${parsed.error ?? "unknown error"}`);
217
81
  }
82
+ } catch {
83
+ report.warn(`${label} provider returned non-JSON doctor output`);
218
84
  }
219
- return outcome;
220
85
  }
221
86
 
222
- function checkAgentBrowserVersion(expectedVersion, failures, command = "agent-browser") {
223
- const version = shell(`${command} --version`);
87
+ function checkCrabboxVersion(cbox, minimum, report) {
88
+ const version = silent(cbox, ["--version"]);
224
89
  if (!version) {
225
- fail(`${command} not found or did not report a version`, failures);
90
+ report.fail("could not read Crabbox version");
226
91
  return;
227
92
  }
228
- const firstLine = version.split(/\r?\n/)[0];
229
- if (!expectedVersion || firstLine.includes(expectedVersion)) ok(`${command}: ${firstLine}`);
230
- else fail(`${command} version ${firstLine} does not match expected ${expectedVersion}`, failures);
93
+ const displayVersion = version.split(/\r?\n/)[0];
94
+ report.ok(`version: ${displayVersion}`);
95
+ if (minimum) {
96
+ if (versionAtLeast(displayVersion, minimum)) {
97
+ report.ok(`version ${displayVersion} >= ${minimum}`);
98
+ } else {
99
+ report.fail(`Crabbox version ${displayVersion} < ${minimum}`);
100
+ }
101
+ }
231
102
  }
232
103
 
233
- export async function runDoctor(config) {
234
- const failures = { count: 0 };
235
- const packageName = config?.packageName ?? "pi-agent-browser-native";
236
- const artifactRoot = config?.artifactRoot ?? ".artifacts/platform-smoke";
237
- const nodeVersion = config?.nodeValidationVersion;
238
- const agentBrowserVersion = config?.agentBrowserVersion;
239
-
240
- console.log("\n── Platform smoke config ──");
241
- ok(`package: ${packageName}`);
242
- ok(`targets: ${(config?.requiredTargets ?? []).join(", ")}`);
243
- ok(`suites: ${(config?.requiredSuites ?? []).join(", ")}`);
244
- ok(`agent-browser baseline: ${agentBrowserVersion ?? "not configured"}`);
245
-
104
+ function checkCrabboxBinary(cbox, config, report) {
246
105
  console.log("\n── Crabbox binary ──");
247
- const cbox = env("PLATFORM_SMOKE_CRABBOX") || "crabbox";
248
- const cboxPath = env("PLATFORM_SMOKE_CRABBOX") || commandPath("crabbox");
106
+ const override = env("PLATFORM_SMOKE_CRABBOX");
107
+ const cboxPath = override || commandPath("crabbox");
249
108
  if (!cboxPath) {
250
- fail("crabbox not found on PATH; install with Homebrew or set PLATFORM_SMOKE_CRABBOX", failures);
251
- } else {
252
- if (env("PLATFORM_SMOKE_CRABBOX")) {
253
- try {
254
- accessSync(cboxPath, constants.X_OK);
255
- ok(`binary: ${cboxPath}`);
256
- } catch {
257
- fail(`${cboxPath} is not executable`, failures);
258
- }
259
- } else {
260
- ok(`binary: ${cboxPath}`);
261
- }
262
- const version = silent(cbox, ["--version"]);
263
- if (version) {
264
- const displayVersion = version.split(/\r?\n/)[0];
265
- ok(`version: ${displayVersion}`);
266
- const minVersion = config?.requiredCrabbox?.minVersion;
267
- if (minVersion) {
268
- if (versionAtLeast(displayVersion, minVersion)) ok(`version ${displayVersion} >= ${minVersion}`);
269
- else fail(`Crabbox version ${displayVersion} < ${minVersion}`, failures);
270
- }
271
- } else {
272
- fail("could not read Crabbox version", failures);
109
+ report.fail("crabbox not found on PATH; install with Homebrew or set PLATFORM_SMOKE_CRABBOX");
110
+ return cboxPath;
111
+ }
112
+ if (override) {
113
+ try {
114
+ accessSync(cboxPath, constants.X_OK);
115
+ report.ok(`binary: ${cboxPath}`);
116
+ } catch {
117
+ report.fail(`${cboxPath} is not executable`);
273
118
  }
119
+ } else {
120
+ report.ok(`binary: ${cboxPath}`);
274
121
  }
122
+ checkCrabboxVersion(cbox, config?.requiredCrabbox?.minVersion, report);
123
+ return cboxPath;
124
+ }
275
125
 
126
+ function checkHostTools(config, report) {
276
127
  console.log("\n── Host tools ──");
277
- for (const [name, command] of [["node", "node --version"], ["npm", "npm --version"], ["git", "git --version"], ["tar", "tar --version"]]) {
128
+ for (const [name, command] of [
129
+ ["node", "node --version"],
130
+ ["npm", "npm --version"],
131
+ ["git", "git --version"],
132
+ ["tar", "tar --version"],
133
+ ]) {
278
134
  const output = shell(command);
279
- if (!output) fail(`${name} not found`, failures);
280
- else ok(`${name}: ${output.split(/\r?\n/)[0]}`);
135
+ if (!output) {
136
+ report.fail(`${name} not found`);
137
+ } else {
138
+ report.ok(`${name}: ${output.split(/\r?\n/)[0]}`);
139
+ }
281
140
  }
282
141
  const localNode = shell("node --version");
283
- if (nodeVersion && localNode && versionAtLeast(localNode, nodeVersion)) ok(`host Node ${localNode} >= ${nodeVersion}`);
284
- else fail(`host Node ${localNode || "unknown"} < ${nodeVersion ?? "configured minimum"}`, failures);
285
- checkAgentBrowserVersion(agentBrowserVersion, failures);
286
-
287
- console.log("\n── Crabbox providers ──");
288
- if (cboxPath) {
289
- checkRequiredProviders(cbox, failures);
290
- const ubuntuImage = env("PLATFORM_SMOKE_UBUNTU_IMAGE") || config?.ubuntuContainerImage || DEFAULT_UBUNTU_IMAGE;
291
- checkCrabboxProvider(cbox, ["--provider", "local-container", "--local-container-image", ubuntuImage], "ubuntu local-container", failures);
292
- const macUser = env("PLATFORM_SMOKE_MAC_USER") || env("USER");
293
- const macHost = env("PLATFORM_SMOKE_MAC_HOST") || config?.macos?.host || "localhost";
294
- const macPort = String(env("PLATFORM_SMOKE_MAC_PORT") || config?.macos?.port || 22);
295
- const macRoot = env("PLATFORM_SMOKE_MAC_WORK_ROOT") || config?.macos?.workRoot || `/Users/${macUser}/crabbox/${packageName}`;
296
- checkCrabboxProvider(cbox, ["--provider", "ssh", "--target", "macos", "--static-host", macHost, "--static-user", macUser, "--static-port", macPort, "--static-work-root", macRoot], "macOS ssh", failures);
142
+ const nodeVersion = config?.nodeValidationVersion;
143
+ if (nodeVersion && localNode && versionAtLeast(localNode, nodeVersion)) {
144
+ report.ok(`host Node ${localNode} >= ${nodeVersion}`);
145
+ } else {
146
+ report.fail(`host Node ${localNode || "unknown"} < ${nodeVersion ?? "configured minimum"}`);
297
147
  }
148
+ checkAgentBrowserVersion(config?.agentBrowserVersion, report);
149
+ }
150
+
151
+ function macSettings(config, packageName) {
152
+ const user = env("PLATFORM_SMOKE_MAC_USER") || env("USER");
153
+ return {
154
+ user,
155
+ host: setting("PLATFORM_SMOKE_MAC_HOST", config?.macos?.host, "localhost"),
156
+ port: String(setting("PLATFORM_SMOKE_MAC_PORT", config?.macos?.port, 22)),
157
+ workRoot: setting(
158
+ "PLATFORM_SMOKE_MAC_WORK_ROOT",
159
+ config?.macos?.workRoot,
160
+ `/Users/${user}/crabbox/${packageName}`,
161
+ ),
162
+ };
163
+ }
164
+
165
+ function checkProviders(cbox, config, settings, report) {
166
+ checkRequiredProviders(cbox, report);
167
+ checkCrabboxProvider(
168
+ cbox,
169
+ ["--provider", "local-container", "--local-container-image", settings.ubuntuImage],
170
+ "ubuntu local-container",
171
+ report,
172
+ );
173
+ const mac = macSettings(config, settings.packageName);
174
+ checkCrabboxProvider(
175
+ cbox,
176
+ [
177
+ "--provider",
178
+ "ssh",
179
+ "--target",
180
+ "macos",
181
+ "--static-host",
182
+ mac.host,
183
+ "--static-user",
184
+ mac.user,
185
+ "--static-port",
186
+ mac.port,
187
+ "--static-work-root",
188
+ mac.workRoot,
189
+ ],
190
+ "macOS ssh",
191
+ report,
192
+ );
193
+ }
298
194
 
195
+ function checkDocker(ubuntuImage, report) {
299
196
  console.log("\n── Docker / Ubuntu ──");
300
197
  const dockerVersion = shell("docker info --format '{{.ServerVersion}}'");
301
- if (dockerVersion) ok(`Docker ${dockerVersion}`);
302
- else fail("Docker is not available or not running", failures);
303
- const ubuntuImage = env("PLATFORM_SMOKE_UBUNTU_IMAGE") || config?.ubuntuContainerImage || DEFAULT_UBUNTU_IMAGE;
304
- ok(`Ubuntu image: ${ubuntuImage}`);
305
-
306
- console.log("\n── macOS SSH ──");
307
- const sshUser = env("PLATFORM_SMOKE_MAC_USER") || env("USER");
308
- const sshHost = env("PLATFORM_SMOKE_MAC_HOST") || config?.macos?.host || "localhost";
309
- const sshPort = String(env("PLATFORM_SMOKE_MAC_PORT") || config?.macos?.port || 22);
310
- const sshProbe = shell(`ssh -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no -p ${sshPort} ${sshUser}@${sshHost} 'node --version && npm --version && git --version && agent-browser --version'`);
311
- if (sshProbe) {
312
- ok(`SSH ${sshUser}@${sshHost}: ${sshProbe.split(/\r?\n/).join(" | ")}`);
313
- if (agentBrowserVersion && !sshProbe.includes(agentBrowserVersion)) fail(`macOS SSH agent-browser does not match expected ${agentBrowserVersion}`, failures);
198
+ if (dockerVersion) {
199
+ report.ok(`Docker ${dockerVersion}`);
314
200
  } else {
315
- fail(`SSH probe failed for ${sshUser}@${sshHost}`, failures);
201
+ report.fail("Docker is not available or not running");
316
202
  }
203
+ report.ok(`Ubuntu image: ${ubuntuImage}`);
204
+ }
317
205
 
318
- if ((config?.requiredTargets ?? []).includes("windows-native")) {
319
- console.log("\n── Windows native / Parallels ──");
320
- if (!hasCommand("prlctl")) {
321
- fail("prlctl not found", failures);
322
- } else {
323
- ok("prlctl found");
324
- const vmName = env("PLATFORM_SMOKE_WINDOWS_VM") || config?.windowsParallels?.sourceVm || "pi-extension-windows-template";
325
- const snapshot = env("PLATFORM_SMOKE_WINDOWS_SNAPSHOT") || config?.windowsParallels?.snapshot || "crabbox-ready";
326
- const user = env("PLATFORM_SMOKE_WINDOWS_USER") || config?.windowsParallels?.user || env("USER");
327
- const workRoot = env("PLATFORM_SMOKE_WINDOWS_WORK_ROOT") || config?.windowsParallels?.workRoot || `C:\\crabbox\\${packageName}`;
328
- const list = shell("prlctl list -a --no-header 2>/dev/null");
329
- if (!list) {
330
- fail("prlctl list returned no VMs", failures);
331
- } else if (!list.includes(vmName)) {
332
- fail(`Windows VM ${vmName} not found`, failures);
333
- } else {
334
- ok(`Windows VM ${vmName} found`);
335
- const status = shell(`prlctl status "${vmName.replace(/"/g, "\\\"")}" 2>/dev/null`);
336
- if (/\bstopped\b/i.test(status ?? "")) ok(`Windows source VM ${vmName} is stopped`);
337
- else fail(`Windows source VM ${vmName} must be stopped for forkable snapshot use; current status: ${status ?? "unknown"}`, failures);
338
- const snapshotsJson = shell(`prlctl snapshot-list "${vmName.replace(/"/g, "\\\"")}" -j 2>/dev/null`);
339
- let snapshotMatch = null;
340
- try {
341
- const snapshots = JSON.parse(snapshotsJson ?? "{}");
342
- snapshotMatch = Object.entries(snapshots).find(([id, data]) => id === snapshot || data?.name === snapshot);
343
- } catch {
344
- // Fall through to the failure below.
345
- }
346
- if (snapshotMatch) {
347
- ok(`snapshot ${snapshot} found`);
348
- const snapshotState = snapshotMatch[1]?.state ?? "unknown";
349
- if (snapshotState === "poweroff") ok(`snapshot ${snapshot} state is poweroff`);
350
- else fail(`snapshot ${snapshot} must be poweroff; current snapshot state: ${snapshotState}`, failures);
351
- } else {
352
- fail(`snapshot ${snapshot} not found on ${vmName}`, failures);
353
- }
354
- checkCrabboxProvider(cbox, ["--provider", "parallels", "--target", "windows", "--windows-mode", "normal", "--parallels-source", vmName, "--parallels-source-snapshot", snapshot, "--parallels-user", user, "--parallels-work-root", workRoot], "windows parallels", failures);
355
- const agentBrowserProbe = disposableWindowsAgentBrowserProbe(cbox, { ...config, windowsParallels: { ...config?.windowsParallels, sourceVm: vmName, snapshot, user, workRoot } }, agentBrowserVersion);
356
- if (agentBrowserProbe.ok) ok(`Windows disposable agent-browser: ${agentBrowserProbe.message}`);
357
- else fail(`Windows disposable agent-browser probe failed: ${agentBrowserProbe.message}`, failures);
358
- }
359
- }
360
- } else {
361
- console.log("\n── Windows native / Parallels ──");
362
- warn("windows-native is not listed in requiredTargets for this configuration");
206
+ function checkMacSsh(config, packageName, report) {
207
+ console.log("\n── macOS SSH ──");
208
+ const mac = macSettings(config, packageName);
209
+ const probe = shell(
210
+ `ssh -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no -p ${mac.port} ${mac.user}@${mac.host} 'node --version && npm --version && git --version && agent-browser --version'`,
211
+ );
212
+ if (!probe) {
213
+ report.fail(`SSH probe failed for ${mac.user}@${mac.host}`);
214
+ return;
363
215
  }
364
-
365
- console.log("\n── Artifact root ──");
366
- const artRoot = resolve(process.cwd(), artifactRoot);
367
- try {
368
- mkdirSync(artRoot, { recursive: true });
369
- const probe = resolve(artRoot, ".doctor-write-test");
370
- writeFileSync(probe, "ok");
371
- unlinkSync(probe);
372
- ok(`writable: ${artRoot}`);
373
- } catch (error) {
374
- fail(`artifact root not writable: ${error.message}`, failures);
216
+ report.ok(`SSH ${mac.user}@${mac.host}: ${probe.split(/\r?\n/).join(" | ")}`);
217
+ const expectedVersion = config?.agentBrowserVersion;
218
+ if (expectedVersion && !probe.includes(expectedVersion)) {
219
+ report.fail(`macOS SSH agent-browser does not match expected ${expectedVersion}`);
375
220
  }
221
+ }
376
222
 
223
+ function doctorSettings(config) {
224
+ return {
225
+ packageName: config?.packageName ?? "pi-agent-browser-native",
226
+ artifactRoot: config?.artifactRoot ?? ".artifacts/platform-smoke",
227
+ targets: (config?.requiredTargets ?? []).join(", "),
228
+ suites: (config?.requiredSuites ?? []).join(", "),
229
+ agentBrowserVersion: config?.agentBrowserVersion,
230
+ };
231
+ }
232
+
233
+ export async function runDoctor(config) {
234
+ const report = createReporter();
235
+ const settings = doctorSettings(config);
236
+ const { packageName, artifactRoot } = settings;
237
+ console.log("\n── Platform smoke config ──");
238
+ report.ok(`package: ${packageName}`);
239
+ report.ok(`targets: ${settings.targets}`);
240
+ report.ok(`suites: ${settings.suites}`);
241
+ report.ok(`agent-browser baseline: ${settings.agentBrowserVersion ?? "not configured"}`);
242
+ const cbox = env("PLATFORM_SMOKE_CRABBOX") || "crabbox";
243
+ const cboxPath = checkCrabboxBinary(cbox, config, report);
244
+ checkHostTools(config, report);
245
+ console.log("\n── Crabbox providers ──");
246
+ const ubuntuImage = setting(
247
+ "PLATFORM_SMOKE_UBUNTU_IMAGE",
248
+ config?.ubuntuContainerImage,
249
+ DEFAULT_UBUNTU_IMAGE,
250
+ );
251
+ if (cboxPath) {
252
+ checkProviders(cbox, config, { packageName, ubuntuImage }, report);
253
+ }
254
+ checkDocker(ubuntuImage, report);
255
+ checkMacSsh(config, packageName, report);
256
+ checkWindows({
257
+ cbox,
258
+ config,
259
+ packageName,
260
+ agentBrowserVersion: settings.agentBrowserVersion,
261
+ report,
262
+ checkCrabboxProvider,
263
+ });
264
+ checkArtifactRoot(artifactRoot, report);
377
265
  console.log("\n── Repository hygiene ──");
378
266
  const status = shell("git status --short");
379
- if (status) warn(`${status.split(/\r?\n/).length} uncommitted change(s) recorded for smoke evidence`);
380
- else ok("git status clean");
381
- checkForbiddenProjectFiles(failures);
382
-
383
- console.log(`\n=== Results: ${failures.count} failure(s) ===`);
384
- if (failures.count > 0) {
267
+ if (status) {
268
+ report.warn(
269
+ `${status.split(/\r?\n/).length} uncommitted change(s) recorded for smoke evidence`,
270
+ );
271
+ } else {
272
+ report.ok("git status clean");
273
+ }
274
+ checkForbiddenProjectFiles(report);
275
+ console.log(`\n=== Results: ${report.count} failure(s) ===`);
276
+ if (report.count > 0) {
385
277
  console.log("Fix doctor failures before running smoke:platform:all.");
386
278
  process.exitCode = 1;
387
279
  } else {