pi-agent-browser-native 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -5
- package/README.md +120 -86
- package/dist/extensions/agent-browser/index.js +43065 -2016
- 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 +113 -49
- 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 -81
- 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 +44 -9
- package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +107 -66
- 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 +171 -57
- 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 +204 -108
- 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 -199
- 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 -1114
- 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 -910
- 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 -753
- 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 -816
- 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 -139
- package/dist/extensions/agent-browser/lib/orchestration/operation-paths.js +124 -58
- package/dist/extensions/agent-browser/lib/orchestration/output-file.js +198 -98
- 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 +59 -243
- package/dist/extensions/agent-browser/lib/parsing.js +13 -4
- package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +134 -68
- package/dist/extensions/agent-browser/lib/playbook.js +18 -14
- package/dist/extensions/agent-browser/lib/process-child.js +284 -0
- package/dist/extensions/agent-browser/lib/process-environment.js +22 -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 +146 -537
- 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 +138 -35
- 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 -10
- 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 +93 -66
- 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 -552
- 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 -1019
- 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 +117 -237
- 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 -248
- 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 +123 -123
- 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 -1037
- 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 +188 -324
- 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 +22 -10
- package/docs/CODE_QUALITY.md +242 -0
- package/docs/COMMAND_REFERENCE.md +264 -229
- package/docs/ELECTRON.md +53 -44
- package/docs/RELEASE.md +21 -17
- package/docs/REQUIREMENTS.md +2 -0
- package/docs/SESSION_STORAGE.md +1 -1
- package/docs/SUPPORT_MATRIX.md +84 -77
- package/docs/TOOL_CONTRACT.md +165 -130
- 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,48 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { isCloseCommand } from "../../command-taxonomy.js";
|
|
2
|
+
import { getSessionPageStateKey } from "../../session-page-state.js";
|
|
3
|
+
export { buildManagedSessionOutcome, formatManagedSessionOutcomeText, buildManagedSessionFreshFailureNextActions, } from "./session-state-outcomes.js";
|
|
4
|
+
export { extractStringResultField, extractNavigationSummaryFromData, shouldCaptureNavigationSummary, mergeNavigationSummaryIntoData, buildAboutBlankRecoveryHint, buildAboutBlankWarning, extractBatchResultCommand, } from "./session-state-observations.js";
|
|
5
|
+
export { getStaleRefArgs, getGuardedRefUsage, buildStaleRefPreflight, } from "./session-state-refs.js";
|
|
6
|
+
export { withSessionCommandObservation, nativePolicyDefinitelyUnestablished, runSessionCommandData, } from "./session-state-commands.js";
|
|
7
|
+
export { commandChoosesSessionTabTarget, shouldPinSessionTabForCommand, shouldCorrectSessionTabAfterCommand, collectOpenResultTabCorrection, collectSessionTabTarget, collectSessionTabSelection, ensureSessionTabTarget, applyOpenResultTabCorrection, } from "./session-state-tabs.js";
|
|
8
|
+
export { isLiveElectronRendererTarget, getLiveElectronRendererTargets, electronTargetLabel, getActiveElectronRecords, findElectronLaunchRecordForSession, buildElectronMismatchNextActions, buildElectronSessionMismatch, formatElectronSessionMismatchText, shouldInspectElectronPostCommandHealth, buildElectronLifecycleNextActions, buildElectronPostCommandHealthDiagnostic, formatElectronPostCommandHealthText, buildElectronIdentifiers, buildElectronRefFreshnessNextActions, buildElectronRefFreshnessDiagnostic, formatElectronRefFreshnessText, } from "./session-state-electron.js";
|
|
9
|
+
function managedLaunchUpdate(patch) {
|
|
10
|
+
return {
|
|
11
|
+
...("managedSessionCompatibilityWorkaround" in patch
|
|
12
|
+
? { managedSessionCompatibilityWorkaround: patch.managedSessionCompatibilityWorkaround }
|
|
13
|
+
: {}),
|
|
14
|
+
...(patch.managedSessionHeadedAutosaveDisabled !== undefined
|
|
15
|
+
? { managedSessionHeadedAutosaveDisabled: patch.managedSessionHeadedAutosaveDisabled }
|
|
16
|
+
: {}),
|
|
17
|
+
...("managedSessionHeadedAutosaveInterval" in patch
|
|
18
|
+
? { managedSessionHeadedAutosaveInterval: patch.managedSessionHeadedAutosaveInterval }
|
|
19
|
+
: {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function managedIdentityUpdate(patch) {
|
|
23
|
+
return {
|
|
24
|
+
...(patch.managedSessionCwd !== undefined
|
|
25
|
+
? { managedSessionCwd: patch.managedSessionCwd }
|
|
26
|
+
: {}),
|
|
27
|
+
...(patch.managedSessionName !== undefined
|
|
28
|
+
? { managedSessionName: patch.managedSessionName }
|
|
29
|
+
: {}),
|
|
30
|
+
...("managedSessionNamespace" in patch
|
|
31
|
+
? { managedSessionNamespace: patch.managedSessionNamespace }
|
|
32
|
+
: {}),
|
|
33
|
+
...(patch.managedSessionActive !== undefined
|
|
34
|
+
? { managedSessionActive: patch.managedSessionActive }
|
|
35
|
+
: {}),
|
|
36
|
+
...(patch.freshSessionOrdinal !== undefined
|
|
37
|
+
? { freshSessionOrdinal: patch.freshSessionOrdinal }
|
|
38
|
+
: {}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
17
41
|
export function applyBrowserRunStatePatch(state, patch) {
|
|
18
|
-
if (!patch)
|
|
42
|
+
if (!patch) {
|
|
19
43
|
return;
|
|
20
|
-
|
|
44
|
+
}
|
|
45
|
+
if ("artifactManifest" in patch) {
|
|
21
46
|
state.artifactManifest = patch.artifactManifest;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (patch.managedSessionActive !== undefined)
|
|
25
|
-
state.managedSessionActive = patch.managedSessionActive;
|
|
26
|
-
if ("managedSessionCompatibilityWorkaround" in patch)
|
|
27
|
-
state.managedSessionCompatibilityWorkaround = patch.managedSessionCompatibilityWorkaround;
|
|
28
|
-
if (patch.managedSessionHeadedAutosaveDisabled !== undefined)
|
|
29
|
-
state.managedSessionHeadedAutosaveDisabled = patch.managedSessionHeadedAutosaveDisabled;
|
|
30
|
-
if ("managedSessionHeadedAutosaveInterval" in patch)
|
|
31
|
-
state.managedSessionHeadedAutosaveInterval = patch.managedSessionHeadedAutosaveInterval;
|
|
32
|
-
if (patch.managedSessionCwd !== undefined)
|
|
33
|
-
state.managedSessionCwd = patch.managedSessionCwd;
|
|
34
|
-
if (patch.managedSessionName !== undefined)
|
|
35
|
-
state.managedSessionName = patch.managedSessionName;
|
|
36
|
-
if ("managedSessionNamespace" in patch)
|
|
37
|
-
state.managedSessionNamespace = patch.managedSessionNamespace;
|
|
38
|
-
if (patch.networkRoutesBySession)
|
|
47
|
+
}
|
|
48
|
+
if (patch.networkRoutesBySession) {
|
|
39
49
|
state.networkRoutesBySession = patch.networkRoutesBySession;
|
|
50
|
+
}
|
|
51
|
+
Object.assign(state, managedLaunchUpdate(patch), managedIdentityUpdate(patch));
|
|
40
52
|
}
|
|
41
53
|
export const getSessionContextKey = getSessionPageStateKey;
|
|
42
54
|
export function buildSessionDetailFields(sessionName, usedImplicitSession, namespace, managedSessionRestoreDisabled = false) {
|
|
43
55
|
return {
|
|
44
56
|
...(namespace !== undefined ? { namespace } : {}),
|
|
45
|
-
...(sessionName
|
|
57
|
+
...((sessionName?.length ?? 0) > 0
|
|
46
58
|
? {
|
|
47
59
|
sessionName,
|
|
48
60
|
usedImplicitSession,
|
|
@@ -51,743 +63,55 @@ export function buildSessionDetailFields(sessionName, usedImplicitSession, names
|
|
|
51
63
|
: {}),
|
|
52
64
|
};
|
|
53
65
|
}
|
|
54
|
-
export function buildManagedSessionOutcome(options) {
|
|
55
|
-
const { activeAfter, activeBefore, attemptedSessionName, command, currentSessionName, currentSessionNamespace, previousSessionName, replacedSessionName, replacedSessionNamespace, sessionMode, succeeded } = options;
|
|
56
|
-
if (!attemptedSessionName)
|
|
57
|
-
return undefined;
|
|
58
|
-
let status;
|
|
59
|
-
let summary;
|
|
60
|
-
if (isCloseCommand(command)) {
|
|
61
|
-
status = succeeded ? "closed" : activeBefore ? "preserved" : "abandoned";
|
|
62
|
-
summary = succeeded
|
|
63
|
-
? `Managed session ${attemptedSessionName} was closed.`
|
|
64
|
-
: activeBefore
|
|
65
|
-
? `Managed session close failed; previous managed session ${previousSessionName} remains current.`
|
|
66
|
-
: `Managed session close failed; no managed session is active.`;
|
|
67
|
-
}
|
|
68
|
-
else if (succeeded) {
|
|
69
|
-
if (replacedSessionName) {
|
|
70
|
-
status = "replaced";
|
|
71
|
-
summary = `Managed session ${replacedSessionName} was replaced by ${currentSessionName}.`;
|
|
72
|
-
}
|
|
73
|
-
else if (!activeBefore && activeAfter) {
|
|
74
|
-
status = "created";
|
|
75
|
-
summary = `Managed session ${currentSessionName} is now current.`;
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
status = "unchanged";
|
|
79
|
-
summary = `Managed session ${currentSessionName} remains current.`;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else if (activeBefore) {
|
|
83
|
-
status = "preserved";
|
|
84
|
-
summary = sessionMode === "fresh" && attemptedSessionName !== previousSessionName
|
|
85
|
-
? `Fresh managed session ${attemptedSessionName} failed before becoming current; previous managed session ${previousSessionName} was preserved.`
|
|
86
|
-
: `Managed session call failed; previous managed session ${previousSessionName} was preserved.`;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
status = "abandoned";
|
|
90
|
-
summary = sessionMode === "fresh"
|
|
91
|
-
? `Fresh managed session ${attemptedSessionName} failed before becoming current; no previous managed session was active, so no managed session is current.`
|
|
92
|
-
: `Managed session call failed before any managed session became current.`;
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
95
|
-
activeAfter,
|
|
96
|
-
activeBefore,
|
|
97
|
-
attemptedSessionName,
|
|
98
|
-
currentSessionName,
|
|
99
|
-
...(currentSessionNamespace ? { currentSessionNamespace } : {}),
|
|
100
|
-
previousSessionName,
|
|
101
|
-
replacedSessionName,
|
|
102
|
-
replacedSessionNamespace,
|
|
103
|
-
sessionMode,
|
|
104
|
-
status,
|
|
105
|
-
succeeded,
|
|
106
|
-
summary,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
function isFreshPostLaunchFailure(outcome) {
|
|
110
|
-
return !outcome.succeeded && outcome.sessionMode === "fresh" && outcome.activeAfter && !!outcome.currentSessionName && (outcome.status === "created" || outcome.status === "replaced" || outcome.status === "unchanged");
|
|
111
|
-
}
|
|
112
|
-
function formatManagedSessionOutcomeHeadline(outcome) {
|
|
113
|
-
if (outcome.status === "preserved") {
|
|
114
|
-
return "Managed session outcome: Fresh launch failed; your previous browser session is still active.";
|
|
115
|
-
}
|
|
116
|
-
if (outcome.status === "abandoned") {
|
|
117
|
-
return "Managed session outcome: Fresh launch failed; no managed browser session is current.";
|
|
118
|
-
}
|
|
119
|
-
if (isFreshPostLaunchFailure(outcome)) {
|
|
120
|
-
return "Managed session outcome: Fresh launch became current, but this tool call failed after launch.";
|
|
121
|
-
}
|
|
122
|
-
return `Managed session outcome: ${outcome.summary}`;
|
|
123
|
-
}
|
|
124
|
-
function formatManagedSessionOutcomeRecoveryGuidance(outcome) {
|
|
125
|
-
const lines = ["Recovery:"];
|
|
126
|
-
if (outcome.status === "preserved") {
|
|
127
|
-
lines.push('- Continue with sessionMode "auto" on the current session, or retry the intended launch with sessionMode "fresh".');
|
|
128
|
-
lines.push("- Run doctor to verify agent-browser install and environment when failures persist.");
|
|
129
|
-
}
|
|
130
|
-
else if (outcome.status === "abandoned") {
|
|
131
|
-
lines.push('- Retry with sessionMode "fresh" (for example args: ["open", "<url>"]) after verifying agent-browser is on PATH.');
|
|
132
|
-
lines.push("- Run doctor when install or environment issues are suspected.");
|
|
133
|
-
}
|
|
134
|
-
else if (isFreshPostLaunchFailure(outcome)) {
|
|
135
|
-
lines.push('- Continue with sessionMode "auto" on the current session, or inspect failureCategory / qaPreset to fix the post-launch failure.');
|
|
136
|
-
lines.push("- Run doctor only if later browser commands also fail.");
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
lines.push('- Retry with sessionMode "fresh" when launch-scoped flags must apply, or run doctor to verify the environment.');
|
|
140
|
-
}
|
|
141
|
-
lines.push("- Full session names and transition details remain in details.managedSessionOutcome.");
|
|
142
|
-
return lines.join("\n");
|
|
143
|
-
}
|
|
144
|
-
export function formatManagedSessionOutcomeText(outcome) {
|
|
145
|
-
if (!outcome)
|
|
146
|
-
return undefined;
|
|
147
|
-
if (outcome.replacedSessionClosed === false) {
|
|
148
|
-
const cleanupWarning = "Cleanup warning: Automatic close of the previous wrapper-managed session failed, so it remains wrapper-owned. Use details.managedSessionOutcome for its exact identity and close it explicitly when safe.";
|
|
149
|
-
return outcome.succeeded
|
|
150
|
-
? ["Managed session outcome: The fresh browser became current.", cleanupWarning].join("\n")
|
|
151
|
-
: [formatManagedSessionOutcomeHeadline(outcome), formatManagedSessionOutcomeRecoveryGuidance(outcome), cleanupWarning].join("\n");
|
|
152
|
-
}
|
|
153
|
-
if (outcome.status === "closed" && outcome.succeeded) {
|
|
154
|
-
return [
|
|
155
|
-
"Managed session outcome: The current wrapper-managed browser session was closed.",
|
|
156
|
-
"Next sessionMode auto call will start or attach a managed session as needed. If upstream session list still shows rows, they are separate saved/upstream sessions; use close --all only when full cleanup is intended.",
|
|
157
|
-
"Full session names and transition details remain in details.managedSessionOutcome.",
|
|
158
|
-
].join("\n");
|
|
159
|
-
}
|
|
160
|
-
if (outcome.succeeded || outcome.sessionMode !== "fresh")
|
|
161
|
-
return undefined;
|
|
162
|
-
return [formatManagedSessionOutcomeHeadline(outcome), formatManagedSessionOutcomeRecoveryGuidance(outcome)].join("\n");
|
|
163
|
-
}
|
|
164
|
-
export function buildManagedSessionFreshFailureNextActions(outcome) {
|
|
165
|
-
if (!outcome || outcome.succeeded || outcome.sessionMode !== "fresh")
|
|
166
|
-
return [];
|
|
167
|
-
const actions = [];
|
|
168
|
-
if (!isFreshPostLaunchFailure(outcome)) {
|
|
169
|
-
actions.push(buildNextToolAction({
|
|
170
|
-
args: ["doctor"],
|
|
171
|
-
id: "run-agent-browser-doctor",
|
|
172
|
-
reason: "Verify agent-browser install, PATH, and environment after a failed fresh launch.",
|
|
173
|
-
safety: "Read-only local diagnostics; does not mutate browser state.",
|
|
174
|
-
}));
|
|
175
|
-
}
|
|
176
|
-
if ((outcome.status === "preserved" || isFreshPostLaunchFailure(outcome)) && outcome.activeAfter && outcome.currentSessionName) {
|
|
177
|
-
const sessionLabel = isFreshPostLaunchFailure(outcome) ? "current managed session" : "preserved managed session";
|
|
178
|
-
const currentSessionArgs = (args) => withOptionalNamespaceArgs(outcome.currentSessionNamespace, withOptionalSessionArgs(outcome.currentSessionName, args));
|
|
179
|
-
actions.push(buildNextToolAction({
|
|
180
|
-
args: currentSessionArgs(["get", "url"]),
|
|
181
|
-
id: "verify-current-managed-session",
|
|
182
|
-
reason: `Confirm the ${sessionLabel} before continuing with sessionMode auto.`,
|
|
183
|
-
safety: `Read-only URL check on the ${sessionLabel}.`,
|
|
184
|
-
}), buildNextToolAction({
|
|
185
|
-
args: currentSessionArgs(["snapshot", "-i"]),
|
|
186
|
-
id: "snapshot-current-managed-session",
|
|
187
|
-
reason: `Refresh interactive refs on the ${sessionLabel} before retrying the workflow.`,
|
|
188
|
-
safety: "Read-only snapshot; no navigation.",
|
|
189
|
-
}));
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
actions.push(buildNextToolAction({
|
|
193
|
-
args: ["open", "about:blank"],
|
|
194
|
-
id: "retry-fresh-managed-session",
|
|
195
|
-
reason: "Start a new managed browser session after the failed fresh launch.",
|
|
196
|
-
safety: "Replace about:blank with the intended URL from your workflow.",
|
|
197
|
-
sessionMode: "fresh",
|
|
198
|
-
}));
|
|
199
|
-
}
|
|
200
|
-
return actions;
|
|
201
|
-
}
|
|
202
66
|
function getTraceOwner(command) {
|
|
203
67
|
return command === "trace" || command === "profiler" ? command : undefined;
|
|
204
68
|
}
|
|
205
69
|
export function getTraceOwnerGuardMessage(options) {
|
|
206
70
|
const owner = getTraceOwner(options.command);
|
|
207
|
-
|
|
208
|
-
|
|
71
|
+
const sessionName = options.sessionName;
|
|
72
|
+
if (owner === undefined ||
|
|
73
|
+
sessionName === undefined ||
|
|
74
|
+
sessionName.length === 0 ||
|
|
75
|
+
(options.subcommand !== "start" && options.subcommand !== "stop")) {
|
|
76
|
+
return;
|
|
209
77
|
}
|
|
210
|
-
const activeOwner = options.traceOwners.get(
|
|
211
|
-
if (
|
|
212
|
-
return
|
|
78
|
+
const activeOwner = options.traceOwners.get(sessionName);
|
|
79
|
+
if (activeOwner === undefined || activeOwner === owner) {
|
|
80
|
+
return;
|
|
213
81
|
}
|
|
214
82
|
return options.subcommand === "start"
|
|
215
|
-
? `Wrapper believes ${activeOwner} tracing is active for session ${
|
|
216
|
-
: `Wrapper believes tracing for session ${
|
|
83
|
+
? `Wrapper believes ${activeOwner} tracing is active for session ${sessionName}; stop ${activeOwner} before starting ${owner}.`
|
|
84
|
+
: `Wrapper believes tracing for session ${sessionName} is owned by ${activeOwner}; run ${activeOwner} stop instead of ${owner} stop.`;
|
|
217
85
|
}
|
|
218
86
|
export function updateTraceOwnerState(options) {
|
|
219
|
-
|
|
87
|
+
const sessionName = options.sessionName;
|
|
88
|
+
if (sessionName === undefined || sessionName.length === 0 || !options.succeeded) {
|
|
220
89
|
return;
|
|
90
|
+
}
|
|
221
91
|
if (isCloseCommand(options.command)) {
|
|
222
|
-
options.traceOwners.delete(
|
|
92
|
+
options.traceOwners.delete(sessionName);
|
|
223
93
|
return;
|
|
224
94
|
}
|
|
225
95
|
const owner = getTraceOwner(options.command);
|
|
226
|
-
if (
|
|
96
|
+
if (owner === undefined) {
|
|
227
97
|
return;
|
|
228
|
-
if (options.subcommand === "start") {
|
|
229
|
-
options.traceOwners.set(options.sessionName, owner);
|
|
230
|
-
}
|
|
231
|
-
if (options.subcommand === "stop" && options.traceOwners.get(options.sessionName) === owner) {
|
|
232
|
-
options.traceOwners.delete(options.sessionName);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
export function extractStringResultField(data, fieldName) {
|
|
236
|
-
if (typeof data === "string") {
|
|
237
|
-
if (fieldName === "value")
|
|
238
|
-
return data;
|
|
239
|
-
const text = data.trim();
|
|
240
|
-
return text.length > 0 ? text : undefined;
|
|
241
|
-
}
|
|
242
|
-
if (!isRecord(data) || typeof data[fieldName] !== "string") {
|
|
243
|
-
return undefined;
|
|
244
|
-
}
|
|
245
|
-
if (fieldName === "value")
|
|
246
|
-
return data[fieldName];
|
|
247
|
-
const text = data[fieldName].trim();
|
|
248
|
-
return text.length > 0 ? text : undefined;
|
|
249
|
-
}
|
|
250
|
-
export function extractNavigationSummaryFromData(data) {
|
|
251
|
-
const result = isRecord(data) && isRecord(data.result) ? data.result : data;
|
|
252
|
-
const title = extractStringResultField(result, "title");
|
|
253
|
-
const url = extractStringResultField(result, "url");
|
|
254
|
-
const urlChanged = isRecord(result) && typeof result.urlChanged === "boolean" ? result.urlChanged : undefined;
|
|
255
|
-
return title || url ? { title, url, urlChanged } : undefined;
|
|
256
|
-
}
|
|
257
|
-
export function shouldCaptureNavigationSummary(command, data, subcommand) {
|
|
258
|
-
if (command === "eval")
|
|
259
|
-
return true;
|
|
260
|
-
return (isNavigationObservableCommandName(command, subcommand) &&
|
|
261
|
-
(!isRecord(data) || (typeof data.title !== "string" && typeof data.url !== "string")));
|
|
262
|
-
}
|
|
263
|
-
export function mergeNavigationSummaryIntoData(data, navigationSummary) {
|
|
264
|
-
if (isRecord(data)) {
|
|
265
|
-
return { ...data, navigationSummary };
|
|
266
|
-
}
|
|
267
|
-
return { navigationSummary, result: data };
|
|
268
|
-
}
|
|
269
|
-
export function buildAboutBlankRecoveryHint() {
|
|
270
|
-
return "agent_browser detected that the active tab became about:blank while this session still had a prior intended tab. Run tab list for this session and re-select the intended tab, or retry with sessionMode:fresh if the tab is gone.".replace("sessionMode:fresh", "sessionMode=fresh");
|
|
271
|
-
}
|
|
272
|
-
export function buildAboutBlankWarning(mismatch) {
|
|
273
|
-
return `Warning: agent_browser detected that this session returned about:blank while the prior intended tab was ${mismatch.targetUrl}. ${mismatch.recoveryApplied ? "The wrapper re-selected the intended tab for the session." : "No matching tab could be re-selected; run tab list for the same session or retry with sessionMode=fresh."}`;
|
|
274
|
-
}
|
|
275
|
-
function extractBatchResultCommand(item) {
|
|
276
|
-
return Array.isArray(item.command) ? item.command.filter((token) => typeof token === "string") : [];
|
|
277
|
-
}
|
|
278
|
-
export function getStaleRefArgs(commandTokens, stdin) {
|
|
279
|
-
if (commandTokens[0] !== "batch") {
|
|
280
|
-
return commandTokens;
|
|
281
|
-
}
|
|
282
|
-
const steps = getUpstreamEffectiveBatchSteps(commandTokens, stdin);
|
|
283
|
-
return steps.length > 0 ? steps.flatMap((step) => step) : commandTokens;
|
|
284
|
-
}
|
|
285
|
-
// Inspect only upstream's selector slots: fill text, file paths and key data are not refs.
|
|
286
|
-
function collectRefsFromTokens(tokens) {
|
|
287
|
-
if (!isRefGuardedCommand(tokens[0]) || (tokens[0] === "diff" && tokens[1] !== "screenshot"))
|
|
288
|
-
return [];
|
|
289
|
-
let selectors;
|
|
290
|
-
switch (tokens[0]) {
|
|
291
|
-
case "click":
|
|
292
|
-
selectors = [tokens.slice(1).find((token) => token !== "--new-tab" && token !== "--human")];
|
|
293
|
-
break;
|
|
294
|
-
case "drag":
|
|
295
|
-
selectors = tokens.slice(1, 3);
|
|
296
|
-
break;
|
|
297
|
-
case "get":
|
|
298
|
-
selectors = [!["url", "title", "cdp-url", "count"].includes(tokens[1]) ? tokens[2] : undefined];
|
|
299
|
-
break;
|
|
300
|
-
case "is":
|
|
301
|
-
selectors = [tokens[2]];
|
|
302
|
-
break;
|
|
303
|
-
case "screenshot":
|
|
304
|
-
selectors = [tokens[getScreenshotPositionalIndices(tokens)[0]]];
|
|
305
|
-
break;
|
|
306
|
-
case "diff":
|
|
307
|
-
case "scroll": {
|
|
308
|
-
let selector;
|
|
309
|
-
for (let index = tokens[0] === "diff" ? 2 : 1; index < tokens.length; index += 1) {
|
|
310
|
-
const token = tokens[index];
|
|
311
|
-
if (token === "--selector" || token === "-s")
|
|
312
|
-
selector = tokens[++index];
|
|
313
|
-
else if (tokens[0] === "diff" && ["--baseline", "-b", "--output", "-o", "--threshold", "-t", "--depth", "-d"].includes(token))
|
|
314
|
-
index += 1;
|
|
315
|
-
}
|
|
316
|
-
selectors = [selector];
|
|
317
|
-
break;
|
|
318
|
-
}
|
|
319
|
-
default: selectors = [tokens[1]];
|
|
320
|
-
}
|
|
321
|
-
return selectors.flatMap((selector) => {
|
|
322
|
-
const ref = selector === undefined ? undefined : parseRefId(selector);
|
|
323
|
-
return ref === undefined ? [] : [ref];
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
export function getGuardedRefUsage(commandTokens, stdin, options = {}) {
|
|
327
|
-
if (commandTokens[0] !== "batch") {
|
|
328
|
-
return collectRefsFromTokens(commandTokens);
|
|
329
|
-
}
|
|
330
|
-
const steps = getUpstreamEffectiveBatchSteps(commandTokens, stdin);
|
|
331
|
-
const refsBeforeInBatchSnapshot = [];
|
|
332
|
-
for (const step of steps) {
|
|
333
|
-
if (!options.includeRefsAfterBatchSnapshot && (step[0] ?? "") === "snapshot")
|
|
334
|
-
break;
|
|
335
|
-
refsBeforeInBatchSnapshot.push(...collectRefsFromTokens(step));
|
|
336
|
-
}
|
|
337
|
-
return refsBeforeInBatchSnapshot;
|
|
338
|
-
}
|
|
339
|
-
function getSnapshotRefRole(refSnapshot, refId) {
|
|
340
|
-
return refSnapshot?.refs?.[refId]?.role?.toLowerCase();
|
|
341
|
-
}
|
|
342
|
-
function isSafeSameSnapshotFormBatchStep(step, refSnapshot) {
|
|
343
|
-
const command = step[0];
|
|
344
|
-
const refIds = collectRefsFromTokens(step);
|
|
345
|
-
if (refIds.length === 0 || !refSnapshot)
|
|
346
|
-
return false;
|
|
347
|
-
const roles = refIds.map((refId) => getSnapshotRefRole(refSnapshot, refId));
|
|
348
|
-
if (roles.some((role) => role === undefined))
|
|
349
|
-
return false;
|
|
350
|
-
if (command === "check" || command === "uncheck")
|
|
351
|
-
return roles.every((role) => role === "checkbox" || role === "radio");
|
|
352
|
-
if (command === "click" || command === "tap")
|
|
353
|
-
return roles.every((role) => role === "checkbox" || role === "radio");
|
|
354
|
-
if (command === "select")
|
|
355
|
-
return roles.every((role) => role === "combobox");
|
|
356
|
-
return false;
|
|
357
|
-
}
|
|
358
|
-
function getBatchRefInvalidationMessage(commandTokens, stdin, refSnapshot) {
|
|
359
|
-
if (commandTokens[0] !== "batch")
|
|
360
|
-
return undefined;
|
|
361
|
-
let priorStepInvalidatesRefs = false;
|
|
362
|
-
for (const step of getUpstreamEffectiveBatchSteps(commandTokens, stdin)) {
|
|
363
|
-
if ((step[0] ?? "") === "snapshot") {
|
|
364
|
-
priorStepInvalidatesRefs = false;
|
|
365
|
-
}
|
|
366
|
-
const refIds = collectRefsFromTokens(step);
|
|
367
|
-
if (refIds.length > 0 && isRefGuardedCommand(step[0]) && priorStepInvalidatesRefs) {
|
|
368
|
-
return `Batch step ${step[0]} uses page-scoped ref ${refIds.map((refId) => `@${refId}`).join(", ")} after an earlier batch step can navigate or mutate the page. Split the batch, run snapshot -i after the page-changing step, then retry with current refs.`;
|
|
369
|
-
}
|
|
370
|
-
if (isRefInvalidatingBatchCommand(step) && !isSafeSameSnapshotFormBatchStep(step, refSnapshot)) {
|
|
371
|
-
priorStepInvalidatesRefs = true;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
return undefined;
|
|
375
|
-
}
|
|
376
|
-
export function buildStaleRefPreflight(options) {
|
|
377
|
-
const guardedRefIds = [...new Set(getGuardedRefUsage(options.commandTokens, options.stdin))];
|
|
378
|
-
const usedRefIds = options.refSnapshotInvalidation
|
|
379
|
-
? [...new Set(getGuardedRefUsage(options.commandTokens, options.stdin, { includeRefsAfterBatchSnapshot: true }))]
|
|
380
|
-
: guardedRefIds;
|
|
381
|
-
const batchInvalidationMessage = getBatchRefInvalidationMessage(options.commandTokens, options.stdin, options.refSnapshot);
|
|
382
|
-
if (batchInvalidationMessage && guardedRefIds.length > 0) {
|
|
383
|
-
return {
|
|
384
|
-
message: batchInvalidationMessage,
|
|
385
|
-
refIds: guardedRefIds,
|
|
386
|
-
snapshot: options.refSnapshot,
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
if (usedRefIds.length === 0)
|
|
390
|
-
return undefined;
|
|
391
|
-
if (options.refSnapshotInvalidation) {
|
|
392
|
-
return {
|
|
393
|
-
message: options.refSnapshotInvalidation.reason === "page-transition"
|
|
394
|
-
? `Ref ${usedRefIds.map((refId) => `@${refId}`).join(", ")} cannot be used yet. ${options.refSnapshotInvalidation.summary}`
|
|
395
|
-
: `Ref ${usedRefIds.map((refId) => `@${refId}`).join(", ")} cannot be used because the latest snapshot for this session reported No active page. Run snapshot -i successfully before using page-scoped refs.`,
|
|
396
|
-
refIds: usedRefIds,
|
|
397
|
-
snapshotInvalidation: options.refSnapshotInvalidation,
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
if (!options.refSnapshot)
|
|
401
|
-
return undefined;
|
|
402
|
-
if (!targetsMatch(options.refSnapshot.target, options.currentTarget)) {
|
|
403
|
-
return {
|
|
404
|
-
message: `Ref ${usedRefIds.map((refId) => `@${refId}`).join(", ")} came from a snapshot for ${options.refSnapshot.target?.url ?? "a prior page"}, but the current session target is ${options.currentTarget?.url ?? "unknown"}. Run snapshot -i again before using page-scoped refs.`,
|
|
405
|
-
refIds: usedRefIds,
|
|
406
|
-
snapshot: options.refSnapshot,
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
const knownRefs = new Set(options.refSnapshot.refIds);
|
|
410
|
-
const missingRefs = usedRefIds.filter((refId) => !knownRefs.has(refId));
|
|
411
|
-
if (missingRefs.length > 0) {
|
|
412
|
-
return {
|
|
413
|
-
message: `Ref ${missingRefs.map((refId) => `@${refId}`).join(", ")} was not present in the latest snapshot for this session. Run snapshot -i again before using page-scoped refs.`,
|
|
414
|
-
refIds: missingRefs,
|
|
415
|
-
snapshot: options.refSnapshot,
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
return undefined;
|
|
419
|
-
}
|
|
420
|
-
export function commandChoosesSessionTabTarget(args) {
|
|
421
|
-
const tokens = parseArgvDescriptor(args).upstreamCommandTokens;
|
|
422
|
-
const [command, subcommand] = tokens;
|
|
423
|
-
return isOpenNavigationCommand(command) || isCloseCommand(command) || command === "connect"
|
|
424
|
-
|| (command === "state" && subcommand === "load")
|
|
425
|
-
|| (command === "tab" && subcommand !== undefined && subcommand !== "list")
|
|
426
|
-
|| isWindowOrDiffPageTransitionCommand(command, subcommand)
|
|
427
|
-
|| (command === "a11y" && findFirstPositionalArgument(tokens) !== undefined)
|
|
428
|
-
|| (["vitals", "web-vitals"].includes(command) && tokens.slice(1).some((token) => !token.startsWith("--")))
|
|
429
|
-
|| getRecordCommandOperands(tokens).url !== undefined;
|
|
430
|
-
}
|
|
431
|
-
export function shouldPinSessionTabForCommand(options) {
|
|
432
|
-
if (!options.pinningRequired || !options.sessionName || !options.command || isBrowserIndependentRead(options.commandTokens, options.stdin))
|
|
433
|
-
return false;
|
|
434
|
-
const steps = options.command === "batch" ? getUpstreamEffectiveBatchSteps(options.commandTokens, options.stdin) : [options.commandTokens];
|
|
435
|
-
for (const step of steps) {
|
|
436
|
-
const descriptor = parseArgvDescriptor(step);
|
|
437
|
-
const tokens = descriptor.upstreamCommandTokens;
|
|
438
|
-
const [command, subcommand] = tokens;
|
|
439
|
-
// A later page action uses the explicit destination, not the remembered tab.
|
|
440
|
-
if (commandChoosesSessionTabTarget(tokens))
|
|
441
|
-
return false;
|
|
442
|
-
if (!needsManagedSession(descriptor) || isSessionTabPinningExcludedCommand(command))
|
|
443
|
-
continue;
|
|
444
|
-
if (command === "get" && subcommand === "url" && !options.reopenPending)
|
|
445
|
-
continue;
|
|
446
|
-
if (command === "record" && subcommand === "stop")
|
|
447
|
-
continue;
|
|
448
|
-
if (["console", "errors"].includes(command))
|
|
449
|
-
continue;
|
|
450
|
-
if (command === "network" && !(subcommand === "requests" && tokens.some((token) => ["--current-page", "--current-origin", "--current-url"].includes(token))))
|
|
451
|
-
continue;
|
|
452
|
-
return true;
|
|
453
|
-
}
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
export function shouldCorrectSessionTabAfterCommand(options) {
|
|
457
|
-
return (options.pinningRequired === true &&
|
|
458
|
-
options.sessionName !== undefined &&
|
|
459
|
-
options.command !== undefined &&
|
|
460
|
-
!isSessionTabPostCommandCorrectionExcludedCommand(options.command));
|
|
461
|
-
}
|
|
462
|
-
function getTabSelection(tab) {
|
|
463
|
-
if (tab.targetId)
|
|
464
|
-
return { selectedTab: tab.targetId, selectionKind: "targetId" };
|
|
465
|
-
if (typeof tab.tabId === "string" && tab.tabId.trim().length > 0)
|
|
466
|
-
return { selectedTab: tab.tabId.trim(), selectionKind: "tabId" };
|
|
467
|
-
if (typeof tab.label === "string" && tab.label.trim().length > 0)
|
|
468
|
-
return { selectedTab: tab.label.trim(), selectionKind: "label" };
|
|
469
|
-
return typeof tab.index === "number" ? { selectedTab: String(tab.index), selectionKind: "index" } : undefined;
|
|
470
|
-
}
|
|
471
|
-
function selectSessionTargetTab(options) {
|
|
472
|
-
if (options.target.targetId) {
|
|
473
|
-
const target = selectAnySessionTargetTab(options);
|
|
474
|
-
return target && options.tabs.find((tab) => tab.targetId === options.target.targetId)?.active !== true ? target : undefined;
|
|
475
|
-
}
|
|
476
|
-
return chooseOpenResultTabCorrection({
|
|
477
|
-
tabs: options.tabs,
|
|
478
|
-
targetTitle: options.target.title,
|
|
479
|
-
targetUrl: options.target.url,
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
function selectAnySessionTargetTab(options) {
|
|
483
|
-
const targetUrl = typeof options.target.url === "string" ? normalizeComparableUrl(options.target.url) : undefined;
|
|
484
|
-
if (!targetUrl)
|
|
485
|
-
return undefined;
|
|
486
|
-
const matchingTabs = options.tabs.filter((tab) => options.target.targetId
|
|
487
|
-
? tab.targetId === options.target.targetId
|
|
488
|
-
: normalizeComparableUrl(tab.url ?? "") === targetUrl);
|
|
489
|
-
const targetTitle = options.target.title?.trim() ?? "";
|
|
490
|
-
const titledTabs = targetTitle ? matchingTabs.filter((tab) => tab.title?.trim() === targetTitle) : [];
|
|
491
|
-
const selectedTab = titledTabs.find((tab) => tab.active) ?? titledTabs[0] ?? matchingTabs.find((tab) => tab.active) ?? matchingTabs[0];
|
|
492
|
-
const selection = selectedTab ? getTabSelection(selectedTab) : undefined;
|
|
493
|
-
return selection ? { ...selection, ...(targetTitle ? { targetTitle } : {}), targetUrl } : undefined;
|
|
494
|
-
}
|
|
495
|
-
export async function runSessionCommandData(options) {
|
|
496
|
-
const { args, cwd, env, namespace, pinNamespace, sessionName, signal, stdin, throwOnFailure, timeoutMs } = options;
|
|
497
|
-
if (!sessionName)
|
|
498
|
-
return undefined;
|
|
499
|
-
const processResult = await runAgentBrowserProcess({
|
|
500
|
-
args: ["--json", ...(namespace !== undefined || pinNamespace ? ["--namespace", namespace ?? ""] : []), "--session", sessionName, ...args],
|
|
501
|
-
cwd,
|
|
502
|
-
env,
|
|
503
|
-
signal,
|
|
504
|
-
stdin,
|
|
505
|
-
timeoutMs,
|
|
506
|
-
});
|
|
507
|
-
try {
|
|
508
|
-
options.onProcessResult?.(processResult);
|
|
509
|
-
if (processResult.aborted || processResult.spawnError || processResult.exitCode !== 0) {
|
|
510
|
-
if (throwOnFailure) {
|
|
511
|
-
const reason = processResult.aborted
|
|
512
|
-
? "command was aborted"
|
|
513
|
-
: processResult.spawnError
|
|
514
|
-
? "process could not start"
|
|
515
|
-
: `process exited with code ${processResult.exitCode}`;
|
|
516
|
-
throw new Error(`agent-browser ${reason}`);
|
|
517
|
-
}
|
|
518
|
-
return undefined;
|
|
519
|
-
}
|
|
520
|
-
const parsed = await parseAgentBrowserEnvelope({
|
|
521
|
-
stdout: processResult.stdout,
|
|
522
|
-
stdoutPath: processResult.stdoutSpillPath,
|
|
523
|
-
});
|
|
524
|
-
if (parsed.parseError || parsed.envelope?.success === false) {
|
|
525
|
-
if (throwOnFailure)
|
|
526
|
-
throw new Error(parsed.parseError ? "agent-browser returned invalid structured output" : "agent-browser reported failure");
|
|
527
|
-
return undefined;
|
|
528
|
-
}
|
|
529
|
-
observeNativeWebMcp(parsed.envelope?.data);
|
|
530
|
-
return parsed.envelope?.data;
|
|
531
|
-
}
|
|
532
|
-
finally {
|
|
533
|
-
if (processResult.stdoutSpillPath) {
|
|
534
|
-
await rm(processResult.stdoutSpillPath, { force: true }).catch(() => undefined);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
export async function collectOpenResultTabCorrection(options) {
|
|
539
|
-
const { cwd, namespace, sessionName, signal, targetTitle, targetUrl } = options;
|
|
540
|
-
const tabData = await runSessionCommandData({ args: ["tab", "list"], cwd, namespace, sessionName, signal });
|
|
541
|
-
if (!isRecord(tabData) || !Array.isArray(tabData.tabs)) {
|
|
542
|
-
return undefined;
|
|
543
|
-
}
|
|
544
|
-
const tabs = tabData.tabs.filter(isRecord).map((tab, index) => ({
|
|
545
|
-
active: tab.active === true,
|
|
546
|
-
index: typeof tab.index === "number" ? tab.index : index,
|
|
547
|
-
label: typeof tab.label === "string" ? tab.label : undefined,
|
|
548
|
-
tabId: typeof tab.tabId === "string" ? tab.tabId : undefined,
|
|
549
|
-
targetId: typeof tab.targetId === "string" ? tab.targetId : undefined,
|
|
550
|
-
title: typeof tab.title === "string" ? tab.title : undefined,
|
|
551
|
-
url: typeof tab.url === "string" ? tab.url : undefined,
|
|
552
|
-
}));
|
|
553
|
-
return chooseOpenResultTabCorrection({ tabs, targetTitle, targetUrl });
|
|
554
|
-
}
|
|
555
|
-
function mapTabData(tabData) {
|
|
556
|
-
if (!isRecord(tabData) || !Array.isArray(tabData.tabs))
|
|
557
|
-
return undefined;
|
|
558
|
-
return tabData.tabs.filter(isRecord).map((tab, index) => ({
|
|
559
|
-
active: tab.active === true,
|
|
560
|
-
index: typeof tab.index === "number" ? tab.index : index,
|
|
561
|
-
label: typeof tab.label === "string" ? tab.label : undefined,
|
|
562
|
-
tabId: typeof tab.tabId === "string" ? tab.tabId : undefined,
|
|
563
|
-
targetId: typeof tab.targetId === "string" ? tab.targetId : undefined,
|
|
564
|
-
title: typeof tab.title === "string" ? tab.title : undefined,
|
|
565
|
-
url: typeof tab.url === "string" ? tab.url : undefined,
|
|
566
|
-
}));
|
|
567
|
-
}
|
|
568
|
-
export async function collectSessionTabTarget(options) {
|
|
569
|
-
const tabs = mapTabData(await runSessionCommandData({ ...options, args: ["tab", "list"] }));
|
|
570
|
-
const active = tabs?.find((tab) => tab.active);
|
|
571
|
-
const observedUrl = normalizeComparableUrl(options.target.url);
|
|
572
|
-
if (normalizeComparableUrl(active?.url) !== observedUrl && tabs?.some((tab) => normalizeComparableUrl(tab.url) === observedUrl))
|
|
573
|
-
return options.target;
|
|
574
|
-
return active?.targetId
|
|
575
|
-
? { ...options.target, targetId: active.targetId }
|
|
576
|
-
: options.target;
|
|
577
|
-
}
|
|
578
|
-
export async function collectSessionTabSelection(options) {
|
|
579
|
-
const { cwd, namespace, sessionName, signal, target } = options;
|
|
580
|
-
const tabData = await runSessionCommandData({ args: ["tab", "list"], cwd, namespace, sessionName, signal });
|
|
581
|
-
const tabs = mapTabData(tabData);
|
|
582
|
-
return tabs ? selectSessionTargetTab({ tabs, target }) : undefined;
|
|
583
|
-
}
|
|
584
|
-
export async function ensureSessionTabTarget(options) {
|
|
585
|
-
const readTabs = async () => mapTabData(await runSessionCommandData({ ...options, args: ["tab", "list"] }));
|
|
586
|
-
const tabs = await readTabs();
|
|
587
|
-
const active = tabs?.find((tab) => tab.active);
|
|
588
|
-
const correction = tabs && selectAnySessionTargetTab({ tabs, target: options.target });
|
|
589
|
-
const error = "agent-browser could not re-select and verify the intended tab before running the command. Run tab list and select the intended tab, then snapshot -i before retrying.";
|
|
590
|
-
if (!correction)
|
|
591
|
-
return { error };
|
|
592
|
-
const verifyUrl = async (tab) => {
|
|
593
|
-
if (normalizeComparableUrl(tab.url) === normalizeComparableUrl(options.target.url))
|
|
594
|
-
return true;
|
|
595
|
-
// Native tab metadata can retain the attempted URL while get url reports Chrome's error page.
|
|
596
|
-
const data = await runSessionCommandData({ ...options, args: ["get", "url"] });
|
|
597
|
-
return normalizeComparableUrl(extractStringResultField(data, "url")) === normalizeComparableUrl(options.target.url);
|
|
598
|
-
};
|
|
599
|
-
// Native tab selection clears refs and frame scope even when selecting the current tab.
|
|
600
|
-
if (active && getTabSelection(active)?.selectedTab === correction.selectedTab)
|
|
601
|
-
return await verifyUrl(active) ? {} : { error };
|
|
602
|
-
if (!await applyOpenResultTabCorrection({ ...options, correction }))
|
|
603
|
-
return { correction, error };
|
|
604
|
-
const selected = (await readTabs())?.find((tab) => tab.active);
|
|
605
|
-
return selected && getTabSelection(selected)?.selectedTab === correction.selectedTab && await verifyUrl(selected)
|
|
606
|
-
? { correction }
|
|
607
|
-
: { correction, error };
|
|
608
|
-
}
|
|
609
|
-
export async function applyOpenResultTabCorrection(options) {
|
|
610
|
-
const { correction, cwd, namespace, sessionName, signal } = options;
|
|
611
|
-
const result = await runSessionCommandData({
|
|
612
|
-
args: ["tab", correction.selectedTab],
|
|
613
|
-
cwd,
|
|
614
|
-
namespace,
|
|
615
|
-
sessionName,
|
|
616
|
-
signal,
|
|
617
|
-
});
|
|
618
|
-
return result === undefined ? undefined : correction;
|
|
619
|
-
}
|
|
620
|
-
export function isLiveElectronRendererTarget(target) {
|
|
621
|
-
const normalizedUrl = normalizeComparableUrl(target.url);
|
|
622
|
-
if (!normalizedUrl || normalizedUrl === "about:blank" || normalizedUrl.startsWith("devtools://"))
|
|
623
|
-
return false;
|
|
624
|
-
return target.type === undefined || target.type === "page" || target.type === "webview";
|
|
625
|
-
}
|
|
626
|
-
export function getLiveElectronRendererTargets(targets) {
|
|
627
|
-
return targets.filter(isLiveElectronRendererTarget);
|
|
628
|
-
}
|
|
629
|
-
export function electronTargetLabel(target) {
|
|
630
|
-
if (!target)
|
|
631
|
-
return "unknown target";
|
|
632
|
-
return [target.title, target.url, target.id].find((value) => typeof value === "string" && value.trim().length > 0) ?? "unknown target";
|
|
633
|
-
}
|
|
634
|
-
export function getActiveElectronRecords(records) {
|
|
635
|
-
return [...records.values()].filter((record) => record.cleanupState === "active" || record.cleanupState === "dead" || record.cleanupState === "partial" || record.cleanupState === "failed");
|
|
636
|
-
}
|
|
637
|
-
export function findElectronLaunchRecordForSession(sessionName, records, namespace) {
|
|
638
|
-
if (!sessionName)
|
|
639
|
-
return undefined;
|
|
640
|
-
const sessionKey = getAgentBrowserSessionIdentityKey(sessionName, namespace);
|
|
641
|
-
return getActiveElectronRecords(records).find((record) => record.sessionName && getAgentBrowserSessionIdentityKey(record.sessionName, record.namespace) === sessionKey);
|
|
642
|
-
}
|
|
643
|
-
function buildElectronReattachNextAction(record, liveTarget) {
|
|
644
|
-
const endpoint = liveTarget?.webSocketDebuggerUrl ?? record.webSocketDebuggerUrl ?? String(record.port);
|
|
645
|
-
return {
|
|
646
|
-
id: "reattach-electron-launch",
|
|
647
|
-
params: { args: ["connect", endpoint], sessionMode: "fresh" },
|
|
648
|
-
reason: "Attach a fresh managed session to the same wrapper-tracked Electron debug endpoint when the current session no longer matches the live renderer.",
|
|
649
|
-
safety: "Creates a new managed browser session; it does not mutate the Electron app. Keep the launchId for later status and cleanup.",
|
|
650
|
-
tool: "agent_browser",
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
export function buildElectronMismatchNextActions(record, liveTarget) {
|
|
654
|
-
const baseActions = buildAgentBrowserNextActions({
|
|
655
|
-
electron: { launchId: record.launchId, sessionName: record.sessionName, status: record.cleanupState },
|
|
656
|
-
resultCategory: "success",
|
|
657
|
-
successCategory: "completed",
|
|
658
|
-
}) ?? [];
|
|
659
|
-
const reattachAction = buildElectronReattachNextAction(record, liveTarget);
|
|
660
|
-
const actions = [];
|
|
661
|
-
for (const action of baseActions) {
|
|
662
|
-
actions.push(action);
|
|
663
|
-
if (action.id === "probe-electron-launch")
|
|
664
|
-
actions.push(reattachAction);
|
|
665
|
-
}
|
|
666
|
-
if (!actions.some((action) => action.id === reattachAction.id))
|
|
667
|
-
actions.push(reattachAction);
|
|
668
|
-
return actions;
|
|
669
|
-
}
|
|
670
|
-
export function buildElectronSessionMismatch(options) {
|
|
671
|
-
const liveTargets = getLiveElectronRendererTargets(options.statusTargets);
|
|
672
|
-
if (liveTargets.length === 0)
|
|
673
|
-
return undefined;
|
|
674
|
-
const managedUrl = normalizeComparableUrl(options.managedSession.url);
|
|
675
|
-
const matchingLiveTarget = managedUrl
|
|
676
|
-
? liveTargets.find((target) => normalizeComparableUrl(target.url) === managedUrl)
|
|
677
|
-
: undefined;
|
|
678
|
-
if (matchingLiveTarget)
|
|
679
|
-
return undefined;
|
|
680
|
-
const liveTarget = liveTargets[0];
|
|
681
|
-
let reason;
|
|
682
|
-
if (isAboutBlankUrl(options.managedSession.url)) {
|
|
683
|
-
reason = "managed-session-about-blank-while-launch-target-live";
|
|
684
98
|
}
|
|
685
|
-
|
|
686
|
-
|
|
99
|
+
if (options.subcommand === "start") {
|
|
100
|
+
options.traceOwners.set(sessionName, owner);
|
|
687
101
|
}
|
|
688
|
-
|
|
689
|
-
|
|
102
|
+
if (options.subcommand === "stop" && options.traceOwners.get(sessionName) === owner) {
|
|
103
|
+
options.traceOwners.delete(sessionName);
|
|
690
104
|
}
|
|
691
|
-
if (!reason)
|
|
692
|
-
return undefined;
|
|
693
|
-
const managedDescription = options.managedSession.url ?? options.managedSession.title ?? options.managedSession.sessionName;
|
|
694
|
-
const liveDescription = electronTargetLabel(liveTarget);
|
|
695
|
-
const summary = reason === "launch-session-not-current"
|
|
696
|
-
? `Electron session mismatch: current managed session ${options.managedSession.sessionName} is not the wrapper launch session ${options.record.sessionName ?? "unknown"}, while launch ${options.record.launchId} still has live target ${liveDescription}.`
|
|
697
|
-
: `Electron session mismatch: managed session ${options.managedSession.sessionName} is on ${managedDescription}, but launch ${options.record.launchId} still has live target ${liveDescription}.`;
|
|
698
|
-
const nextActions = buildElectronMismatchNextActions(options.record, liveTarget);
|
|
699
|
-
return {
|
|
700
|
-
launchId: options.record.launchId,
|
|
701
|
-
liveTarget,
|
|
702
|
-
managedSession: options.managedSession,
|
|
703
|
-
nextActionIds: nextActions.map((action) => action.id),
|
|
704
|
-
reason,
|
|
705
|
-
sessionName: options.record.sessionName,
|
|
706
|
-
statusTargets: options.statusTargets,
|
|
707
|
-
summary,
|
|
708
|
-
};
|
|
709
105
|
}
|
|
710
|
-
export function formatElectronSessionMismatchText(mismatch) {
|
|
711
|
-
return `${mismatch.summary}\nNext: run electron.status/electron.probe with launchId ${mismatch.launchId}, reattach with the reattach-electron-launch nextAction if needed, or cleanup when finished.`;
|
|
712
|
-
}
|
|
713
|
-
export function shouldInspectElectronPostCommandHealth(command) {
|
|
714
|
-
return isElectronPostCommandHealthCommand(command);
|
|
715
|
-
}
|
|
716
|
-
export function buildElectronLifecycleNextActions(record) {
|
|
717
|
-
return buildAgentBrowserNextActions({
|
|
718
|
-
electron: { launchId: record.launchId, sessionName: record.sessionName, status: record.cleanupState },
|
|
719
|
-
resultCategory: "success",
|
|
720
|
-
successCategory: "completed",
|
|
721
|
-
}) ?? [];
|
|
722
|
-
}
|
|
723
|
-
export function buildElectronPostCommandHealthDiagnostic(options) {
|
|
724
|
-
let reason;
|
|
725
|
-
if (options.status.pidAlive === false)
|
|
726
|
-
reason = "process-dead";
|
|
727
|
-
else if (!options.status.portAlive)
|
|
728
|
-
reason = "debug-port-dead";
|
|
729
|
-
else if (isAboutBlankUrl(options.target?.url) && getLiveElectronRendererTargets(options.status.targets).length === 0)
|
|
730
|
-
reason = "about-blank-no-live-target";
|
|
731
|
-
if (!reason)
|
|
732
|
-
return undefined;
|
|
733
|
-
const nextActions = buildElectronLifecycleNextActions(options.record);
|
|
734
|
-
const commandText = options.command ? `${options.command} command` : "command";
|
|
735
|
-
const statusText = `${options.status.portAlive ? "debug port alive" : "debug port dead"}${options.status.pidAlive === undefined ? "" : options.status.pidAlive ? ", pid alive" : ", pid dead"}`;
|
|
736
|
-
const summary = `Electron lifecycle warning: ${commandText} completed, but launch ${options.record.launchId} is no longer healthy (${statusText}).`;
|
|
737
|
-
return {
|
|
738
|
-
appName: options.record.appName,
|
|
739
|
-
command: options.command,
|
|
740
|
-
launchId: options.record.launchId,
|
|
741
|
-
nextActionIds: nextActions.map((action) => action.id),
|
|
742
|
-
reason,
|
|
743
|
-
sessionName: options.record.sessionName,
|
|
744
|
-
status: options.status,
|
|
745
|
-
summary,
|
|
746
|
-
target: options.target,
|
|
747
|
-
};
|
|
748
|
-
}
|
|
749
|
-
export function formatElectronPostCommandHealthText(diagnostic) {
|
|
750
|
-
if (!diagnostic)
|
|
751
|
-
return undefined;
|
|
752
|
-
const lines = [diagnostic.summary];
|
|
753
|
-
if (diagnostic.target?.url)
|
|
754
|
-
lines.push(`Current browser session target: ${diagnostic.target.url}.`);
|
|
755
|
-
lines.push(`Status: ${diagnostic.status.portAlive ? "debug port alive" : "debug port dead"}${diagnostic.status.pidAlive === undefined ? "" : diagnostic.status.pidAlive ? ", pid alive" : ", pid dead"}; ${diagnostic.status.targets.length} CDP target(s).`);
|
|
756
|
-
lines.push(`Next: run electron.status/electron.probe with launchId ${diagnostic.launchId}, cleanup the wrapper-owned launch if dead, or relaunch the app.`);
|
|
757
|
-
return lines.join("\n");
|
|
758
|
-
}
|
|
759
|
-
export function buildElectronIdentifiers(record) {
|
|
760
|
-
return { appName: record.appName, launchId: record.launchId, sessionName: record.sessionName };
|
|
761
|
-
}
|
|
762
|
-
export function buildElectronRefFreshnessNextActions(sessionName) {
|
|
763
|
-
return [{
|
|
764
|
-
id: "refresh-electron-refs-after-rerender",
|
|
765
|
-
params: { args: sessionName ? ["--session", sessionName, "snapshot", "-i"] : ["snapshot", "-i"] },
|
|
766
|
-
reason: "Electron UIs often rerender without changing URL; refresh refs before using old @e handles again.",
|
|
767
|
-
safety: "Read-only snapshot; avoids stale same-URL refs after quick-pick, modal, theme, or editor rerenders.",
|
|
768
|
-
tool: "agent_browser",
|
|
769
|
-
}];
|
|
770
|
-
}
|
|
771
|
-
export function buildElectronRefFreshnessDiagnostic(options) {
|
|
772
|
-
if (!options.record || !shouldInspectElectronPostCommandHealth(options.command))
|
|
773
|
-
return undefined;
|
|
774
|
-
if (getGuardedRefUsage(options.commandTokens, options.stdin).length === 0)
|
|
775
|
-
return undefined;
|
|
776
|
-
const nextActions = buildElectronRefFreshnessNextActions(options.sessionName);
|
|
777
|
-
return {
|
|
778
|
-
command: options.command,
|
|
779
|
-
launchId: options.record.launchId,
|
|
780
|
-
nextActionIds: nextActions.map((action) => action.id),
|
|
781
|
-
sessionName: options.sessionName,
|
|
782
|
-
summary: `Electron ref freshness: ${options.command ?? "mutation"} used page-scoped refs in an Electron UI. Re-run snapshot -i before reusing old @e refs, even if the URL did not change.`,
|
|
783
|
-
};
|
|
784
|
-
}
|
|
785
|
-
export function formatElectronRefFreshnessText(diagnostic) {
|
|
786
|
-
return diagnostic?.summary;
|
|
787
|
-
}
|
|
788
|
-
export { extractBatchResultCommand };
|
|
789
106
|
export function getPersistentSessionArtifactStore(ctx) {
|
|
790
|
-
const sessionDir = typeof ctx.sessionManager.getSessionDir === "function"
|
|
107
|
+
const sessionDir = typeof ctx.sessionManager.getSessionDir === "function"
|
|
108
|
+
? ctx.sessionManager.getSessionDir()
|
|
109
|
+
: undefined;
|
|
791
110
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
792
|
-
return sessionDir
|
|
111
|
+
return sessionDir !== undefined &&
|
|
112
|
+
sessionDir.length > 0 &&
|
|
113
|
+
sessionId !== undefined &&
|
|
114
|
+
sessionId.length > 0
|
|
115
|
+
? { sessionDir, sessionId }
|
|
116
|
+
: undefined;
|
|
793
117
|
}
|