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,34 +1,81 @@
1
- import { constants as fsConstants } from "node:fs";
2
- import { access, readdir, readFile, realpath, stat } from "node:fs/promises";
3
1
  import { homedir } from "node:os";
4
- import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
5
- import { pathExists } from "../fs-utils.js";
6
- export const ELECTRON_DISCOVERY_DEFAULT_MAX_RESULTS = 50;
7
- export const ELECTRON_DISCOVERY_MAX_RESULTS = 200;
8
- const LINUX_ELECTRON_CANDIDATE_MAX_DEPTH = 7;
9
- const LINUX_ELECTRON_CANDIDATE_MAX_ENTRIES = 5_000;
10
- const LINUX_NON_EXECUTABLE_CANDIDATE_EXTENSIONS = new Set([".asar", ".dat", ".desktop", ".json", ".md", ".pak", ".png", ".so", ".txt"]);
11
- const ELECTRON_SENSITIVE_APP_CATEGORY_PATTERNS = [
2
+ import { basename, join, resolve } from "node:path";
3
+ import { discoverDarwinApps, inspectDarwinApp } from "./discovery-darwin.js";
4
+ import { hasLinuxElectronEvidence, inspectWin32Executable, resolveRealPath, } from "./discovery-evidence.js";
5
+ import { discoverLinuxApps } from "./discovery-linux.js";
6
+ import { ELECTRON_DISCOVERY_DEFAULT_MAX_RESULTS, ELECTRON_DISCOVERY_MAX_RESULTS, } from "./discovery-types.js";
7
+ export { inspectDarwinApp } from "./discovery-darwin.js";
8
+ export { hasLinuxElectronEvidence } from "./discovery-evidence.js";
9
+ export { ELECTRON_DISCOVERY_DEFAULT_MAX_RESULTS, ELECTRON_DISCOVERY_MAX_RESULTS, } from "./discovery-types.js";
10
+ const SENSITIVE_APP_PATTERNS = [
12
11
  { category: "notes", patterns: [/\bobsidian\b/i, /\bnotion\b/i, /\blogseq\b/i] },
13
- { category: "chat", patterns: [/\bslack\b/i, /\bdiscord\b/i, /\bteams\b/i, /\bsignal\b/i, /\btelegram\b/i, /\bwhatsapp\b/i] },
14
- { category: "mail", patterns: [/\bmail\b/i, /\boutlook\b/i, /\bthunderbird\b/i, /\bspark\b/i, /\bproton[- ]?mail\b/i] },
15
- { category: "developer-workspace", patterns: [/\bvisual studio code\b/i, /\bvs ?code\b/i, /\bcode - insiders\b/i, /^code$/i, /\bcursor\b/i, /\bwindsurf\b/i] },
16
- { category: "passwords-auth", patterns: [/\b1password\b/i, /\bbitwarden\b/i, /\blastpass\b/i, /\bdashlane\b/i, /\bauthy\b/i, /\bauthenticator\b/i, /\bkeepass\b/i] },
12
+ {
13
+ category: "chat",
14
+ patterns: [
15
+ /\bslack\b/i,
16
+ /\bdiscord\b/i,
17
+ /\bteams\b/i,
18
+ /\bsignal\b/i,
19
+ /\btelegram\b/i,
20
+ /\bwhatsapp\b/i,
21
+ ],
22
+ },
23
+ {
24
+ category: "mail",
25
+ patterns: [
26
+ /\bmail\b/i,
27
+ /\boutlook\b/i,
28
+ /\bthunderbird\b/i,
29
+ /\bspark\b/i,
30
+ /\bproton[- ]?mail\b/i,
31
+ ],
32
+ },
33
+ {
34
+ category: "developer-workspace",
35
+ patterns: [
36
+ /\bvisual studio code\b/i,
37
+ /\bvs ?code\b/i,
38
+ /\bcode - insiders\b/i,
39
+ /^code$/i,
40
+ /\bcursor\b/i,
41
+ /\bwindsurf\b/i,
42
+ ],
43
+ },
44
+ {
45
+ category: "passwords-auth",
46
+ patterns: [
47
+ /\b1password\b/i,
48
+ /\bbitwarden\b/i,
49
+ /\blastpass\b/i,
50
+ /\bdashlane\b/i,
51
+ /\bauthy\b/i,
52
+ /\bauthenticator\b/i,
53
+ /\bkeepass\b/i,
54
+ ],
55
+ },
17
56
  ];
18
57
  function normalizeSensitivityValue(value) {
19
- return value?.trim().replace(/[_./\\-]+/g, " ").replace(/\s+/g, " ") || undefined;
58
+ const normalized = value
59
+ ?.trim()
60
+ .replace(/[_./\\-]+/g, " ")
61
+ .replace(/\s+/g, " ");
62
+ return normalized === undefined || normalized.length === 0 ? undefined : normalized;
20
63
  }
21
64
  export function getElectronAppSensitivity(app) {
22
- const metadataValues = [app.name, app.bundleId, app.desktopId, app.appPath, app.executablePath]
65
+ const values = [app.name, app.bundleId, app.desktopId, app.appPath, app.executablePath]
23
66
  .map(normalizeSensitivityValue)
24
67
  .filter((value) => value !== undefined);
25
- const categories = ELECTRON_SENSITIVE_APP_CATEGORY_PATTERNS
26
- .filter(({ patterns }) => metadataValues.some((value) => patterns.some((pattern) => pattern.test(value))))
27
- .map(({ category }) => category);
28
- if (categories.length === 0)
68
+ const categories = SENSITIVE_APP_PATTERNS.filter(({ patterns }) => values.some((value) => patterns.some((pattern) => pattern.test(value)))).map(({ category }) => category);
69
+ if (categories.length === 0) {
29
70
  return undefined;
71
+ }
30
72
  return {
31
- categories: [...new Set(categories)].sort(),
73
+ categories: [...new Set(categories)].sort((left, right) => {
74
+ if (left === right) {
75
+ return 0;
76
+ }
77
+ return left < right ? -1 : 1;
78
+ }),
32
79
  level: "likely-sensitive",
33
80
  reason: "App name, bundle id, desktop id, or path matched common private-data app patterns; discovery still does not enforce policy.",
34
81
  };
@@ -37,558 +84,100 @@ function annotateElectronAppSensitivity(app) {
37
84
  const sensitivity = getElectronAppSensitivity(app);
38
85
  return sensitivity ? { ...app, sensitivity } : app;
39
86
  }
40
- function normalizeMaxResults(maxResults) {
41
- if (typeof maxResults !== "number" || !Number.isInteger(maxResults) || maxResults <= 0) {
87
+ function normalizeMaxResults(value) {
88
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
42
89
  return ELECTRON_DISCOVERY_DEFAULT_MAX_RESULTS;
43
90
  }
44
- return Math.min(maxResults, ELECTRON_DISCOVERY_MAX_RESULTS);
91
+ return Math.min(value, ELECTRON_DISCOVERY_MAX_RESULTS);
45
92
  }
46
- function resolveLocations(locations) {
47
- const homeDir = locations?.homeDir ?? homedir();
93
+ function linuxDesktopDirectories(locations, homeDir) {
94
+ return (locations?.linuxDesktopDirectories ?? [
95
+ join(homeDir, ".local", "share", "applications"),
96
+ "/usr/share/applications",
97
+ "/var/lib/snapd/desktop/applications",
98
+ join(homeDir, ".local", "share", "flatpak", "exports", "share", "applications"),
99
+ "/var/lib/flatpak/exports/share/applications",
100
+ ]);
101
+ }
102
+ function resolvePackageLocations(locations, homeDir) {
48
103
  return {
49
- darwinApplicationDirectories: locations?.darwinApplicationDirectories ?? ["/Applications", join(homeDir, "Applications")],
50
104
  flatpakSystemAppDirectory: locations?.flatpakSystemAppDirectory ?? "/var/lib/flatpak/app",
51
105
  flatpakUserAppDirectory: locations?.flatpakUserAppDirectory ?? join(homeDir, ".local", "share", "flatpak", "app"),
52
- homeDir,
53
- linuxDesktopDirectories: locations?.linuxDesktopDirectories ?? [
54
- join(homeDir, ".local", "share", "applications"),
55
- "/usr/share/applications",
56
- "/var/lib/snapd/desktop/applications",
57
- join(homeDir, ".local", "share", "flatpak", "exports", "share", "applications"),
58
- "/var/lib/flatpak/exports/share/applications",
59
- ],
60
- pathEnv: locations?.pathEnv ?? process.env.PATH ?? "",
61
106
  snapBinDirectory: locations?.snapBinDirectory ?? "/snap/bin",
62
107
  snapMountDirectory: locations?.snapMountDirectory ?? "/snap",
63
108
  };
64
109
  }
65
- async function isDirectory(path) {
66
- try {
67
- return (await stat(path)).isDirectory();
68
- }
69
- catch {
70
- return false;
71
- }
72
- }
73
- async function isFile(path) {
74
- try {
75
- return (await stat(path)).isFile();
76
- }
77
- catch {
78
- return false;
79
- }
80
- }
81
- async function isExecutableFile(path) {
82
- try {
83
- const metadata = await stat(path);
84
- if (!metadata.isFile())
85
- return false;
86
- await access(path, fsConstants.X_OK);
87
- return true;
88
- }
89
- catch {
90
- return false;
91
- }
92
- }
93
- async function resolveRealPath(path) {
94
- try {
95
- return await realpath(path);
96
- }
97
- catch {
98
- return path;
99
- }
100
- }
101
- function escapeRegExp(value) {
102
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
103
- }
104
- function decodeXmlEntities(value) {
105
- return value
106
- .replaceAll("&amp;", "&")
107
- .replaceAll("&lt;", "<")
108
- .replaceAll("&gt;", ">")
109
- .replaceAll("&quot;", '"')
110
- .replaceAll("&apos;", "'");
111
- }
112
- function readPlistString(plist, key) {
113
- const pattern = new RegExp(`<key>\\s*${escapeRegExp(key)}\\s*</key>\\s*<string>([\\s\\S]*?)</string>`, "i");
114
- const match = pattern.exec(plist);
115
- return match ? decodeXmlEntities(match[1]?.trim() ?? "") : undefined;
116
- }
117
- async function readMacInfoPlist(appPath) {
118
- try {
119
- const plist = await readFile(join(appPath, "Contents", "Info.plist"), "utf8");
120
- return {
121
- CFBundleDisplayName: readPlistString(plist, "CFBundleDisplayName") ?? "",
122
- CFBundleExecutable: readPlistString(plist, "CFBundleExecutable") ?? "",
123
- CFBundleIdentifier: readPlistString(plist, "CFBundleIdentifier") ?? "",
124
- CFBundleName: readPlistString(plist, "CFBundleName") ?? "",
125
- };
126
- }
127
- catch {
128
- return {};
129
- }
130
- }
131
- async function resolveMacExecutablePath(appPath, executableName, fallbackName) {
132
- const macOsDirectory = join(appPath, "Contents", "MacOS");
133
- if (executableName && executableName.trim().length > 0) {
134
- const executablePath = join(macOsDirectory, executableName);
135
- return await pathExists(executablePath) ? executablePath : undefined;
136
- }
137
- try {
138
- const entries = await readdir(macOsDirectory, { withFileTypes: true });
139
- const exact = entries.find((entry) => entry.isFile() && entry.name === fallbackName);
140
- const candidate = exact ?? entries.find((entry) => entry.isFile());
141
- return candidate ? join(macOsDirectory, candidate.name) : undefined;
142
- }
143
- catch {
144
- return undefined;
145
- }
146
- }
147
- export async function inspectDarwinApp(appPath) {
148
- const frameworkPath = join(appPath, "Contents", "Frameworks", "Electron Framework.framework");
149
- const resourcesPath = join(appPath, "Contents", "Resources");
150
- const hasElectronFramework = await isDirectory(frameworkPath);
151
- const hasAppPayload = await pathExists(join(resourcesPath, "app.asar")) || await isDirectory(join(resourcesPath, "app"));
152
- if (!hasElectronFramework || !hasAppPayload)
153
- return undefined;
154
- const info = await readMacInfoPlist(appPath);
155
- const appDirectoryName = basename(appPath, ".app");
156
- const executablePath = await resolveMacExecutablePath(appPath, info.CFBundleExecutable, appDirectoryName);
157
- if (!executablePath)
158
- return undefined;
159
- const name = info.CFBundleDisplayName || info.CFBundleName || appDirectoryName;
160
- return {
161
- appPath,
162
- bundleId: info.CFBundleIdentifier || undefined,
163
- executablePath,
164
- name,
165
- platform: "darwin",
166
- };
167
- }
168
- async function discoverDarwinApps(locations) {
169
- const apps = [];
170
- let skippedCount = 0;
171
- for (const directory of locations.darwinApplicationDirectories) {
172
- let entries;
173
- try {
174
- entries = await readdir(directory, { withFileTypes: true });
175
- }
176
- catch {
177
- continue;
178
- }
179
- for (const entry of entries) {
180
- if (!entry.name.endsWith(".app"))
181
- continue;
182
- const appPath = join(directory, entry.name);
183
- try {
184
- const app = await inspectDarwinApp(appPath);
185
- if (app)
186
- apps.push(app);
187
- }
188
- catch {
189
- skippedCount += 1;
190
- }
191
- }
192
- }
193
- return { apps, skippedCount };
194
- }
195
- function unescapeDesktopValue(value) {
196
- return value
197
- .replace(/\\s/g, " ")
198
- .replace(/\\n/g, "\n")
199
- .replace(/\\r/g, "\r")
200
- .replace(/\\t/g, "\t")
201
- .replace(/\\\\/g, "\\");
202
- }
203
- function parseDesktopBoolean(value) {
204
- return value?.trim().toLowerCase() === "true";
205
- }
206
- function parseDesktopFile(text, filePath) {
207
- const fields = new Map();
208
- let inDesktopEntry = false;
209
- for (const rawLine of text.split(/\r?\n/)) {
210
- const line = rawLine.trim();
211
- if (line.length === 0 || line.startsWith("#"))
212
- continue;
213
- if (line.startsWith("[") && line.endsWith("]")) {
214
- inDesktopEntry = line === "[Desktop Entry]";
215
- continue;
216
- }
217
- if (!inDesktopEntry)
218
- continue;
219
- const separatorIndex = line.indexOf("=");
220
- if (separatorIndex <= 0)
221
- continue;
222
- const key = line.slice(0, separatorIndex);
223
- const value = unescapeDesktopValue(line.slice(separatorIndex + 1));
224
- fields.set(key, value);
225
- }
226
- if (fields.get("Type") !== "Application")
227
- return undefined;
228
- if (parseDesktopBoolean(fields.get("NoDisplay")) || parseDesktopBoolean(fields.get("Hidden")))
229
- return undefined;
230
- const exec = fields.get("Exec")?.trim();
231
- if (!exec)
232
- return undefined;
233
- const desktopId = basename(filePath, ".desktop");
234
- return {
235
- comment: fields.get("Comment") || undefined,
236
- desktopId,
237
- exec,
238
- filePath,
239
- icon: fields.get("Icon") || undefined,
240
- name: fields.get("Name") || desktopId,
241
- };
242
- }
243
- function stripDesktopExecFieldCodes(exec) {
244
- const placeholder = "\u0000PERCENT\u0000";
245
- return exec
246
- .replaceAll("%%", placeholder)
247
- .replace(/%[A-Za-z]/g, "")
248
- .replaceAll(placeholder, "%");
249
- }
250
- function tokenizeDesktopExec(exec) {
251
- const tokens = [];
252
- let current = "";
253
- let quote;
254
- let escaped = false;
255
- for (const char of stripDesktopExecFieldCodes(exec)) {
256
- if (escaped) {
257
- current += char;
258
- escaped = false;
259
- continue;
260
- }
261
- if (char === "\\") {
262
- escaped = true;
263
- continue;
264
- }
265
- if (quote) {
266
- if (char === quote) {
267
- quote = undefined;
268
- }
269
- else {
270
- current += char;
271
- }
272
- continue;
273
- }
274
- if (char === '"' || char === "'") {
275
- quote = char;
276
- continue;
277
- }
278
- if (/\s/.test(char)) {
279
- if (current.length > 0) {
280
- tokens.push(current);
281
- current = "";
282
- }
283
- continue;
284
- }
285
- current += char;
286
- }
287
- if (escaped)
288
- current += "\\";
289
- if (current.length > 0)
290
- tokens.push(current);
291
- return tokens;
292
- }
293
- function stripEnvLauncher(tokens) {
294
- if (tokens.length === 0 || basename(tokens[0] ?? "") !== "env")
295
- return tokens;
296
- let index = 1;
297
- while (index < tokens.length) {
298
- const token = tokens[index] ?? "";
299
- if (token.startsWith("-")) {
300
- index += token === "-u" || token === "--unset" || token === "--chdir" ? 2 : 1;
301
- continue;
302
- }
303
- if (/^[A-Za-z_][A-Za-z0-9_]*=.*/.test(token)) {
304
- index += 1;
305
- continue;
306
- }
307
- break;
308
- }
309
- return tokens.slice(index);
310
- }
311
- async function directoryContainsChromePak(directory) {
312
- try {
313
- const entries = await readdir(directory, { withFileTypes: true });
314
- return entries.some((entry) => entry.isFile() && /^chrome_.*\.pak$/i.test(entry.name));
315
- }
316
- catch {
317
- return false;
318
- }
319
- }
320
- export async function hasLinuxElectronEvidence(executablePath) {
321
- const resolvedExecutablePath = await resolveRealPath(executablePath);
322
- if (!await isExecutableFile(resolvedExecutablePath))
323
- return false;
324
- const executableDirectory = dirname(resolvedExecutablePath);
325
- if (!await directoryContainsChromePak(executableDirectory))
326
- return false;
327
- const resourceBases = [executableDirectory, dirname(executableDirectory)];
328
- for (const base of resourceBases) {
329
- const resourcesDirectory = join(base, "resources");
330
- if (await pathExists(join(resourcesDirectory, "app.asar")) || await isDirectory(join(resourcesDirectory, "app"))) {
331
- return true;
332
- }
333
- }
334
- return false;
335
- }
336
- async function findExecutableInPath(command, pathEnv) {
337
- if (command.includes("/"))
338
- return undefined;
339
- for (const directory of pathEnv.split(":")) {
340
- if (directory.length === 0)
341
- continue;
342
- const candidate = join(directory, command);
343
- if (await isFile(candidate))
344
- return candidate;
345
- }
346
- return undefined;
347
- }
348
- function pathIsWithin(path, parent) {
349
- const relativePath = relative(resolve(parent), resolve(path));
350
- return relativePath.length === 0 || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
351
- }
352
- function isLikelyExecutableCandidate(path) {
353
- return !LINUX_NON_EXECUTABLE_CANDIDATE_EXTENSIONS.has(extname(path).toLowerCase());
354
- }
355
- async function findElectronBinaryUnder(root, preferredNames) {
356
- if (!await isDirectory(root))
357
- return undefined;
358
- const preferredNameSet = new Set(preferredNames.filter((name) => name.length > 0));
359
- const allFileCandidates = [];
360
- let visitedEntries = 0;
361
- async function visit(directory, depth) {
362
- if (depth > LINUX_ELECTRON_CANDIDATE_MAX_DEPTH || visitedEntries >= LINUX_ELECTRON_CANDIDATE_MAX_ENTRIES)
363
- return undefined;
364
- let entries;
365
- try {
366
- entries = await readdir(directory, { withFileTypes: true });
367
- }
368
- catch {
369
- return undefined;
370
- }
371
- for (const entry of entries) {
372
- visitedEntries += 1;
373
- if (visitedEntries > LINUX_ELECTRON_CANDIDATE_MAX_ENTRIES)
374
- return undefined;
375
- const path = join(directory, entry.name);
376
- if (entry.isDirectory()) {
377
- const found = await visit(path, depth + 1);
378
- if (found)
379
- return found;
380
- }
381
- else if (entry.isFile() && isLikelyExecutableCandidate(path)) {
382
- if (preferredNameSet.has(entry.name) && await hasLinuxElectronEvidence(path))
383
- return await resolveRealPath(path);
384
- allFileCandidates.push(path);
385
- }
386
- }
387
- return undefined;
388
- }
389
- const preferredMatch = await visit(root, 0);
390
- if (preferredMatch)
391
- return preferredMatch;
392
- for (const candidate of allFileCandidates) {
393
- if (await hasLinuxElectronEvidence(candidate))
394
- return await resolveRealPath(candidate);
395
- }
396
- return undefined;
397
- }
398
- function getSnapCandidateNames(commandName, desktopId) {
399
- const names = [commandName, commandName.split(".")[0] ?? "", desktopId.split(".")[0] ?? ""];
400
- return [...new Set(names.filter((name) => name.length > 0))];
401
- }
402
- async function resolveSnapExecutable(commandPath, entry, locations) {
403
- const commandName = basename(commandPath);
404
- for (const snapName of getSnapCandidateNames(commandName, entry.desktopId)) {
405
- const root = join(locations.snapMountDirectory, snapName, "current");
406
- const candidate = await findElectronBinaryUnder(root, [commandName, commandName.split(".").at(-1) ?? commandName]);
407
- if (candidate)
408
- return candidate;
409
- }
410
- return undefined;
411
- }
412
- function getFlatpakAppId(tokens, desktopId) {
413
- for (let index = tokens.length - 1; index >= 0; index -= 1) {
414
- const token = tokens[index] ?? "";
415
- if (!token.startsWith("-") && token.includes(".") && token !== "flatpak")
416
- return token;
417
- }
418
- return desktopId;
419
- }
420
- function getFlatpakCommandName(tokens) {
421
- for (let index = 0; index < tokens.length; index += 1) {
422
- const token = tokens[index] ?? "";
423
- if (token.startsWith("--command="))
424
- return token.slice("--command=".length);
425
- if (token === "--command")
426
- return tokens[index + 1];
427
- }
428
- return undefined;
429
- }
430
- function getFlatpakRoots(entry, locations) {
431
- const userExportDirectory = join(locations.homeDir, ".local", "share", "flatpak", "exports", "share", "applications");
432
- const systemExportDirectory = "/var/lib/flatpak/exports/share/applications";
433
- if (pathIsWithin(entry.filePath, userExportDirectory)) {
434
- return [locations.flatpakUserAppDirectory, locations.flatpakSystemAppDirectory];
435
- }
436
- if (pathIsWithin(entry.filePath, systemExportDirectory)) {
437
- return [locations.flatpakSystemAppDirectory, locations.flatpakUserAppDirectory];
438
- }
439
- return [locations.flatpakUserAppDirectory, locations.flatpakSystemAppDirectory];
440
- }
441
- async function resolveFlatpakExecutable(tokens, entry, locations) {
442
- const appId = getFlatpakAppId(tokens, entry.desktopId);
443
- const commandName = getFlatpakCommandName(tokens);
444
- const preferredNames = commandName ? [commandName] : [];
445
- for (const root of getFlatpakRoots(entry, locations)) {
446
- const filesRoot = join(root, appId, "current", "active", "files");
447
- const candidate = await findElectronBinaryUnder(filesRoot, preferredNames);
448
- if (candidate)
449
- return candidate;
450
- }
451
- return undefined;
452
- }
453
- async function resolveLinuxExecutable(entry, locations) {
454
- const tokens = stripEnvLauncher(tokenizeDesktopExec(entry.exec));
455
- const executableToken = tokens[0];
456
- if (!executableToken)
457
- return undefined;
458
- if (basename(executableToken) === "flatpak") {
459
- const executablePath = await resolveFlatpakExecutable(tokens, entry, locations);
460
- return executablePath ? { executablePath, packageSource: "flatpak" } : undefined;
461
- }
462
- let executablePath = executableToken;
463
- if (!isAbsolute(executablePath)) {
464
- const pathExecutable = await findExecutableInPath(executablePath, locations.pathEnv);
465
- if (!pathExecutable)
466
- return undefined;
467
- executablePath = pathExecutable;
468
- }
469
- if (pathIsWithin(executablePath, locations.snapBinDirectory)) {
470
- const snapExecutable = await resolveSnapExecutable(executablePath, entry, locations);
471
- return snapExecutable ? { executablePath: snapExecutable, packageSource: "snap" } : undefined;
472
- }
473
- return { executablePath: await resolveRealPath(executablePath), packageSource: "desktop" };
474
- }
475
- async function inspectLinuxDesktopFile(filePath, locations) {
476
- let text;
477
- try {
478
- text = await readFile(filePath, "utf8");
479
- }
480
- catch {
481
- return undefined;
482
- }
483
- const entry = parseDesktopFile(text, filePath);
484
- if (!entry)
485
- return undefined;
486
- const resolution = await resolveLinuxExecutable(entry, locations);
487
- if (!resolution)
488
- return undefined;
489
- if (!await hasLinuxElectronEvidence(resolution.executablePath))
490
- return undefined;
110
+ function resolveLocations(locations) {
111
+ const homeDir = locations?.homeDir ?? homedir();
491
112
  return {
492
- comment: entry.comment,
493
- desktopId: entry.desktopId,
494
- executablePath: resolution.executablePath,
495
- icon: entry.icon,
496
- name: entry.name,
497
- packageSource: resolution.packageSource,
498
- platform: "linux",
113
+ ...resolvePackageLocations(locations, homeDir),
114
+ homeDir,
115
+ darwinApplicationDirectories: locations?.darwinApplicationDirectories ?? [
116
+ "/Applications",
117
+ join(homeDir, "Applications"),
118
+ ],
119
+ linuxDesktopDirectories: linuxDesktopDirectories(locations, homeDir),
120
+ pathEnv: locations?.pathEnv ?? process.env.PATH ?? "",
499
121
  };
500
122
  }
501
- async function discoverLinuxApps(locations) {
502
- const apps = [];
503
- let skippedCount = 0;
504
- for (const directory of locations.linuxDesktopDirectories) {
505
- let entries;
506
- try {
507
- entries = await readdir(directory, { withFileTypes: true });
508
- }
509
- catch {
510
- continue;
511
- }
512
- for (const entry of entries) {
513
- if (!entry.isFile() || extname(entry.name) !== ".desktop")
514
- continue;
515
- try {
516
- const app = await inspectLinuxDesktopFile(join(directory, entry.name), locations);
517
- if (app)
518
- apps.push(app);
519
- }
520
- catch {
521
- skippedCount += 1;
522
- }
523
- }
524
- }
525
- return { apps, skippedCount };
526
- }
527
123
  function appMatchesQuery(app, query) {
528
- if (!query)
124
+ if (query === undefined || query.length === 0) {
529
125
  return true;
530
- const normalizedQuery = query.toLowerCase();
531
- const searchableValues = [app.name, app.bundleId, app.appPath, app.executablePath, app.comment, app.desktopId, app.icon, app.packageSource]
126
+ }
127
+ const normalized = query.toLowerCase();
128
+ return [
129
+ app.name,
130
+ app.bundleId,
131
+ app.appPath,
132
+ app.executablePath,
133
+ app.comment,
134
+ app.desktopId,
135
+ app.icon,
136
+ app.packageSource,
137
+ ]
532
138
  .filter((value) => typeof value === "string" && value.length > 0)
533
- .map((value) => value.toLowerCase());
534
- return searchableValues.some((value) => value.includes(normalizedQuery));
139
+ .some((value) => value.toLowerCase().includes(normalized));
535
140
  }
536
141
  function dedupeApps(apps) {
537
142
  const seen = new Set();
538
- const deduped = [];
539
- for (const app of apps) {
143
+ return apps.filter((app) => {
540
144
  const key = app.appPath ?? app.executablePath;
541
- if (seen.has(key))
542
- continue;
145
+ if (seen.has(key)) {
146
+ return false;
147
+ }
543
148
  seen.add(key);
544
- deduped.push(app);
545
- }
546
- return deduped;
149
+ return true;
150
+ });
547
151
  }
548
152
  function sortApps(apps) {
549
153
  return [...apps].sort((left, right) => {
550
- const nameComparison = left.name.localeCompare(right.name, undefined, { sensitivity: "base" });
551
- return nameComparison === 0 ? left.executablePath.localeCompare(right.executablePath) : nameComparison;
154
+ const comparison = left.name.localeCompare(right.name, undefined, { sensitivity: "base" });
155
+ return comparison === 0 ? left.executablePath.localeCompare(right.executablePath) : comparison;
552
156
  });
553
157
  }
554
158
  function findMacAppBundleAncestor(path) {
555
159
  const parts = resolve(path).split(/[\\/]+/);
556
- const appIndex = parts.findIndex((part) => part.endsWith(".app"));
557
- return appIndex >= 0 ? parts.slice(0, appIndex + 1).join("/") || "/" : undefined;
558
- }
559
- async function inspectWin32Executable(executablePath) {
560
- const resolvedExecutablePath = await resolveRealPath(executablePath);
561
- if (!await isExecutableFile(resolvedExecutablePath))
160
+ const index = parts.findIndex((part) => part.endsWith(".app"));
161
+ if (index < 0) {
562
162
  return undefined;
563
- const executableDirectory = dirname(resolvedExecutablePath);
564
- const resourcesDirectory = join(executableDirectory, "resources");
565
- const hasAppPayload = await pathExists(join(resourcesDirectory, "app.asar")) || await isDirectory(join(resourcesDirectory, "app"));
566
- const hasPak = await directoryContainsChromePak(executableDirectory) || await pathExists(join(executableDirectory, "resources.pak"));
567
- if (!hasAppPayload || !hasPak)
568
- return undefined;
569
- return {
570
- executablePath: resolvedExecutablePath,
571
- name: basename(resolvedExecutablePath, extname(resolvedExecutablePath)),
572
- platform: "win32",
573
- };
163
+ }
164
+ const ancestor = parts.slice(0, index + 1).join("/");
165
+ return ancestor.length > 0 ? ancestor : "/";
574
166
  }
575
167
  export async function inspectElectronExecutablePath(executablePath, platform = process.platform) {
576
- const resolvedExecutablePath = await resolveRealPath(executablePath);
168
+ const resolved = await resolveRealPath(executablePath);
577
169
  if (platform === "darwin") {
578
- const appPath = findMacAppBundleAncestor(resolvedExecutablePath);
579
- return appPath ? inspectDarwinApp(appPath) : undefined;
170
+ const appPath = findMacAppBundleAncestor(resolved);
171
+ return appPath === undefined ? undefined : inspectDarwinApp(appPath);
580
172
  }
581
173
  if (platform === "linux") {
582
- if (!await hasLinuxElectronEvidence(resolvedExecutablePath))
174
+ if (!(await hasLinuxElectronEvidence(resolved))) {
583
175
  return undefined;
584
- return {
585
- executablePath: resolvedExecutablePath,
586
- name: basename(resolvedExecutablePath),
587
- platform: "linux",
588
- };
176
+ }
177
+ return { executablePath: resolved, name: basename(resolved), platform: "linux" };
589
178
  }
590
179
  if (platform === "win32") {
591
- return inspectWin32Executable(resolvedExecutablePath);
180
+ return inspectWin32Executable(resolved);
592
181
  }
593
182
  return undefined;
594
183
  }
@@ -600,27 +189,29 @@ export async function inspectElectronAppPath(appPath, platform = process.platfor
600
189
  }
601
190
  export async function discoverElectronApps(options = {}) {
602
191
  const platform = options.platform ?? process.platform;
603
- const query = options.query?.trim() || undefined;
192
+ const query = normalizeDiscoveryQuery(options.query);
604
193
  const maxResults = normalizeMaxResults(options.maxResults);
605
194
  const locations = resolveLocations(options.locations);
606
- let discovered;
607
- if (platform === "darwin") {
608
- discovered = await discoverDarwinApps(locations);
609
- }
610
- else if (platform === "linux") {
611
- discovered = await discoverLinuxApps(locations);
612
- }
613
- else {
195
+ if (platform !== "darwin" && platform !== "linux") {
614
196
  return { apps: [], maxResults, omittedCount: 0, platform: "unsupported", query };
615
197
  }
616
- const filteredApps = sortApps(dedupeApps(discovered.apps.map(annotateElectronAppSensitivity).filter((app) => appMatchesQuery(app, query))));
617
- const apps = filteredApps.slice(0, maxResults);
198
+ const discovered = platform === "darwin"
199
+ ? await discoverDarwinApps(locations.darwinApplicationDirectories)
200
+ : await discoverLinuxApps(locations);
201
+ const filtered = sortApps(dedupeApps(discovered.apps
202
+ .map(annotateElectronAppSensitivity)
203
+ .filter((app) => appMatchesQuery(app, query))));
204
+ const apps = filtered.slice(0, maxResults);
618
205
  return {
619
206
  apps,
620
207
  maxResults,
621
- omittedCount: Math.max(0, filteredApps.length - apps.length),
208
+ omittedCount: Math.max(0, filtered.length - apps.length),
622
209
  platform,
623
210
  query,
624
- skippedCount: discovered.skippedCount || undefined,
211
+ skippedCount: discovered.skippedCount === 0 ? undefined : discovered.skippedCount,
625
212
  };
626
213
  }
214
+ function normalizeDiscoveryQuery(value) {
215
+ const query = value?.trim();
216
+ return query === undefined || query.length === 0 ? undefined : query;
217
+ }