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,427 +1,24 @@
|
|
|
1
|
-
import { randomBytes
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const TEMP_ROOT_MARKER_FILE_NAME = ".pi-agent-browser-owner.json";
|
|
10
|
-
const TEMP_ROOT_MARKER_KIND = "pi-agent-browser-temp-root";
|
|
11
|
-
const TEMP_ROOT_MARKER_VERSION = 2;
|
|
12
|
-
const STALE_TEMP_ROOT_MAX_AGE_MS = 24 * 60 * 60 * 1_000;
|
|
13
|
-
const STALE_TEMP_ROOT_BATCH_SIZE = 8;
|
|
14
|
-
let lastTempGcName;
|
|
15
|
-
const TEMP_ROOT_MAX_BYTES_ENV = "PI_AGENT_BROWSER_TEMP_ROOT_MAX_BYTES";
|
|
16
|
-
const DEFAULT_TEMP_ROOT_MAX_BYTES = 32 * 1_024 * 1_024;
|
|
17
|
-
const SESSION_ARTIFACT_MAX_BYTES_ENV = "PI_AGENT_BROWSER_SESSION_ARTIFACT_MAX_BYTES";
|
|
18
|
-
const DEFAULT_SESSION_ARTIFACT_MAX_BYTES = 32 * 1_024 * 1_024;
|
|
19
|
-
const SESSION_ARTIFACTS_ROOT_DIR_NAME = ".pi-agent-browser-artifacts";
|
|
20
|
-
let sessionTempRootPromise;
|
|
21
|
-
let exitCleanupRegistered = false;
|
|
22
|
-
let tempMutationQueue = Promise.resolve();
|
|
23
|
-
const ownedTempRoots = new Set();
|
|
24
|
-
const protectedTempChildren = new Set();
|
|
25
|
-
function getCurrentProcessUid() {
|
|
26
|
-
return typeof process.getuid === "function" ? process.getuid() : undefined;
|
|
27
|
-
}
|
|
28
|
-
function isPositiveFiniteNumber(value) {
|
|
29
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
30
|
-
}
|
|
31
|
-
function isProtectedTempChildName(value) {
|
|
32
|
-
if (typeof value !== "string")
|
|
33
|
-
return false;
|
|
34
|
-
if (value === "" || value === "." || value === ".." || value === TEMP_ROOT_MARKER_FILE_NAME)
|
|
35
|
-
return false;
|
|
36
|
-
if (value.includes("/") || value.includes("\\"))
|
|
37
|
-
return false;
|
|
38
|
-
return basename(value) === value;
|
|
39
|
-
}
|
|
40
|
-
function isTempRootOwnershipRecord(value) {
|
|
41
|
-
if (!isRecord(value))
|
|
42
|
-
return false;
|
|
43
|
-
if (value.kind !== TEMP_ROOT_MARKER_KIND || value.version !== TEMP_ROOT_MARKER_VERSION)
|
|
44
|
-
return false;
|
|
45
|
-
if (!isPositiveFiniteNumber(value.createdAtMs))
|
|
46
|
-
return false;
|
|
47
|
-
if (value.leaseUpdatedAtMs !== undefined && !isPositiveFiniteNumber(value.leaseUpdatedAtMs))
|
|
48
|
-
return false;
|
|
49
|
-
if (value.ownerPid !== undefined) {
|
|
50
|
-
if (typeof value.ownerPid !== "number" || !Number.isSafeInteger(value.ownerPid) || value.ownerPid <= 0)
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
if (value.ownerProcessStartIdentity !== undefined) {
|
|
54
|
-
if (typeof value.ownerProcessStartIdentity !== "string" || value.ownerProcessStartIdentity.trim() === "")
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
if (value.ownerUid !== undefined) {
|
|
58
|
-
if (typeof value.ownerUid !== "number" || !Number.isSafeInteger(value.ownerUid) || value.ownerUid < 0)
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
if (value.protectedChildNames !== undefined) {
|
|
62
|
-
if (!Array.isArray(value.protectedChildNames))
|
|
63
|
-
return false;
|
|
64
|
-
if (!value.protectedChildNames.every(isProtectedTempChildName))
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
function getTempArtifactByteLength(content) {
|
|
70
|
-
return typeof content === "string" ? Buffer.byteLength(content) : content.byteLength;
|
|
71
|
-
}
|
|
72
|
-
function enqueueTempMutation(task) {
|
|
73
|
-
const nextTask = tempMutationQueue.then(task, task);
|
|
74
|
-
tempMutationQueue = nextTask.then(() => undefined, () => undefined);
|
|
75
|
-
return nextTask;
|
|
76
|
-
}
|
|
77
|
-
async function listArtifactFiles(directory, excludedNames = new Set()) {
|
|
78
|
-
const entries = await readdir(directory, { withFileTypes: true }).catch(() => []);
|
|
79
|
-
const files = [];
|
|
80
|
-
for (const entry of entries) {
|
|
81
|
-
if (!entry.isFile() || excludedNames.has(entry.name))
|
|
82
|
-
continue;
|
|
83
|
-
const path = join(directory, entry.name);
|
|
84
|
-
const stats = await stat(path).catch(() => undefined);
|
|
85
|
-
if (stats?.isFile()) {
|
|
86
|
-
files.push({ mtimeMs: stats.mtimeMs, path, size: stats.size });
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return files;
|
|
90
|
-
}
|
|
91
|
-
async function getTempRootArtifactBytes(tempRoot) {
|
|
92
|
-
const files = await listArtifactFiles(tempRoot, new Set([TEMP_ROOT_MARKER_FILE_NAME]));
|
|
93
|
-
return files.reduce((totalBytes, file) => totalBytes + file.size, 0);
|
|
94
|
-
}
|
|
95
|
-
async function readTempRootOwnershipMarker(tempRoot) {
|
|
96
|
-
try {
|
|
97
|
-
const markerText = await readFile(join(tempRoot, TEMP_ROOT_MARKER_FILE_NAME), "utf8");
|
|
98
|
-
const parsed = JSON.parse(markerText);
|
|
99
|
-
return isTempRootOwnershipRecord(parsed) ? parsed : undefined;
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function getProtectedTempChildName(tempRoot, childPath) {
|
|
106
|
-
const normalizedTempRoot = resolve(tempRoot);
|
|
107
|
-
const normalizedChildPath = resolve(childPath);
|
|
108
|
-
if (dirname(normalizedChildPath) !== normalizedTempRoot)
|
|
109
|
-
return undefined;
|
|
110
|
-
const childName = basename(normalizedChildPath);
|
|
111
|
-
return isProtectedTempChildName(childName) ? childName : undefined;
|
|
112
|
-
}
|
|
113
|
-
function normalizeProtectedChildNames(names) {
|
|
114
|
-
return [...new Set([...names].filter(isProtectedTempChildName))].sort();
|
|
115
|
-
}
|
|
116
|
-
function getPersistedProtectedChildPaths(tempRoot, ownershipMarker) {
|
|
117
|
-
const normalizedTempRoot = resolve(tempRoot);
|
|
118
|
-
return new Set((ownershipMarker?.protectedChildNames ?? []).map((childName) => resolve(join(normalizedTempRoot, childName))));
|
|
119
|
-
}
|
|
120
|
-
async function writeTempRootOwnershipMarkerRecord(tempRoot, markerRecord, options = {}) {
|
|
121
|
-
const markerPath = join(tempRoot, TEMP_ROOT_MARKER_FILE_NAME);
|
|
122
|
-
await writeFile(markerPath, JSON.stringify(markerRecord, null, 2), {
|
|
123
|
-
encoding: "utf8",
|
|
124
|
-
flag: options.flag,
|
|
125
|
-
mode: 0o600,
|
|
126
|
-
});
|
|
127
|
-
await chmod(markerPath, 0o600).catch(() => undefined);
|
|
128
|
-
return markerPath;
|
|
129
|
-
}
|
|
130
|
-
async function persistProtectedTempChildren(tempRoot, protectedChildren) {
|
|
131
|
-
if (protectedChildren.size === 0)
|
|
132
|
-
return;
|
|
133
|
-
const ownershipMarker = await readTempRootOwnershipMarker(tempRoot);
|
|
134
|
-
if (!ownershipMarker)
|
|
135
|
-
return;
|
|
136
|
-
const childNames = normalizeProtectedChildNames([
|
|
137
|
-
...(ownershipMarker.protectedChildNames ?? []),
|
|
138
|
-
...[...protectedChildren]
|
|
139
|
-
.map((path) => getProtectedTempChildName(tempRoot, path))
|
|
140
|
-
.filter((childName) => childName !== undefined),
|
|
141
|
-
]);
|
|
142
|
-
if (childNames.length === 0)
|
|
143
|
-
return;
|
|
144
|
-
await writeTempRootOwnershipMarkerRecord(tempRoot, {
|
|
145
|
-
...ownershipMarker,
|
|
146
|
-
leaseUpdatedAtMs: Date.now(),
|
|
147
|
-
protectedChildNames: childNames,
|
|
148
|
-
version: TEMP_ROOT_MARKER_VERSION,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
async function getExistingProtectedChildren(tempRoot, protectedChildren) {
|
|
152
|
-
const normalizedTempRoot = resolve(tempRoot);
|
|
153
|
-
const existingChildren = new Set();
|
|
154
|
-
for (const path of protectedChildren) {
|
|
155
|
-
const normalizedPath = resolve(path);
|
|
156
|
-
if (dirname(normalizedPath) !== normalizedTempRoot)
|
|
157
|
-
continue;
|
|
158
|
-
if (await stat(normalizedPath).then((stats) => stats.isDirectory(), () => false)) {
|
|
159
|
-
existingChildren.add(normalizedPath);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return existingChildren;
|
|
163
|
-
}
|
|
164
|
-
async function removeTempRootChildrenExcept(tempRoot, protectedChildren) {
|
|
165
|
-
const entries = await readdir(tempRoot, { withFileTypes: true }).catch(() => []);
|
|
166
|
-
await Promise.all(entries.map(async (entry) => {
|
|
167
|
-
if (entry.name === TEMP_ROOT_MARKER_FILE_NAME)
|
|
168
|
-
return;
|
|
169
|
-
const entryPath = join(tempRoot, entry.name);
|
|
170
|
-
if (protectedChildren.has(resolve(entryPath)))
|
|
171
|
-
return;
|
|
172
|
-
await rm(entryPath, { force: true, recursive: true }).catch(() => undefined);
|
|
173
|
-
}));
|
|
174
|
-
}
|
|
175
|
-
async function getProcessStartIdentity(pid) {
|
|
176
|
-
return pid === undefined ? undefined : await readProcessStartIdentity(pid);
|
|
177
|
-
}
|
|
178
|
-
export async function writeSecureTempRootOwnershipMarker(tempRoot, options = {}) {
|
|
179
|
-
const createdAtMs = options.createdAtMs ?? Date.now();
|
|
180
|
-
const ownerPid = options.ownerPid ?? process.pid;
|
|
181
|
-
const markerRecord = {
|
|
182
|
-
createdAtMs,
|
|
183
|
-
kind: TEMP_ROOT_MARKER_KIND,
|
|
184
|
-
leaseUpdatedAtMs: options.leaseUpdatedAtMs ?? createdAtMs,
|
|
185
|
-
ownerPid,
|
|
186
|
-
ownerProcessStartIdentity: options.ownerProcessStartIdentity ?? (await getProcessStartIdentity(ownerPid)),
|
|
187
|
-
ownerUid: getCurrentProcessUid(),
|
|
188
|
-
version: TEMP_ROOT_MARKER_VERSION,
|
|
189
|
-
};
|
|
190
|
-
return await writeTempRootOwnershipMarkerRecord(tempRoot, markerRecord, { flag: "wx" });
|
|
191
|
-
}
|
|
192
|
-
async function refreshSecureTempRootLease(tempRoot) {
|
|
193
|
-
const ownershipMarker = await readTempRootOwnershipMarker(tempRoot);
|
|
194
|
-
if (!ownershipMarker)
|
|
195
|
-
return;
|
|
196
|
-
if (ownershipMarker.ownerPid !== process.pid)
|
|
197
|
-
return;
|
|
198
|
-
const currentUid = getCurrentProcessUid();
|
|
199
|
-
if (currentUid !== undefined && ownershipMarker.ownerUid !== undefined && ownershipMarker.ownerUid !== currentUid)
|
|
200
|
-
return;
|
|
201
|
-
const currentProcessStartIdentity = await getProcessStartIdentity(process.pid);
|
|
202
|
-
if (ownershipMarker.ownerProcessStartIdentity !== undefined && currentProcessStartIdentity !== undefined) {
|
|
203
|
-
const identitiesMatch = processStartIdentitiesMatch(ownershipMarker.ownerProcessStartIdentity, currentProcessStartIdentity);
|
|
204
|
-
if (identitiesMatch === false)
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
const refreshedMarker = {
|
|
208
|
-
...ownershipMarker,
|
|
209
|
-
leaseUpdatedAtMs: Date.now(),
|
|
210
|
-
ownerPid: process.pid,
|
|
211
|
-
ownerProcessStartIdentity: currentProcessStartIdentity ?? ownershipMarker.ownerProcessStartIdentity,
|
|
212
|
-
ownerUid: currentUid,
|
|
213
|
-
version: TEMP_ROOT_MARKER_VERSION,
|
|
214
|
-
};
|
|
215
|
-
await writeTempRootOwnershipMarkerRecord(tempRoot, refreshedMarker);
|
|
216
|
-
}
|
|
217
|
-
async function getMarkerOwnerLiveness(ownershipMarker) {
|
|
218
|
-
const pid = ownershipMarker.ownerPid;
|
|
219
|
-
if (pid === undefined)
|
|
220
|
-
return "unknown";
|
|
221
|
-
try {
|
|
222
|
-
process.kill(pid, 0);
|
|
223
|
-
}
|
|
224
|
-
catch (error) {
|
|
225
|
-
const errorWithCode = error;
|
|
226
|
-
if (errorWithCode.code === "ESRCH")
|
|
227
|
-
return "dead";
|
|
228
|
-
if (errorWithCode.code !== "EPERM")
|
|
229
|
-
return "unknown";
|
|
230
|
-
}
|
|
231
|
-
const currentProcessStartIdentity = await getProcessStartIdentity(pid);
|
|
232
|
-
if (ownershipMarker.ownerProcessStartIdentity === undefined || currentProcessStartIdentity === undefined) {
|
|
233
|
-
return "unknown";
|
|
234
|
-
}
|
|
235
|
-
const identitiesMatch = processStartIdentitiesMatch(ownershipMarker.ownerProcessStartIdentity, currentProcessStartIdentity);
|
|
236
|
-
return identitiesMatch === undefined ? "unknown" : identitiesMatch ? "alive" : "dead";
|
|
237
|
-
}
|
|
238
|
-
async function pruneStaleTempRoots(currentTempRoot) {
|
|
239
|
-
const entries = await readdir(tmpdir(), { withFileTypes: true }).catch(() => []);
|
|
240
|
-
const cutoffTime = Date.now() - STALE_TEMP_ROOT_MAX_AGE_MS;
|
|
241
|
-
const currentUid = getCurrentProcessUid();
|
|
242
|
-
// ponytail: list/sort all names; stream directories if enumeration becomes the bottleneck.
|
|
243
|
-
const candidates = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(TEMP_ROOT_PREFIX))
|
|
244
|
-
.map((entry) => entry.name).sort();
|
|
245
|
-
if (candidates.length === 0)
|
|
246
|
-
return;
|
|
247
|
-
const start = lastTempGcName === undefined ? randomInt(candidates.length)
|
|
248
|
-
: Math.max(0, candidates.findIndex((name) => name > lastTempGcName));
|
|
249
|
-
const batch = Array.from({ length: Math.min(STALE_TEMP_ROOT_BATCH_SIZE, candidates.length) }, (_, offset) => candidates[(start + offset) % candidates.length]);
|
|
250
|
-
lastTempGcName = batch.at(-1);
|
|
251
|
-
await Promise.all(batch.map(async (name) => {
|
|
252
|
-
const path = join(tmpdir(), name);
|
|
253
|
-
if (path === currentTempRoot)
|
|
254
|
-
return;
|
|
255
|
-
const ownershipMarker = await readTempRootOwnershipMarker(path);
|
|
256
|
-
if (!ownershipMarker)
|
|
257
|
-
return;
|
|
258
|
-
if (currentUid !== undefined &&
|
|
259
|
-
ownershipMarker.ownerUid !== undefined &&
|
|
260
|
-
ownershipMarker.ownerUid !== currentUid) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
const staleTimestampMs = ownershipMarker.leaseUpdatedAtMs ?? ownershipMarker.createdAtMs;
|
|
264
|
-
if (staleTimestampMs >= cutoffTime)
|
|
265
|
-
return;
|
|
266
|
-
// Preserve roots when owner liveness cannot be proven; safe cleanup beats deleting another live process's files.
|
|
267
|
-
if ((await getMarkerOwnerLiveness(ownershipMarker)) !== "dead")
|
|
268
|
-
return;
|
|
269
|
-
const stats = await stat(path).catch(() => undefined);
|
|
270
|
-
if (!stats?.isDirectory())
|
|
271
|
-
return;
|
|
272
|
-
const protectedChildren = await getExistingProtectedChildren(path, getPersistedProtectedChildPaths(path, ownershipMarker));
|
|
273
|
-
if (protectedChildren.size > 0) {
|
|
274
|
-
await removeTempRootChildrenExcept(path, protectedChildren);
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
await rm(path, { force: true, recursive: true }).catch(() => undefined);
|
|
278
|
-
}));
|
|
279
|
-
}
|
|
280
|
-
function getProtectedChildrenForRoot(tempRoot) {
|
|
281
|
-
const normalizedTempRoot = resolve(tempRoot);
|
|
282
|
-
return new Set([...protectedTempChildren].filter((path) => dirname(path) === normalizedTempRoot && existsSync(path)));
|
|
283
|
-
}
|
|
284
|
-
function removeTempRootChildrenExceptSync(tempRoot, protectedChildren) {
|
|
285
|
-
for (const entry of readdirSync(tempRoot, { withFileTypes: true })) {
|
|
286
|
-
if (entry.name === TEMP_ROOT_MARKER_FILE_NAME)
|
|
287
|
-
continue;
|
|
288
|
-
const entryPath = join(tempRoot, entry.name);
|
|
289
|
-
if (protectedChildren.has(resolve(entryPath)))
|
|
290
|
-
continue;
|
|
291
|
-
rmSync(entryPath, { force: true, recursive: true });
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
function registerExitCleanup() {
|
|
295
|
-
if (exitCleanupRegistered)
|
|
296
|
-
return;
|
|
297
|
-
exitCleanupRegistered = true;
|
|
298
|
-
process.once("exit", () => {
|
|
299
|
-
for (const tempRoot of ownedTempRoots) {
|
|
300
|
-
try {
|
|
301
|
-
const protectedChildren = getProtectedChildrenForRoot(tempRoot);
|
|
302
|
-
if (protectedChildren.size === 0) {
|
|
303
|
-
rmSync(tempRoot, { force: true, recursive: true });
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
removeTempRootChildrenExceptSync(tempRoot, protectedChildren);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
catch {
|
|
310
|
-
// Best-effort cleanup only.
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
export function getSecureTempRootMaxBytes(env = process.env) {
|
|
316
|
-
return parsePositiveInteger(env[TEMP_ROOT_MAX_BYTES_ENV]) ?? DEFAULT_TEMP_ROOT_MAX_BYTES;
|
|
317
|
-
}
|
|
318
|
-
export function getPersistentSessionArtifactMaxBytes(env = process.env) {
|
|
319
|
-
if (env[SESSION_ARTIFACT_MAX_BYTES_ENV]?.trim() === "0")
|
|
320
|
-
return 0;
|
|
321
|
-
return parsePositiveInteger(env[SESSION_ARTIFACT_MAX_BYTES_ENV]) ?? DEFAULT_SESSION_ARTIFACT_MAX_BYTES;
|
|
322
|
-
}
|
|
323
|
-
async function assertSecureTempRootBudget(tempRoot, additionalBytes) {
|
|
324
|
-
if (additionalBytes <= 0)
|
|
325
|
-
return;
|
|
326
|
-
const currentBytes = await getTempRootArtifactBytes(tempRoot);
|
|
327
|
-
const maxBytes = getSecureTempRootMaxBytes();
|
|
328
|
-
const nextBytes = currentBytes + additionalBytes;
|
|
329
|
-
if (nextBytes > maxBytes) {
|
|
330
|
-
throw new Error(`pi-agent-browser temp spill budget exceeded (${nextBytes} bytes > ${maxBytes} byte limit).`);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
export async function preserveSecureTempDirectory(path) {
|
|
334
|
-
await enqueueTempMutation(async () => {
|
|
335
|
-
const childPath = resolve(path);
|
|
336
|
-
const tempRoot = dirname(childPath);
|
|
337
|
-
if (!ownedTempRoots.has(tempRoot) || !getProtectedTempChildName(tempRoot, childPath) || !(await stat(childPath)).isDirectory()) {
|
|
338
|
-
throw new Error(`Cannot preserve ${path}; expected an existing child directory of a currently owned temp root.`);
|
|
339
|
-
}
|
|
340
|
-
protectedTempChildren.add(childPath);
|
|
341
|
-
await persistProtectedTempChildren(tempRoot, new Set([childPath]));
|
|
342
|
-
if (!getPersistedProtectedChildPaths(tempRoot, await readTempRootOwnershipMarker(tempRoot)).has(childPath)) {
|
|
343
|
-
throw new Error(`Could not persist temp directory preservation for ${path}.`);
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
export async function cleanupSecureTempArtifacts(options = {}) {
|
|
348
|
-
await enqueueTempMutation(async () => {
|
|
349
|
-
const tempRoot = await sessionTempRootPromise?.catch(() => undefined);
|
|
350
|
-
if (!tempRoot)
|
|
351
|
-
return;
|
|
352
|
-
const normalizedTempRoot = resolve(tempRoot);
|
|
353
|
-
for (const path of options.preservePaths ?? []) {
|
|
354
|
-
const childName = getProtectedTempChildName(normalizedTempRoot, path);
|
|
355
|
-
if (childName)
|
|
356
|
-
protectedTempChildren.add(resolve(join(normalizedTempRoot, childName)));
|
|
357
|
-
}
|
|
358
|
-
const preservedChildren = await getExistingProtectedChildren(normalizedTempRoot, protectedTempChildren);
|
|
359
|
-
for (const path of protectedTempChildren) {
|
|
360
|
-
if (dirname(path) === normalizedTempRoot && !preservedChildren.has(path))
|
|
361
|
-
protectedTempChildren.delete(path);
|
|
362
|
-
}
|
|
363
|
-
if (preservedChildren.size === 0) {
|
|
364
|
-
sessionTempRootPromise = undefined;
|
|
365
|
-
ownedTempRoots.delete(tempRoot);
|
|
366
|
-
await rm(tempRoot, { force: true, recursive: true }).catch(() => undefined);
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
await persistProtectedTempChildren(tempRoot, preservedChildren);
|
|
370
|
-
await removeTempRootChildrenExcept(tempRoot, preservedChildren);
|
|
371
|
-
await refreshSecureTempRootLease(tempRoot).catch(() => undefined);
|
|
372
|
-
});
|
|
373
|
-
}
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { chmod, mkdir, mkdtemp, open, rm } from "node:fs/promises";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { enqueueTempMutation } from "./temp-mutation-queue.js";
|
|
5
|
+
import { getSessionTempRoot, refreshSecureTempRootLease } from "./temp-root.js";
|
|
6
|
+
import { assertSecureTempRootBudget, getTempArtifactByteLength, prunePersistentSessionArtifactsToBudget, } from "./temp-artifact-budget.js";
|
|
7
|
+
export { cleanupSecureTempArtifacts, getSecureTempChildDirectoryValidationError, getSecureTempDebugState, preserveSecureTempDirectory, writeSecureTempRootOwnershipMarker, } from "./temp-root.js";
|
|
8
|
+
export { getPersistentSessionArtifactMaxBytes, getSecureTempRootMaxBytes, } from "./temp-artifact-budget.js";
|
|
374
9
|
async function ensurePersistentSessionArtifactDir(store) {
|
|
375
|
-
const rootDir = join(store.sessionDir,
|
|
10
|
+
const rootDir = join(store.sessionDir, ".pi-agent-browser-artifacts");
|
|
376
11
|
const sessionDir = join(rootDir, store.sessionId);
|
|
377
12
|
await mkdir(rootDir, { recursive: true, mode: 0o700 });
|
|
378
|
-
await chmod(rootDir, 0o700).catch(() =>
|
|
13
|
+
await chmod(rootDir, 0o700).catch(() => {
|
|
14
|
+
/* Native creation may already enforce the mode. */
|
|
15
|
+
});
|
|
379
16
|
await mkdir(sessionDir, { recursive: true, mode: 0o700 });
|
|
380
|
-
await chmod(sessionDir, 0o700).catch(() =>
|
|
17
|
+
await chmod(sessionDir, 0o700).catch(() => {
|
|
18
|
+
/* Native creation may already enforce the mode. */
|
|
19
|
+
});
|
|
381
20
|
return sessionDir;
|
|
382
21
|
}
|
|
383
|
-
async function prunePersistentSessionArtifactsToBudget(sessionArtifactDir, additionalBytes, protectedPaths) {
|
|
384
|
-
if (additionalBytes <= 0)
|
|
385
|
-
return [];
|
|
386
|
-
const maxBytes = getPersistentSessionArtifactMaxBytes();
|
|
387
|
-
if (maxBytes === 0)
|
|
388
|
-
return [];
|
|
389
|
-
let files = await listArtifactFiles(sessionArtifactDir);
|
|
390
|
-
let totalBytes = files.reduce((total, file) => total + file.size, 0);
|
|
391
|
-
if (totalBytes + additionalBytes <= maxBytes) {
|
|
392
|
-
return [];
|
|
393
|
-
}
|
|
394
|
-
const evictedArtifacts = [];
|
|
395
|
-
files = files.sort((left, right) => left.mtimeMs - right.mtimeMs || left.path.localeCompare(right.path));
|
|
396
|
-
for (const file of files) {
|
|
397
|
-
if (protectedPaths.has(file.path)) {
|
|
398
|
-
continue;
|
|
399
|
-
}
|
|
400
|
-
await rm(file.path, { force: true }).catch(() => undefined);
|
|
401
|
-
evictedArtifacts.push({ mtimeMs: file.mtimeMs, path: file.path, sizeBytes: file.size });
|
|
402
|
-
totalBytes -= file.size;
|
|
403
|
-
if (totalBytes + additionalBytes <= maxBytes) {
|
|
404
|
-
return evictedArtifacts;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
throw new Error(`pi-agent-browser persisted spill budget exceeded (${totalBytes + additionalBytes} bytes > ${maxBytes} byte limit).`);
|
|
408
|
-
}
|
|
409
|
-
async function getSessionTempRoot() {
|
|
410
|
-
if (!sessionTempRootPromise) {
|
|
411
|
-
sessionTempRootPromise = (async () => {
|
|
412
|
-
const tempRoot = await mkdtemp(join(tmpdir(), TEMP_ROOT_PREFIX));
|
|
413
|
-
await chmod(tempRoot, 0o700).catch(() => undefined);
|
|
414
|
-
await writeSecureTempRootOwnershipMarker(tempRoot);
|
|
415
|
-
ownedTempRoots.add(tempRoot);
|
|
416
|
-
registerExitCleanup();
|
|
417
|
-
return tempRoot;
|
|
418
|
-
})();
|
|
419
|
-
}
|
|
420
|
-
const tempRoot = await sessionTempRootPromise;
|
|
421
|
-
await refreshSecureTempRootLease(tempRoot).catch(() => undefined);
|
|
422
|
-
await pruneStaleTempRoots(tempRoot).catch(() => undefined);
|
|
423
|
-
return tempRoot;
|
|
424
|
-
}
|
|
425
22
|
export async function openSecureTempFile(prefix, suffix) {
|
|
426
23
|
const tempRoot = await getSessionTempRoot();
|
|
427
24
|
const path = join(tempRoot, `${prefix}-${randomBytes(8).toString("hex")}${suffix}`);
|
|
@@ -432,7 +29,9 @@ export async function writeSecureTempChunk(options) {
|
|
|
432
29
|
const { content, fileHandle, path } = options;
|
|
433
30
|
await enqueueTempMutation(async () => {
|
|
434
31
|
const tempRoot = dirname(path);
|
|
435
|
-
await refreshSecureTempRootLease(tempRoot).catch(() =>
|
|
32
|
+
await refreshSecureTempRootLease(tempRoot).catch(() => {
|
|
33
|
+
/* Lease renewal is best-effort; file ownership is already captured. */
|
|
34
|
+
});
|
|
436
35
|
await assertSecureTempRootBudget(tempRoot, getTempArtifactByteLength(content));
|
|
437
36
|
await fileHandle.appendFile(content);
|
|
438
37
|
});
|
|
@@ -444,7 +43,9 @@ export async function writeSecureTempFile(options) {
|
|
|
444
43
|
await writeSecureTempChunk({ content, fileHandle, path });
|
|
445
44
|
}
|
|
446
45
|
catch (error) {
|
|
447
|
-
await rm(path, { force: true }).catch(() =>
|
|
46
|
+
await rm(path, { force: true }).catch(() => {
|
|
47
|
+
/* Retain the original write failure if removal also fails. */
|
|
48
|
+
});
|
|
448
49
|
throw error;
|
|
449
50
|
}
|
|
450
51
|
finally {
|
|
@@ -456,26 +57,14 @@ export async function createSecureTempDirectory(prefix) {
|
|
|
456
57
|
const tempRoot = await getSessionTempRoot();
|
|
457
58
|
await assertSecureTempRootBudget(tempRoot, 0);
|
|
458
59
|
const directory = await mkdtemp(join(tempRoot, prefix));
|
|
459
|
-
await chmod(directory, 0o700).catch(() =>
|
|
460
|
-
|
|
60
|
+
await chmod(directory, 0o700).catch(() => {
|
|
61
|
+
/* mkdtemp supplies the private directory when chmod is unavailable. */
|
|
62
|
+
});
|
|
63
|
+
await refreshSecureTempRootLease(tempRoot).catch(() => {
|
|
64
|
+
/* Renewal is best-effort after private creation. */
|
|
65
|
+
});
|
|
461
66
|
return directory;
|
|
462
67
|
}
|
|
463
|
-
export async function getSecureTempChildDirectoryValidationError(path, childPrefix) {
|
|
464
|
-
const parentDirectory = dirname(path);
|
|
465
|
-
const childName = path.slice(parentDirectory.length + 1);
|
|
466
|
-
if (!childName.startsWith(childPrefix)) {
|
|
467
|
-
return `Refusing to remove ${path}; expected wrapper temp child prefix ${childPrefix}.`;
|
|
468
|
-
}
|
|
469
|
-
const ownershipMarker = await readTempRootOwnershipMarker(parentDirectory);
|
|
470
|
-
if (!ownershipMarker) {
|
|
471
|
-
return `Refusing to remove ${path}; parent directory is not a pi-agent-browser owned temp root.`;
|
|
472
|
-
}
|
|
473
|
-
const currentUid = getCurrentProcessUid();
|
|
474
|
-
if (currentUid !== undefined && ownershipMarker.ownerUid !== undefined && ownershipMarker.ownerUid !== currentUid) {
|
|
475
|
-
return `Refusing to remove ${path}; parent temp root is owned by uid ${ownershipMarker.ownerUid}, not current uid ${currentUid}.`;
|
|
476
|
-
}
|
|
477
|
-
return undefined;
|
|
478
|
-
}
|
|
479
68
|
export async function writePersistentSessionArtifactFile(options) {
|
|
480
69
|
const { content, prefix, store, suffix } = options;
|
|
481
70
|
return await enqueueTempMutation(async () => {
|
|
@@ -487,18 +76,16 @@ export async function writePersistentSessionArtifactFile(options) {
|
|
|
487
76
|
await fileHandle.writeFile(content);
|
|
488
77
|
}
|
|
489
78
|
catch (error) {
|
|
490
|
-
await rm(path, { force: true }).catch(() =>
|
|
79
|
+
await rm(path, { force: true }).catch(() => {
|
|
80
|
+
/* Preserve write failure identity. */
|
|
81
|
+
});
|
|
491
82
|
throw error;
|
|
492
83
|
}
|
|
493
84
|
finally {
|
|
494
|
-
await fileHandle.close().catch(() =>
|
|
85
|
+
await fileHandle.close().catch(() => {
|
|
86
|
+
/* A completed artifact write retains its receipt even if close fails. */
|
|
87
|
+
});
|
|
495
88
|
}
|
|
496
89
|
return { evictedArtifacts, path };
|
|
497
90
|
});
|
|
498
91
|
}
|
|
499
|
-
export async function getSecureTempDebugState() {
|
|
500
|
-
return {
|
|
501
|
-
currentTempRoot: await sessionTempRootPromise?.catch(() => undefined),
|
|
502
|
-
ownedTempRoots: [...ownedTempRoots].sort(),
|
|
503
|
-
};
|
|
504
|
-
}
|