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.
- package/CHANGELOG.md +77 -5
- package/README.md +103 -81
- package/dist/extensions/agent-browser/index.js +43057 -2031
- package/dist/extensions/agent-browser/lib/argv-descriptor.js +49 -26
- package/dist/extensions/agent-browser/lib/argv-grammar.js +82 -93
- package/dist/extensions/agent-browser/lib/bash-guard.js +129 -126
- package/dist/extensions/agent-browser/lib/batch-lifecycle.js +112 -51
- package/dist/extensions/agent-browser/lib/browser-execution-claim-codec.js +61 -0
- package/dist/extensions/agent-browser/lib/browser-execution-claim-storage.js +232 -0
- package/dist/extensions/agent-browser/lib/browser-execution-claims.js +202 -0
- package/dist/extensions/agent-browser/lib/browser-execution-identity.js +77 -0
- package/dist/extensions/agent-browser/lib/browser-journal-branch.js +98 -0
- package/dist/extensions/agent-browser/lib/browser-journal-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/browser-journal-projection.js +221 -0
- package/dist/extensions/agent-browser/lib/browser-journal-reader.js +89 -0
- package/dist/extensions/agent-browser/lib/browser-journal-replay.js +246 -0
- package/dist/extensions/agent-browser/lib/browser-journal.js +103 -394
- package/dist/extensions/agent-browser/lib/browser-legacy-pages.js +220 -0
- package/dist/extensions/agent-browser/lib/browser-legacy-projection.js +282 -0
- package/dist/extensions/agent-browser/lib/browser-legacy-types.js +1 -0
- package/dist/extensions/agent-browser/lib/browser-session-conversion-stream.js +217 -0
- package/dist/extensions/agent-browser/lib/browser-session-conversion.js +80 -335
- package/dist/extensions/agent-browser/lib/browser-transcript-contracts.js +35 -0
- package/dist/extensions/agent-browser/lib/browser-transcript-validation.js +166 -0
- package/dist/extensions/agent-browser/lib/browser-transcript.js +137 -82
- package/dist/extensions/agent-browser/lib/browser-value-parsing.js +15 -0
- package/dist/extensions/agent-browser/lib/command-capabilities.js +340 -0
- package/dist/extensions/agent-browser/lib/command-policy.js +107 -88
- package/dist/extensions/agent-browser/lib/command-taxonomy.js +49 -322
- package/dist/extensions/agent-browser/lib/config-policy.js +138 -343
- package/dist/extensions/agent-browser/lib/config-providers.js +71 -0
- package/dist/extensions/agent-browser/lib/config-validation.js +218 -0
- package/dist/extensions/agent-browser/lib/config.js +19 -7
- package/dist/extensions/agent-browser/lib/electron/cdp.js +15 -7
- package/dist/extensions/agent-browser/lib/electron/cleanup.js +134 -55
- package/dist/extensions/agent-browser/lib/electron/discovery-darwin.js +109 -0
- package/dist/extensions/agent-browser/lib/electron/discovery-desktop.js +136 -0
- package/dist/extensions/agent-browser/lib/electron/discovery-evidence.js +89 -0
- package/dist/extensions/agent-browser/lib/electron/discovery-linux.js +93 -0
- package/dist/extensions/agent-browser/lib/electron/discovery-packages.js +162 -0
- package/dist/extensions/agent-browser/lib/electron/discovery-types.js +2 -0
- package/dist/extensions/agent-browser/lib/electron/discovery.js +140 -549
- package/dist/extensions/agent-browser/lib/electron/launch-monitor.js +102 -0
- package/dist/extensions/agent-browser/lib/electron/launch-process.js +209 -0
- package/dist/extensions/agent-browser/lib/electron/launch-types.js +2 -0
- package/dist/extensions/agent-browser/lib/electron/launch.js +249 -354
- package/dist/extensions/agent-browser/lib/executable-path.js +21 -12
- package/dist/extensions/agent-browser/lib/execution-cwd.js +35 -18
- package/dist/extensions/agent-browser/lib/input-modes/electron.js +162 -121
- package/dist/extensions/agent-browser/lib/input-modes/job.js +116 -313
- package/dist/extensions/agent-browser/lib/input-modes/lookup-network-evidence.js +104 -0
- package/dist/extensions/agent-browser/lib/input-modes/lookup-plan.js +132 -0
- package/dist/extensions/agent-browser/lib/input-modes/lookup-redaction.js +57 -0
- package/dist/extensions/agent-browser/lib/input-modes/lookup-source-evidence.js +151 -0
- package/dist/extensions/agent-browser/lib/input-modes/lookup-workspace.js +142 -0
- package/dist/extensions/agent-browser/lib/input-modes/lookups.js +57 -412
- package/dist/extensions/agent-browser/lib/input-modes/params.js +63 -17
- package/dist/extensions/agent-browser/lib/input-modes/qa-analysis.js +268 -0
- package/dist/extensions/agent-browser/lib/input-modes/qa-presentation.js +117 -0
- package/dist/extensions/agent-browser/lib/input-modes/script-child.js +396 -0
- package/dist/extensions/agent-browser/lib/input-modes/script-protocol.js +86 -0
- package/dist/extensions/agent-browser/lib/input-modes/script-types.js +1 -0
- package/dist/extensions/agent-browser/lib/input-modes/script-validation.js +60 -0
- package/dist/extensions/agent-browser/lib/input-modes/script.js +60 -409
- package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +218 -128
- package/dist/extensions/agent-browser/lib/input-modes/shared.js +15 -4
- package/dist/extensions/agent-browser/lib/input-modes/types.js +56 -7
- package/dist/extensions/agent-browser/lib/json-schema.js +22 -10
- package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +17 -5
- package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +92 -425
- package/dist/extensions/agent-browser/lib/managed-session-posix-storage.js +58 -0
- package/dist/extensions/agent-browser/lib/managed-session-project-identity.js +244 -0
- package/dist/extensions/agent-browser/lib/managed-session-restore-context.js +84 -0
- package/dist/extensions/agent-browser/lib/managed-session-restore-policy.js +119 -0
- package/dist/extensions/agent-browser/lib/managed-session-restore-state.js +83 -0
- package/dist/extensions/agent-browser/lib/managed-session-restore.js +168 -300
- package/dist/extensions/agent-browser/lib/managed-session-snapshot-records.js +277 -0
- package/dist/extensions/agent-browser/lib/managed-session-snapshots.js +128 -305
- package/dist/extensions/agent-browser/lib/managed-session-storage.js +56 -253
- package/dist/extensions/agent-browser/lib/native-confirmation.js +140 -0
- package/dist/extensions/agent-browser/lib/native-output.js +43 -9
- package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +106 -59
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-merge.js +14 -6
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +109 -57
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/browser-observation-result.js +82 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +164 -60
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostic-values.js +31 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +152 -781
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-observation.js +202 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-text-diagnostics.js +109 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/fill-diagnostics.js +119 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-action-recovery.js +147 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-actions.js +144 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-content.js +123 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-details.js +156 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js +179 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-evidence.js +39 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-missing-binary.js +89 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-recovery.js +97 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js +106 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-timeout.js +110 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +41 -538
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +199 -154
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/interaction-diagnostics.js +290 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-close.js +167 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-inspection.js +108 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +127 -205
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/native-helper-observation.js +65 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/observation-types.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/overlay-diagnostics.js +120 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +113 -30
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +109 -28
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter-data.js +150 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +138 -253
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-rendered-text.js +147 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +59 -24
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-artifacts.js +159 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-command.js +131 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-daemon.js +93 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-failure.js +42 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-guards.js +242 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-input.js +75 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-observations.js +92 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-selection.js +254 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-state.js +121 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-refs.js +130 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-resources.js +114 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-semantic.js +121 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-session-plan.js +222 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-timeouts.js +68 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +176 -1123
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-analysis.js +191 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-confirmation.js +152 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-diagnostics.js +182 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-electron.js +150 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase.js +115 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle.js +256 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed.js +256 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase.js +93 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native.js +113 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation.js +316 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-ownership.js +28 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase.js +142 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation.js +333 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase.js +71 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication.js +201 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-receipts.js +183 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-refs.js +200 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-tabs.js +142 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +18 -968
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +23 -13
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-receipt-reconciliation.js +198 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-presentation.js +154 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery.js +68 -151
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-capture.js +14 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-observation.js +169 -46
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-commands.js +130 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-electron.js +210 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-observations.js +61 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-outcomes.js +187 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-refs.js +171 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-tabs.js +228 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +77 -765
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/text-visibility-diagnostics.js +182 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-diagnostics.js +256 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-progress.js +108 -0
- package/dist/extensions/agent-browser/lib/orchestration/code-artifact-observation.js +39 -0
- package/dist/extensions/agent-browser/lib/orchestration/code-image-observation.js +119 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/branch.js +92 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup-result.js +58 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup.js +78 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/discovery.js +106 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +48 -821
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/policy.js +86 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-collection.js +69 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-data.js +167 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js +164 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe.js +161 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/status.js +165 -0
- package/dist/extensions/agent-browser/lib/orchestration/execution-queue.js +21 -9
- package/dist/extensions/agent-browser/lib/orchestration/extension-artifact-preflight.js +211 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-artifacts.js +23 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-attachment-replay.js +99 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-branch-restore.js +275 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-code.js +280 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-command-admission.js +303 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-command-output.js +36 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-command-result.js +335 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-command-run.js +227 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-command-state.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-electron-ownership.js +204 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-execution-locks.js +139 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-execution-queue.js +24 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-host-coordination.js +98 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-host-run.js +295 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-intent-replay.js +41 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-invocation.js +7 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-lifecycle.js +102 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-managed-ownership.js +133 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-observation.js +120 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-prompt.js +180 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-recording.js +290 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-resource-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-resource-replay.js +269 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-result-state.js +113 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-runtime.js +146 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-script-leases.js +58 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-tool-boundary.js +62 -0
- package/dist/extensions/agent-browser/lib/orchestration/extension-version-check.js +54 -0
- package/dist/extensions/agent-browser/lib/orchestration/input-plan-types.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +261 -185
- package/dist/extensions/agent-browser/lib/orchestration/input-redaction.js +62 -0
- package/dist/extensions/agent-browser/lib/orchestration/native-config.js +144 -0
- package/dist/extensions/agent-browser/lib/orchestration/native-root-launch.js +77 -0
- package/dist/extensions/agent-browser/lib/orchestration/native-session-defaults.js +210 -157
- package/dist/extensions/agent-browser/lib/orchestration/operation-paths.js +124 -58
- package/dist/extensions/agent-browser/lib/orchestration/output-file.js +197 -99
- package/dist/extensions/agent-browser/lib/orchestration/script-mode.js +199 -96
- package/dist/extensions/agent-browser/lib/owned-managed-session-context.js +55 -0
- package/dist/extensions/agent-browser/lib/page-target-batch.js +118 -0
- package/dist/extensions/agent-browser/lib/page-target-guards.js +50 -0
- package/dist/extensions/agent-browser/lib/page-target-navigation.js +104 -0
- package/dist/extensions/agent-browser/lib/page-target-validation.js +55 -246
- package/dist/extensions/agent-browser/lib/parsing.js +13 -4
- package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +133 -68
- package/dist/extensions/agent-browser/lib/playbook.js +16 -12
- package/dist/extensions/agent-browser/lib/process-child.js +284 -0
- package/dist/extensions/agent-browser/lib/process-environment.js +13 -6
- package/dist/extensions/agent-browser/lib/process-errors.js +23 -0
- package/dist/extensions/agent-browser/lib/process-identity.js +47 -15
- package/dist/extensions/agent-browser/lib/process-socket-storage.js +256 -0
- package/dist/extensions/agent-browser/lib/process-stdout.js +74 -0
- package/dist/extensions/agent-browser/lib/process.js +145 -536
- package/dist/extensions/agent-browser/lib/prompt-artifacts.js +287 -0
- package/dist/extensions/agent-browser/lib/prompt-policy.js +15 -194
- package/dist/extensions/agent-browser/lib/read-command.js +41 -0
- package/dist/extensions/agent-browser/lib/read-confirmation.js +131 -68
- package/dist/extensions/agent-browser/lib/recording-reservations.js +118 -45
- package/dist/extensions/agent-browser/lib/redaction-fields.js +75 -0
- package/dist/extensions/agent-browser/lib/redaction-json.js +149 -0
- package/dist/extensions/agent-browser/lib/redaction-url.js +88 -0
- package/dist/extensions/agent-browser/lib/results/action-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/results/action-recommendations.js +28 -271
- package/dist/extensions/agent-browser/lib/results/artifact-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/results/artifact-manifest-validation.js +133 -0
- package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +96 -94
- package/dist/extensions/agent-browser/lib/results/artifact-recommendations.js +73 -0
- package/dist/extensions/agent-browser/lib/results/categories.js +111 -54
- package/dist/extensions/agent-browser/lib/results/confirmation.js +29 -13
- package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +62 -27
- package/dist/extensions/agent-browser/lib/results/electron-recommendations.js +83 -0
- package/dist/extensions/agent-browser/lib/results/envelope-decoding.js +48 -0
- package/dist/extensions/agent-browser/lib/results/envelope.js +90 -67
- package/dist/extensions/agent-browser/lib/results/evidence-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/results/failure-recommendations.js +180 -0
- package/dist/extensions/agent-browser/lib/results/network-routes.js +86 -45
- package/dist/extensions/agent-browser/lib/results/network.js +35 -12
- package/dist/extensions/agent-browser/lib/results/next-actions.js +49 -19
- package/dist/extensions/agent-browser/lib/results/presentation/artifact-files.js +320 -0
- package/dist/extensions/agent-browser/lib/results/presentation/artifact-format.js +138 -0
- package/dist/extensions/agent-browser/lib/results/presentation/artifact-images.js +113 -0
- package/dist/extensions/agent-browser/lib/results/presentation/artifact-verification.js +145 -0
- package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +99 -555
- package/dist/extensions/agent-browser/lib/results/presentation/batch-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/results/presentation/batch-recording.js +118 -0
- package/dist/extensions/agent-browser/lib/results/presentation/batch-redaction.js +68 -0
- package/dist/extensions/agent-browser/lib/results/presentation/batch-rendering.js +135 -0
- package/dist/extensions/agent-browser/lib/results/presentation/batch-step.js +227 -0
- package/dist/extensions/agent-browser/lib/results/presentation/batch-summary.js +91 -0
- package/dist/extensions/agent-browser/lib/results/presentation/batch.js +91 -460
- package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +9 -5
- package/dist/extensions/agent-browser/lib/results/presentation/command-presenters.js +216 -0
- package/dist/extensions/agent-browser/lib/results/presentation/common.js +26 -9
- package/dist/extensions/agent-browser/lib/results/presentation/content.js +86 -29
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-a11y.js +67 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-health.js +79 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-identity.js +199 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-logs.js +75 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network-actions.js +216 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network.js +124 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js +64 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js +209 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-stream.js +69 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-summary.js +222 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +103 -1052
- package/dist/extensions/agent-browser/lib/results/presentation/early-result.js +70 -0
- package/dist/extensions/agent-browser/lib/results/presentation/errors.js +130 -60
- package/dist/extensions/agent-browser/lib/results/presentation/input-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +60 -145
- package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +147 -88
- package/dist/extensions/agent-browser/lib/results/presentation/notices.js +75 -0
- package/dist/extensions/agent-browser/lib/results/presentation/observation-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/results/presentation/observation-rendering.js +127 -0
- package/dist/extensions/agent-browser/lib/results/presentation/outcomes.js +120 -0
- package/dist/extensions/agent-browser/lib/results/presentation/output-completion.js +77 -0
- package/dist/extensions/agent-browser/lib/results/presentation/output-spill.js +51 -0
- package/dist/extensions/agent-browser/lib/results/presentation/registry.js +116 -240
- package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +35 -21
- package/dist/extensions/agent-browser/lib/results/presentation/skills.js +104 -73
- package/dist/extensions/agent-browser/lib/results/presentation/source.js +109 -0
- package/dist/extensions/agent-browser/lib/results/presentation.js +17 -261
- package/dist/extensions/agent-browser/lib/results/recommendation-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/results/recording.js +52 -14
- package/dist/extensions/agent-browser/lib/results/recovery-actions.js +14 -5
- package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +30 -22
- package/dist/extensions/agent-browser/lib/results/selector-recovery-target.js +83 -0
- package/dist/extensions/agent-browser/lib/results/selector-recovery.js +119 -119
- package/dist/extensions/agent-browser/lib/results/snapshot-compact.js +266 -0
- package/dist/extensions/agent-browser/lib/results/snapshot-content.js +32 -0
- package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +104 -71
- package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +31 -11
- package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +125 -66
- package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +26 -7
- package/dist/extensions/agent-browser/lib/results/snapshot.js +28 -248
- package/dist/extensions/agent-browser/lib/results/text.js +16 -5
- package/dist/extensions/agent-browser/lib/runtime-args-validation.js +133 -0
- package/dist/extensions/agent-browser/lib/runtime-compatibility.js +81 -0
- package/dist/extensions/agent-browser/lib/runtime-contracts.js +1 -0
- package/dist/extensions/agent-browser/lib/runtime-redaction.js +118 -0
- package/dist/extensions/agent-browser/lib/runtime-replay-events.js +144 -0
- package/dist/extensions/agent-browser/lib/runtime-session-identity.js +76 -0
- package/dist/extensions/agent-browser/lib/runtime-session-plan.js +114 -0
- package/dist/extensions/agent-browser/lib/runtime-session-replay.js +123 -0
- package/dist/extensions/agent-browser/lib/runtime-tab-correction.js +65 -0
- package/dist/extensions/agent-browser/lib/runtime-timeouts.js +28 -0
- package/dist/extensions/agent-browser/lib/runtime.js +137 -1041
- package/dist/extensions/agent-browser/lib/session-identity.js +51 -0
- package/dist/extensions/agent-browser/lib/session-page-observation.js +357 -0
- package/dist/extensions/agent-browser/lib/session-page-state.js +178 -333
- package/dist/extensions/agent-browser/lib/session-page-types.js +1 -0
- package/dist/extensions/agent-browser/lib/temp-artifact-budget.js +78 -0
- package/dist/extensions/agent-browser/lib/temp-mutation-queue.js +7 -0
- package/dist/extensions/agent-browser/lib/temp-root-ownership.js +234 -0
- package/dist/extensions/agent-browser/lib/temp-root.js +207 -0
- package/dist/extensions/agent-browser/lib/temp.js +33 -446
- package/dist/extensions/agent-browser/lib/tool-surface.js +94 -24
- package/dist/extensions/agent-browser/lib/upstream-version.js +3 -2
- package/dist/extensions/agent-browser/lib/web-search-providers.js +229 -0
- package/dist/extensions/agent-browser/lib/web-search-request.js +108 -0
- package/dist/extensions/agent-browser/lib/web-search-results.js +281 -0
- package/dist/extensions/agent-browser/lib/web-search-schema.js +82 -0
- package/dist/extensions/agent-browser/lib/web-search.js +109 -617
- package/dist/extensions/agent-browser/lib/webmcp-observation.js +13 -6
- package/dist/extensions/agent-browser/lib/windows-stock-launcher.js +63 -37
- package/dist/extensions/agent-browser/script-worker.js +80 -43
- package/dist/scripts/agent-browser-target.mjs +4 -2
- package/docs/ARCHITECTURE.md +17 -5
- package/docs/CODE_QUALITY.md +242 -0
- package/docs/COMMAND_REFERENCE.md +251 -220
- package/docs/ELECTRON.md +53 -44
- package/docs/RELEASE.md +18 -15
- package/docs/REQUIREMENTS.md +1 -0
- package/docs/SUPPORT_MATRIX.md +76 -75
- package/docs/TOOL_CONTRACT.md +145 -116
- package/docs/platform-smoke.md +5 -5
- package/package.json +143 -120
- package/scripts/agent-browser-capability-baseline.mjs +361 -957
- package/scripts/agent-browser-target.mjs +6 -2
- package/scripts/build.mjs +37 -8
- package/scripts/capability-core-commands.mjs +193 -0
- package/scripts/capability-options.mjs +283 -0
- package/scripts/capability-samples.mjs +133 -0
- package/scripts/capability-section.mjs +11 -0
- package/scripts/config.mjs +213 -114
- package/scripts/convert-browser-session.mjs +30 -9
- package/scripts/doctor-sources.mjs +195 -0
- package/scripts/doctor.mjs +92 -247
- package/scripts/platform-smoke/artifacts.mjs +38 -11
- package/scripts/platform-smoke/commands.mjs +104 -0
- package/scripts/platform-smoke/crabbox-runner.mjs +167 -80
- package/scripts/platform-smoke/doctor-support.mjs +157 -0
- package/scripts/platform-smoke/doctor-windows.mjs +230 -0
- package/scripts/platform-smoke/doctor.mjs +212 -320
- package/scripts/platform-smoke/lease-evidence.mjs +134 -0
- package/scripts/platform-smoke/suite-checks.mjs +98 -0
- package/scripts/platform-smoke/suite-evidence.mjs +281 -0
- package/scripts/platform-smoke/targets.mjs +158 -472
- package/scripts/platform-smoke.mjs +55 -40
- 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,
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
26
|
-
|
|
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(
|
|
41
|
-
if (typeof
|
|
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(
|
|
91
|
+
return Math.min(value, ELECTRON_DISCOVERY_MAX_RESULTS);
|
|
45
92
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
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
|
-
|
|
66
|
-
|
|
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("&", "&")
|
|
107
|
-
.replaceAll("<", "<")
|
|
108
|
-
.replaceAll(">", ">")
|
|
109
|
-
.replaceAll(""", '"')
|
|
110
|
-
.replaceAll("'", "'");
|
|
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
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
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 (
|
|
124
|
+
if (query === undefined || query.length === 0) {
|
|
529
125
|
return true;
|
|
530
|
-
|
|
531
|
-
const
|
|
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
|
-
.
|
|
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
|
-
|
|
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
|
-
|
|
145
|
+
if (seen.has(key)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
543
148
|
seen.add(key);
|
|
544
|
-
|
|
545
|
-
}
|
|
546
|
-
return deduped;
|
|
149
|
+
return true;
|
|
150
|
+
});
|
|
547
151
|
}
|
|
548
152
|
function sortApps(apps) {
|
|
549
153
|
return [...apps].sort((left, right) => {
|
|
550
|
-
const
|
|
551
|
-
return
|
|
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
|
|
557
|
-
|
|
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
|
-
|
|
564
|
-
const
|
|
565
|
-
|
|
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
|
|
168
|
+
const resolved = await resolveRealPath(executablePath);
|
|
577
169
|
if (platform === "darwin") {
|
|
578
|
-
const appPath = findMacAppBundleAncestor(
|
|
579
|
-
return appPath ? inspectDarwinApp(appPath)
|
|
170
|
+
const appPath = findMacAppBundleAncestor(resolved);
|
|
171
|
+
return appPath === undefined ? undefined : inspectDarwinApp(appPath);
|
|
580
172
|
}
|
|
581
173
|
if (platform === "linux") {
|
|
582
|
-
if (!await hasLinuxElectronEvidence(
|
|
174
|
+
if (!(await hasLinuxElectronEvidence(resolved))) {
|
|
583
175
|
return undefined;
|
|
584
|
-
|
|
585
|
-
|
|
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(
|
|
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
|
|
192
|
+
const query = normalizeDiscoveryQuery(options.query);
|
|
604
193
|
const maxResults = normalizeMaxResults(options.maxResults);
|
|
605
194
|
const locations = resolveLocations(options.locations);
|
|
606
|
-
|
|
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
|
|
617
|
-
|
|
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,
|
|
208
|
+
omittedCount: Math.max(0, filtered.length - apps.length),
|
|
622
209
|
platform,
|
|
623
210
|
query,
|
|
624
|
-
skippedCount: discovered.skippedCount
|
|
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
|
+
}
|