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
@@ -0,0 +1,195 @@
1
+ /** Read-only Pi settings and autoload source discovery for the package doctor. */
2
+ import { homedir } from "node:os";
3
+ import { dirname, isAbsolute, resolve, sep } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import stripJsonComments from "strip-json-comments";
6
+
7
+ const PACKAGE_NAME = "pi-agent-browser-native";
8
+ const REPO_URL_FRAGMENT = "github.com/fitchmultz/pi-agent-browser-native";
9
+ const EXTENSION_ENTRYPOINTS = [
10
+ "extensions/agent-browser/index.ts",
11
+ "dist/extensions/agent-browser/index.js",
12
+ ];
13
+ const THIS_PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
14
+
15
+ function isInsidePath(childPath, parentPath) {
16
+ const child = resolve(childPath);
17
+ const parent = resolve(parentPath);
18
+ return child === parent || child.startsWith(`${parent}${sep}`);
19
+ }
20
+
21
+ function expandUserPath(path) {
22
+ if (path === "~") {
23
+ return homedir();
24
+ }
25
+ if (path.startsWith("~/")) {
26
+ return resolve(homedir(), path.slice(2));
27
+ }
28
+ return path;
29
+ }
30
+
31
+ function isPathLikeSource(source) {
32
+ return (
33
+ isAbsolute(source) ||
34
+ source.startsWith("./") ||
35
+ source.startsWith("../") ||
36
+ source.startsWith("~")
37
+ );
38
+ }
39
+
40
+ function sourceLooksLikeThisPackage(source, cwd, sourceBaseDir = cwd) {
41
+ const text = String(source ?? "").trim();
42
+ if (text.length === 0) {
43
+ return false;
44
+ }
45
+ if (
46
+ /^npm:pi-agent-browser-native(?:@|$)/.test(text) ||
47
+ text === PACKAGE_NAME ||
48
+ text.includes(REPO_URL_FRAGMENT)
49
+ ) {
50
+ return true;
51
+ }
52
+ if (!isPathLikeSource(text)) {
53
+ return false;
54
+ }
55
+ const resolvedSource = resolve(sourceBaseDir, expandUserPath(text));
56
+ return [cwd, THIS_PACKAGE_ROOT].some(
57
+ (root) =>
58
+ resolvedSource === root ||
59
+ EXTENSION_ENTRYPOINTS.some((entrypoint) =>
60
+ isInsidePath(resolve(root, entrypoint), resolvedSource),
61
+ ),
62
+ );
63
+ }
64
+
65
+ function arrayEntries(value) {
66
+ return Array.isArray(value) ? value.entries() : [];
67
+ }
68
+
69
+ function entrySource(entry) {
70
+ if (typeof entry === "string") {
71
+ return entry;
72
+ }
73
+ if (entry && typeof entry === "object") {
74
+ return entry.source ?? entry.path ?? entry.package;
75
+ }
76
+ }
77
+
78
+ function collectSettingsSources(settings, settingsPath, cwd) {
79
+ const sources = [];
80
+ const sourceBaseDir = dirname(settingsPath);
81
+ for (const [field, kind] of [
82
+ ["packages", "package"],
83
+ ["extensions", "extension"],
84
+ ]) {
85
+ for (const [index, entry] of arrayEntries(settings?.[field])) {
86
+ const source = entrySource(entry);
87
+ if (sourceLooksLikeThisPackage(source, cwd, sourceBaseDir)) {
88
+ sources.push({
89
+ kind,
90
+ source: String(source),
91
+ location: `${settingsPath} ${field}[${index}]`,
92
+ });
93
+ }
94
+ }
95
+ }
96
+ return sources;
97
+ }
98
+
99
+ async function inspectSettingsPath({ path, cwd, readText }) {
100
+ try {
101
+ const text = await readText(path);
102
+ if (text === undefined) {
103
+ return { sources: [], warnings: [] };
104
+ }
105
+ const settings = JSON.parse(stripJsonComments(text));
106
+ return { sources: collectSettingsSources(settings, path, cwd), warnings: [] };
107
+ } catch (error) {
108
+ return {
109
+ sources: [],
110
+ warnings: [
111
+ `Could not inspect Pi settings ${path}: ${error instanceof Error ? error.message : String(error)}`,
112
+ ],
113
+ };
114
+ }
115
+ }
116
+
117
+ async function collectRepoLocalSources({ cwd, pathExists }) {
118
+ const candidates = [
119
+ resolve(cwd, ".pi/extensions/agent-browser.ts"),
120
+ resolve(cwd, ".pi/extensions/agent-browser/index.ts"),
121
+ ];
122
+ const sources = [];
123
+ for (const candidate of candidates) {
124
+ // Inspect one autoload location at a time to preserve the injected read-only I/O order.
125
+ // oxlint-disable-next-line no-await-in-loop
126
+ if (await pathExists(candidate)) {
127
+ sources.push({
128
+ kind: "repo-local",
129
+ source: candidate,
130
+ location: `${candidate} repo-local autoload`,
131
+ });
132
+ }
133
+ }
134
+ return sources;
135
+ }
136
+
137
+ /**
138
+ * @param {{cwd: string, agentDir: string, settingsPaths: readonly string[], readText: (path: string) => Promise<string | undefined>, pathExists: (path: string) => Promise<boolean>}} options
139
+ * @returns {Promise<{status: "fail" | "pass" | "warn", title: string, lines: string[], warnings: string[]}>}
140
+ */
141
+ export async function checkPiSources({ cwd, agentDir, settingsPaths, readText, pathExists }) {
142
+ const defaultSettingsPaths = [
143
+ resolve(agentDir, "settings.json"),
144
+ resolve(cwd, ".pi/settings.json"),
145
+ ];
146
+ const allSettingsPaths = [
147
+ ...new Set([...defaultSettingsPaths, ...settingsPaths].map((path) => resolve(path))),
148
+ ];
149
+ const sources = [];
150
+ const warnings = [];
151
+ for (const path of allSettingsPaths) {
152
+ // Settings are inspected in configured precedence order; injected I/O preserves that order.
153
+ // oxlint-disable-next-line no-await-in-loop
154
+ if (await pathExists(path)) {
155
+ // Finish reading this settings file before reporting and inspecting the next source.
156
+ // oxlint-disable-next-line no-await-in-loop
157
+ const result = await inspectSettingsPath({ path, cwd, readText });
158
+ sources.push(...result.sources);
159
+ warnings.push(...result.warnings);
160
+ }
161
+ }
162
+ sources.push(...(await collectRepoLocalSources({ cwd, pathExists })));
163
+ if (sources.length > 1) {
164
+ return {
165
+ status: "fail",
166
+ title: "Duplicate pi-agent-browser-native sources detected.",
167
+ lines: [
168
+ "Pi may register multiple `agent_browser` tools when a checkout source and a package source are both active.",
169
+ "Detected sources:",
170
+ ...sources.map((source) => `- ${source.source} from ${source.location}`),
171
+ "Keep exactly one active source:",
172
+ "- for normal use: keep `pi install npm:pi-agent-browser-native` and remove/disable checkout paths from Pi settings",
173
+ "- for temporary package or checkout trials: use `pi --approve --no-extensions -e <source>` when you intentionally trust the current project, or omit `--approve` to let Pi prompt in interactive mode",
174
+ "- for configured-source lifecycle validation: keep exactly one checkout or package source, then launch plain `pi`",
175
+ ],
176
+ warnings,
177
+ };
178
+ }
179
+ if (sources.length === 1) {
180
+ return {
181
+ status: "pass",
182
+ title: "No duplicate pi-agent-browser-native sources detected.",
183
+ lines: [`Detected source: ${sources[0].source} from ${sources[0].location}`],
184
+ warnings,
185
+ };
186
+ }
187
+ return {
188
+ status: "warn",
189
+ title: "No configured pi-agent-browser-native source was found in inspected Pi settings.",
190
+ lines: [
191
+ "This is OK for isolated runs such as `pi --no-extensions -e npm:pi-agent-browser-native`, but normal package use should install exactly one source with `pi install npm:pi-agent-browser-native`.",
192
+ ],
193
+ warnings,
194
+ };
195
+ }
@@ -11,46 +11,61 @@ import { execFile as execFileCallback } from "node:child_process";
11
11
  import { realpathSync } from "node:fs";
12
12
  import { access, readFile } from "node:fs/promises";
13
13
  import { homedir } from "node:os";
14
- import { dirname, isAbsolute, resolve, sep } from "node:path";
14
+ import { resolve } from "node:path";
15
15
  import { fileURLToPath } from "node:url";
16
16
  import { promisify } from "node:util";
17
17
 
18
18
  import { CAPABILITY_BASELINE_SOURCE } from "./agent-browser-capability-baseline.mjs";
19
- import { MINIMUM_AGENT_BROWSER_VERSION, TARGET_AGENT_BROWSER_SOURCE, TARGET_AGENT_BROWSER_VERSION, isSupportedAgentBrowserVersion } from "./agent-browser-target.mjs";
19
+ import { checkPiSources } from "./doctor-sources.mjs";
20
+ import {
21
+ MINIMUM_AGENT_BROWSER_VERSION,
22
+ TARGET_AGENT_BROWSER_SOURCE,
23
+ TARGET_AGENT_BROWSER_VERSION,
24
+ isSupportedAgentBrowserVersion,
25
+ } from "./agent-browser-target.mjs";
20
26
 
21
27
  const execFile = promisify(execFileCallback);
22
- const PACKAGE_NAME = "pi-agent-browser-native";
23
- const REPO_URL_FRAGMENT = "github.com/fitchmultz/pi-agent-browser-native";
24
- const EXTENSION_ENTRYPOINTS = Object.freeze([
25
- "extensions/agent-browser/index.ts",
26
- "dist/extensions/agent-browser/index.js",
27
- ]);
28
28
  const RECOMMENDED_VERSION = TARGET_AGENT_BROWSER_VERSION;
29
29
  export const MINIMUM_PI_VERSION = "1.0.0";
30
30
  const DEFAULT_AGENT_DIR = resolve(homedir(), ".pi/agent");
31
- const THIS_PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
31
+
32
+ /** @typedef {{readonly status: "pass" | "warn" | "fail", readonly title: string, readonly lines: readonly string[], readonly warnings?: readonly string[]}} DoctorCheck */
33
+ /** @typedef {{readonly checks: readonly DoctorCheck[], readonly failures: readonly DoctorCheck[], readonly warnings: readonly string[]}} DoctorReport */
34
+ /** @typedef {{readonly cwd?: string, readonly agentDir?: string, readonly settingsPaths?: readonly string[], readonly skipSourceCheck?: boolean, readonly readText?: (path: string) => Promise<string | undefined>, readonly pathExists?: (path: string) => Promise<boolean>, readonly runAgentBrowser?: (args: readonly string[]) => Promise<string>, readonly runPi?: (args: readonly string[]) => Promise<string>}} DoctorOptions */
32
35
 
33
36
  export function normalizeAgentBrowserVersion(output) {
34
- return String(output ?? "").trim().replace(/^agent-browser\s+/, "");
37
+ return String(output ?? "")
38
+ .trim()
39
+ .replace(/^agent-browser\s+/, "");
35
40
  }
36
41
 
37
42
  export function normalizePiVersion(output) {
38
- return String(output ?? "").trim().replace(/^pi\s+/, "");
43
+ return String(output ?? "")
44
+ .trim()
45
+ .replace(/^pi\s+/, "");
39
46
  }
40
47
 
41
48
  function parseVersionParts(version) {
42
49
  const match = String(version ?? "").match(/^(\d+)\.(\d+)\.(\d+)(?:\b|[-+])/);
43
- if (!match) return undefined;
50
+ if (!match) {
51
+ return;
52
+ }
44
53
  return match.slice(1).map((part) => Number.parseInt(part, 10));
45
54
  }
46
55
 
47
56
  export function versionAtLeast(actual, minimum) {
48
57
  const actualParts = parseVersionParts(actual);
49
58
  const minimumParts = parseVersionParts(minimum);
50
- if (!actualParts || !minimumParts) return undefined;
59
+ if (!actualParts || !minimumParts) {
60
+ return;
61
+ }
51
62
  for (let index = 0; index < minimumParts.length; index += 1) {
52
- if (actualParts[index] > minimumParts[index]) return true;
53
- if (actualParts[index] < minimumParts[index]) return false;
63
+ if (actualParts[index] > minimumParts[index]) {
64
+ return true;
65
+ }
66
+ if (actualParts[index] < minimumParts[index]) {
67
+ return false;
68
+ }
54
69
  }
55
70
  return true;
56
71
  }
@@ -98,7 +113,7 @@ export function parseCliArgs(argv = process.argv.slice(2)) {
98
113
 
99
114
  for (let index = 0; index < argv.length; index += 1) {
100
115
  const arg = argv[index];
101
- if (arg === "-h" || arg === "--help") {
116
+ if (["-h", "--help"].includes(arg)) {
102
117
  parsed.showHelp = true;
103
118
  continue;
104
119
  }
@@ -106,15 +121,17 @@ export function parseCliArgs(argv = process.argv.slice(2)) {
106
121
  parsed.skipSourceCheck = true;
107
122
  continue;
108
123
  }
109
- if (arg === "--cwd" || arg === "--agent-dir" || arg === "--settings") {
124
+ if (["--cwd", "--agent-dir", "--settings"].includes(arg)) {
110
125
  const value = argv[index + 1];
111
126
  if (value === undefined || value.startsWith("--")) {
112
127
  throw new Error(`${arg} requires a value. Run with --help for usage.`);
113
128
  }
114
129
  index += 1;
115
- if (arg === "--cwd") parsed.cwd = value;
116
- if (arg === "--agent-dir") parsed.agentDir = value;
117
- if (arg === "--settings") parsed.settingsPaths.push(value);
130
+ if (arg === "--settings") {
131
+ parsed.settingsPaths.push(value);
132
+ } else {
133
+ parsed[arg === "--cwd" ? "cwd" : "agentDir"] = value;
134
+ }
118
135
  continue;
119
136
  }
120
137
  throw new Error(`Unknown option: ${arg}. Run with --help for usage.`);
@@ -124,12 +141,18 @@ export function parseCliArgs(argv = process.argv.slice(2)) {
124
141
  }
125
142
 
126
143
  async function defaultRunAgentBrowser(args) {
127
- const { stdout, stderr } = await execFile("agent-browser", args, { maxBuffer: 1024 * 1024, ...buildNpmShimExecOptions(process.platform) });
144
+ const { stdout, stderr } = await execFile("agent-browser", args, {
145
+ maxBuffer: 1024 * 1024,
146
+ ...buildNpmShimExecOptions(process.platform),
147
+ });
128
148
  return `${stdout}${stderr}`;
129
149
  }
130
150
 
131
151
  async function defaultRunPi(args) {
132
- const { stdout, stderr } = await execFile("pi", args, { maxBuffer: 1024 * 1024, ...buildNpmShimExecOptions(process.platform) });
152
+ const { stdout, stderr } = await execFile("pi", args, {
153
+ maxBuffer: 1024 * 1024,
154
+ ...buildNpmShimExecOptions(process.platform),
155
+ });
133
156
  return `${stdout}${stderr}`;
134
157
  }
135
158
 
@@ -150,164 +173,6 @@ async function defaultPathExists(path) {
150
173
  }
151
174
  }
152
175
 
153
- function isInsidePath(childPath, parentPath) {
154
- const child = resolve(childPath);
155
- const parent = resolve(parentPath);
156
- return child === parent || child.startsWith(`${parent}${sep}`);
157
- }
158
-
159
- function expandUserPath(path) {
160
- if (path === "~") return homedir();
161
- if (path.startsWith("~/")) return resolve(homedir(), path.slice(2));
162
- return path;
163
- }
164
-
165
- function isPathLikeSource(source) {
166
- return isAbsolute(source) || source.startsWith("./") || source.startsWith("../") || source.startsWith("~");
167
- }
168
-
169
- function sourceLooksLikeThisPackage(source, cwd, sourceBaseDir = cwd) {
170
- const text = String(source ?? "").trim();
171
- if (text.length === 0) return false;
172
- if (/^npm:pi-agent-browser-native(?:@|$)/.test(text)) return true;
173
- if (text === PACKAGE_NAME) return true;
174
- if (text.includes(REPO_URL_FRAGMENT)) return true;
175
-
176
- if (!isPathLikeSource(text)) return false;
177
- const resolvedSource = resolve(sourceBaseDir, expandUserPath(text));
178
- const cwdEntrypoints = EXTENSION_ENTRYPOINTS.map((entrypoint) => resolve(cwd, entrypoint));
179
- const packageEntrypoints = EXTENSION_ENTRYPOINTS.map((entrypoint) => resolve(THIS_PACKAGE_ROOT, entrypoint));
180
- return (
181
- resolvedSource === cwd ||
182
- resolvedSource === THIS_PACKAGE_ROOT ||
183
- cwdEntrypoints.some((entrypoint) => resolvedSource === entrypoint || isInsidePath(entrypoint, resolvedSource)) ||
184
- packageEntrypoints.some((entrypoint) => resolvedSource === entrypoint || isInsidePath(entrypoint, resolvedSource))
185
- );
186
- }
187
-
188
- function stripJsonComments(text) {
189
- let result = "";
190
- let inString = false;
191
- let quote = "";
192
- let escaped = false;
193
- let inLineComment = false;
194
- let inBlockComment = false;
195
-
196
- for (let index = 0; index < text.length; index += 1) {
197
- const char = text[index];
198
- const next = text[index + 1];
199
-
200
- if (inLineComment) {
201
- if (char === "\n") {
202
- inLineComment = false;
203
- result += char;
204
- }
205
- continue;
206
- }
207
- if (inBlockComment) {
208
- if (char === "*" && next === "/") {
209
- inBlockComment = false;
210
- index += 1;
211
- }
212
- continue;
213
- }
214
- if (inString) {
215
- result += char;
216
- if (escaped) {
217
- escaped = false;
218
- continue;
219
- }
220
- if (char === "\\") {
221
- escaped = true;
222
- continue;
223
- }
224
- if (char === quote) {
225
- inString = false;
226
- }
227
- continue;
228
- }
229
- if (char === '"' || char === "'") {
230
- inString = true;
231
- quote = char;
232
- result += char;
233
- continue;
234
- }
235
- if (char === "/" && next === "/") {
236
- inLineComment = true;
237
- index += 1;
238
- continue;
239
- }
240
- if (char === "/" && next === "*") {
241
- inBlockComment = true;
242
- index += 1;
243
- continue;
244
- }
245
- result += char;
246
- }
247
- return result;
248
- }
249
-
250
- function parseSettingsText(text, path) {
251
- return JSON.parse(stripJsonComments(text));
252
- }
253
-
254
- function arrayEntries(value) {
255
- return Array.isArray(value) ? value.entries() : [];
256
- }
257
-
258
- function entrySource(entry) {
259
- if (typeof entry === "string") return entry;
260
- if (entry && typeof entry === "object") return entry.source ?? entry.path ?? entry.package;
261
- return undefined;
262
- }
263
-
264
- function collectSettingsSources(settings, settingsPath, cwd) {
265
- const sources = [];
266
- const sourceBaseDir = dirname(settingsPath);
267
- for (const [index, entry] of arrayEntries(settings?.packages)) {
268
- const source = entrySource(entry);
269
- if (sourceLooksLikeThisPackage(source, cwd, sourceBaseDir)) {
270
- sources.push({ kind: "package", source: String(source), location: `${settingsPath} packages[${index}]` });
271
- }
272
- }
273
- for (const [index, entry] of arrayEntries(settings?.extensions)) {
274
- const source = entrySource(entry);
275
- if (sourceLooksLikeThisPackage(source, cwd, sourceBaseDir)) {
276
- sources.push({ kind: "extension", source: String(source), location: `${settingsPath} extensions[${index}]` });
277
- }
278
- }
279
- return sources;
280
- }
281
-
282
- function dedupe(paths) {
283
- return [...new Set(paths.map((path) => resolve(path)))];
284
- }
285
-
286
- async function inspectSettingsPath({ path, cwd, readText }) {
287
- try {
288
- const text = await readText(path);
289
- if (text === undefined) return { sources: [], warnings: [] };
290
- const settings = parseSettingsText(text, path);
291
- return { sources: collectSettingsSources(settings, path, cwd), warnings: [] };
292
- } catch (error) {
293
- return {
294
- sources: [],
295
- warnings: [`Could not inspect Pi settings ${path}: ${error instanceof Error ? error.message : String(error)}`],
296
- };
297
- }
298
- }
299
-
300
- async function collectRepoLocalSources({ cwd, pathExists }) {
301
- const candidates = [resolve(cwd, ".pi/extensions/agent-browser.ts"), resolve(cwd, ".pi/extensions/agent-browser/index.ts")];
302
- const sources = [];
303
- for (const candidate of candidates) {
304
- if (await pathExists(candidate)) {
305
- sources.push({ kind: "repo-local", source: candidate, location: `${candidate} repo-local autoload` });
306
- }
307
- }
308
- return sources;
309
- }
310
-
311
176
  async function checkPiVersion({ runPi }) {
312
177
  try {
313
178
  const rawOutput = await runPi(["--version"]);
@@ -327,10 +192,16 @@ async function checkPiVersion({ runPi }) {
327
192
  return {
328
193
  status: "warn",
329
194
  title: `Could not parse pi --version output: ${version || "<empty>"}.`,
330
- lines: [`Pi ${MINIMUM_PI_VERSION} or newer is required for this release; run this doctor from the same shell that launches Pi so the setup gate can verify the host runtime.`],
195
+ lines: [
196
+ `Pi ${MINIMUM_PI_VERSION} or newer is required for this release; run this doctor from the same shell that launches Pi so the setup gate can verify the host runtime.`,
197
+ ],
331
198
  };
332
199
  }
333
- return { status: "pass", title: `Pi version satisfies the minimum runtime floor: ${version}`, lines: [] };
200
+ return {
201
+ status: "pass",
202
+ title: `Pi version satisfies the minimum runtime floor: ${version}`,
203
+ lines: [],
204
+ };
334
205
  } catch (error) {
335
206
  const code = error && typeof error === "object" ? error.code : undefined;
336
207
  return {
@@ -361,9 +232,10 @@ async function checkAgentBrowserVersion({ runAgentBrowser }) {
361
232
  }
362
233
  return {
363
234
  status: "pass",
364
- title: version === RECOMMENDED_VERSION
365
- ? `agent-browser version matches recommended baseline: ${version}`
366
- : `agent-browser version meets supported floor: ${version} (recommended ${RECOMMENDED_VERSION})`,
235
+ title:
236
+ version === RECOMMENDED_VERSION
237
+ ? `agent-browser version matches recommended baseline: ${version}`
238
+ : `agent-browser version meets supported floor: ${version} (recommended ${RECOMMENDED_VERSION})`,
367
239
  lines: [],
368
240
  };
369
241
  } catch (error) {
@@ -383,89 +255,52 @@ async function checkAgentBrowserVersion({ runAgentBrowser }) {
383
255
  }
384
256
  }
385
257
 
386
- async function checkPiSources({ cwd, agentDir, settingsPaths, readText, pathExists }) {
387
- const defaultSettingsPaths = [resolve(agentDir, "settings.json"), resolve(cwd, ".pi/settings.json")];
388
- const allSettingsPaths = dedupe([...defaultSettingsPaths, ...settingsPaths]);
389
- const sources = [];
390
- const warnings = [];
391
-
392
- for (const path of allSettingsPaths) {
393
- if (await pathExists(path)) {
394
- const result = await inspectSettingsPath({ path, cwd, readText });
395
- sources.push(...result.sources);
396
- warnings.push(...result.warnings);
397
- }
398
- }
399
- sources.push(...(await collectRepoLocalSources({ cwd, pathExists })));
400
-
401
- if (sources.length > 1) {
402
- return {
403
- status: "fail",
404
- title: "Duplicate pi-agent-browser-native sources detected.",
405
- lines: [
406
- "Pi may register multiple `agent_browser` tools when a checkout source and a package source are both active.",
407
- "Detected sources:",
408
- ...sources.map((source) => `- ${source.source} from ${source.location}`),
409
- "Keep exactly one active source:",
410
- "- for normal use: keep `pi install npm:pi-agent-browser-native` and remove/disable checkout paths from Pi settings",
411
- "- for temporary package or checkout trials: use `pi --approve --no-extensions -e <source>` when you intentionally trust the current project, or omit `--approve` to let Pi prompt in interactive mode",
412
- "- for configured-source lifecycle validation: keep exactly one checkout or package source, then launch plain `pi`",
413
- ],
414
- warnings,
415
- };
416
- }
417
- if (sources.length === 1) {
418
- return {
419
- status: "pass",
420
- title: "No duplicate pi-agent-browser-native sources detected.",
421
- lines: [`Detected source: ${sources[0].source} from ${sources[0].location}`],
422
- warnings,
423
- };
424
- }
258
+ function doctorIo(options) {
425
259
  return {
426
- status: "warn",
427
- title: "No configured pi-agent-browser-native source was found in inspected Pi settings.",
428
- lines: [
429
- "This is OK for isolated runs such as `pi --no-extensions -e npm:pi-agent-browser-native`, but normal package use should install exactly one source with `pi install npm:pi-agent-browser-native`.",
430
- ],
431
- warnings,
260
+ readText: options.readText ?? ((path) => readFile(path, "utf8")),
261
+ pathExists: options.pathExists ?? defaultPathExists,
262
+ runAgentBrowser: options.runAgentBrowser ?? defaultRunAgentBrowser,
263
+ runPi: options.runPi ?? defaultRunPi,
432
264
  };
433
265
  }
434
266
 
267
+ /** @param {DoctorOptions} [options] @returns {Promise<DoctorReport>} */
435
268
  export async function evaluateDoctor(options = {}) {
436
269
  const cwd = resolve(options.cwd ?? process.cwd());
437
270
  const agentDir = resolve(options.agentDir ?? DEFAULT_AGENT_DIR);
438
- const settingsPaths = (options.settingsPaths ?? []).map((path) => resolve(cwd, path));
439
- const readText = options.readText ?? ((path) => readFile(path, "utf8"));
440
- const pathExists = options.pathExists ?? defaultPathExists;
441
- const runAgentBrowser = options.runAgentBrowser ?? defaultRunAgentBrowser;
442
- const runPi = options.runPi ?? defaultRunPi;
271
+ const settingsPaths = Array.from(options.settingsPaths ?? [], (path) => resolve(cwd, path));
272
+ const { readText, pathExists, runAgentBrowser, runPi } = doctorIo(options);
443
273
  const checks = [];
444
- const failures = [];
274
+
445
275
  const warnings = [];
446
276
 
447
277
  const versionCheck = await checkAgentBrowserVersion({ runAgentBrowser });
448
278
  checks.push(versionCheck);
449
- if (versionCheck.status === "fail") failures.push(versionCheck);
450
279
 
451
280
  const piVersionCheck = await checkPiVersion({ runPi });
452
281
  checks.push(piVersionCheck);
453
- if (piVersionCheck.status === "fail") failures.push(piVersionCheck);
454
282
 
455
283
  if (!options.skipSourceCheck) {
456
- const sourceCheck = await checkPiSources({ cwd, agentDir, settingsPaths, readText, pathExists });
284
+ const sourceCheck = await checkPiSources({
285
+ cwd,
286
+ agentDir,
287
+ settingsPaths,
288
+ readText,
289
+ pathExists,
290
+ });
457
291
  checks.push(sourceCheck);
458
- if (sourceCheck.status === "fail") failures.push(sourceCheck);
292
+
459
293
  warnings.push(...(sourceCheck.warnings ?? []));
460
294
  }
461
295
 
462
- return { checks, failures, warnings };
296
+ return { checks, failures: checks.filter((check) => check.status === "fail"), warnings };
463
297
  }
464
298
 
299
+ /** @param {DoctorReport} report @returns {string} */
465
300
  export function formatDoctorReport(report) {
466
301
  const lines = ["pi-agent-browser-native doctor", ""];
467
302
  for (const check of report.checks) {
468
- const prefix = check.status === "pass" ? "✓" : check.status === "warn" ? "!" : "✗";
303
+ const prefix = { pass: "✓", warn: "!", fail: "✗" }[check.status];
469
304
  lines.push(`${prefix} ${check.title}`);
470
305
  for (const line of check.lines ?? []) {
471
306
  lines.push(` ${line}`);
@@ -475,7 +310,9 @@ export function formatDoctorReport(report) {
475
310
  for (const warning of report.warnings ?? []) {
476
311
  lines.push(`! ${warning}`);
477
312
  }
478
- if ((report.warnings ?? []).length > 0) lines.push("");
313
+ if ((report.warnings ?? []).length > 0) {
314
+ lines.push("");
315
+ }
479
316
  lines.push(report.failures.length > 0 ? "Doctor found setup failures." : "Doctor passed.");
480
317
  return lines.join("\n");
481
318
  }
@@ -502,8 +339,11 @@ export async function main(argv = process.argv.slice(2)) {
502
339
  return 0;
503
340
  }
504
341
 
342
+ /** @param {string} metaUrl @param {string | undefined} [argv1] @param {(path: string) => string} [resolveRealPath] @returns {boolean} */
505
343
  export function isDirectRun(metaUrl, argv1 = process.argv[1], resolveRealPath = realpathSync) {
506
- if (!argv1) return false;
344
+ if (!argv1) {
345
+ return false;
346
+ }
507
347
  try {
508
348
  return resolveRealPath(argv1) === fileURLToPath(metaUrl);
509
349
  } catch {
@@ -512,7 +352,12 @@ export function isDirectRun(metaUrl, argv1 = process.argv[1], resolveRealPath =
512
352
  }
513
353
 
514
354
  if (isDirectRun(import.meta.url)) {
515
- main().then((exitCode) => {
516
- process.exitCode = exitCode;
517
- });
355
+ main()
356
+ .then((exitCode) => {
357
+ process.exitCode = exitCode;
358
+ })
359
+ .catch((error) => {
360
+ console.error(error instanceof Error ? error.message : error);
361
+ process.exitCode = 1;
362
+ });
518
363
  }