superbrowser-sdk 2.5.0__tar.gz → 2.7.0__tar.gz
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.
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/CHANGELOG.md +67 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/PKG-INFO +1 -1
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/api-reference.md +30 -0
- superbrowser_sdk-2.7.0/docs/design/inspect_redaction.md +277 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/mcp.md +16 -10
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/pyproject.toml +1 -1
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/verify_release_artifact.py +144 -64
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/__init__.py +1 -1
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/facade.py +54 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/mcp_server.py +258 -9
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_diagnostics.py +4 -4
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_navigation.py +259 -13
- superbrowser_sdk-2.7.0/tests/test_mcp_redaction.py +544 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_server.py +4 -4
- superbrowser_sdk-2.7.0/tests/test_release/test_verify_artifact.py +246 -0
- superbrowser_sdk-2.5.0/tests/test_release/test_verify_artifact.py +0 -133
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.env.example +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/adversarial-v3.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/adversarial.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/benchmark.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/dco.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/e2e.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/publish.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/smoke.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/stress.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.github/workflows/test.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.gitignore +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/.pre-commit-config.yaml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/CONTRIBUTING.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/Dockerfile +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/LICENSE +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/README.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/Super-Browser.png +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/benchmarks/fixtures/behavioral.html +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/benchmarks/fixtures/dom-heavy.html +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/benchmarks/fixtures/form.html +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/benchmarks/fixtures/simple.html +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/benchmarks/v1.11.0-baseline-patchright.json +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/benchmarks/v1.11.0-baseline-patchright.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docker-compose.yml +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/agent-reliability.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/aiv/AIV_FRAMEWORK_v5.3.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/anti-detection-ejecta.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/api-ergonomics-audit.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/api-stability.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/architecture.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/behavioral-synthesis.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/browser-networking.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/cloak-integration.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/consistency-engine.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/discovery/DISCOVERY-REPORT.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/error-catalog.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/fingerprint-scoring.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/fingerprint-validation.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/gap-analysis.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/human-behavior.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/memory.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/migration/v1-to-v2.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/migration/v1.8-to-v1.9.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/operating-doctrine.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/platform-abstraction.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/plugins.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/quickstart.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/recording.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/rfcs/README.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/rfcs/v2-decomposition.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/rfcs/v2-track-a-api-simplification.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/rfcs/v2-track-b-network-stealth.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/rfcs/v2-track-c-behavioral-realism.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/rfcs/v2-track-d-challenge-infrastructure.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/rfcs/v2-track-e-e2e-harness.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/stealth-coverage.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/docs/stealth-evidence.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/backend_selection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/basic_usage.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/budget_tracking.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/cloak_stealth.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/error_handling.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/fingerprint_scan.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/human_behavior.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/multi_tab_workflow.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/session_persistence.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/examples/stealth_mode.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/adversarial_run.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/agent_efficiency_benchmark.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/browser_benchmark.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/e2e_trend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/run_stealth_gauntlet.sh +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/smoke_published.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/stress_real_world.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/scripts/validate_e2e_report.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/__main__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/debug.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/delegator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/diagnostics.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/llm/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/llm/anthropic_client.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/llm/browser_transport.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/llm/budget_aware.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/llm/factory.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/llm/openai_client.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/llm/protocol.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/loop.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/loop_detector.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/plugins.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/registry.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/router.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/structured_logging.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/agent/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/bezier.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/dwell.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/fitts.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/gauss.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/keyboard.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/mouse.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/navigation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/orchestrator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/prng.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/qwerty.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/scroll.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/session_seed.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/behavioral/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/backends/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/backends/cdp_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/backends/patchright_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/backends/playwright_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/backends/selenium_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/cdp.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/cloak_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/cloud.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/discovery.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/engine.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/fetch.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/injectors/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/injectors/bidi_injector.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/injectors/cdp_injector.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/injectors/page_injector.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/page.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/session.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/shutdown.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/browser/tabs.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/cascade.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/client.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/compressor.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/cost_estimator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/credential_pool.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/governor.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/budget/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/cli/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/cli/commands.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/cli/interactive.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/cli/script.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/events/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/events/bus.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/events/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/cache.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/controller.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/decorator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/presets.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/recovery.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/snapshot.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/interaction/vision.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/memory/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/memory/integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/memory/store.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/memory/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/plugins/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/plugins/decorators.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/plugins/hooks.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/py.typed +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recording/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recording/persistence.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recording/recorder.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recording/replayer.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recording/report.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recording/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/checkpoint.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/classifier.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/coordinator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/event_bus.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/format_validator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/reflection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/retry_tracker.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/session_recovery.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/recovery/watchdogs.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/results/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/results/output.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/results/typed.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/results/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/results/validation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/action_redaction.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/approval.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/credential_vault.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/domain_filter.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/gate.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/injection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/manager.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/policy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/redactor.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/security/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/session/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/session/proxy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/skills/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/skills/activation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/skills/markdown.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/skills/registry.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/skills/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/action_policy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/captcha.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/challenges/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/challenges/cache.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/challenges/pow.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/challenges/turnstile.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/dag.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/derive.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/errors.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/inject.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/inject_delivery.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/matrix.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/prng.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rule.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/audio.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/behavior.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/fonts.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/gpu.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/locale.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/navigator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/screen.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/consistency/rules/user_agent.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/diagnostics.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/audio.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/browser_apis.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/canvas.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/registry.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/timing.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ejecta/webrtc.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/fingerprint_scanner.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/fingerprint_score.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/headers.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/human.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/human_config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/ip_reputation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/manager.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/profiles/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/profiles/data/linux-chrome-stable.json +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/profiles/data/macos-chrome-stable.json +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/profiles/data/macos-m4-chrome-stable.json +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/profiles/data/windows-chrome-stable.json +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/profiles/host_detect.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/profiles/schema.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/proxy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/proxy_pool.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/report.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/scoring.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/tls_baselines.json +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/user_agent_pool.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/validation/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/validation/checks.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/validation/harness.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/validation/report.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/stealth/validation/suite.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/testing.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/tracing/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/tracing/cost_analytics.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/tracing/flow_logger.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/tracing/middleware.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/tracing/session_db.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/tracing/sinks.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/tracing/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/verification/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/verification/ax_diff.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/verification/hasher.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/verification/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/verification/verifier.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/cache.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/controller.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/coords.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/factory.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/ocr.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/providers.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/src/super_browser/vision/types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/stress/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/stress/server.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/controlled_server.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/report.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/scoring.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/targets.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/test_controlled_server.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/test_targets_unit.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/test_tier1_scanners.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/test_tier2_vendors.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial/test_tier3_controlled.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/README.md +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/backends.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/behavioral_telemetry.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/core.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/engines/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/engines/scoring.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/harness.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/reporters/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/reporters/history.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/reporters/json_reporter.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/reporters/markdown_reporter.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/server.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/automation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/behavioral.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/controlled.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/ejector.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/external.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/fingerprint.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/adversarial3/vectors/network.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/pytest.ini +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/run.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_backends.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_behavioral_telemetry.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_behavioral_telemetry_smoke.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_behavioral_vectors.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_core.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_external.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_harness_smoke.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_header_ordering.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_reporters.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_scoring.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_server.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_superbrowser_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/adversarial_v3/tests/test_vectors.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_01_example_nav.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_02_google_search.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_03_github_login.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_04_amazon_search.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_05_google_forms.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_06_google_flights.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_07_wikipedia_extract.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_08_reddit_spa.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_09_form_complex.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/discovery/test_task_10_signup_flow.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_behavioral_realism.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_challenge_detection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_interaction.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_live_navigation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_multi_tab.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_navigation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_session_persistence.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e/test_stealth_overhead.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/e2e_v1_3_journey.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_config_composition.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_engine_backends.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_error_paths.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_facade_smoke.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_full_lifecycle.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_multi_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_performance_smoke.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_playwright_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_public_api.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_session_persistence.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_stealth_abstraction.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v1100_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v150_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v160_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v170_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v180_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v190_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v191_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v192_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v193_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v194_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v195_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v1_3_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/integration/test_v1_4_features.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/pattern_validation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/conftest.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/test_chrome_runtime.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/test_cli_switches.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/test_headless_indicators.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/test_live_sites.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/test_runtime_enable.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/test_tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/stealth_detection/test_webdriver.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_action_timeout.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_browser_transport.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_controller_rebinding.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_debug_mode.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_default_tooling.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_delegator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_error_screenshots.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_facade.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_facade_security.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_facade_security_control.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_facade_security_file_tab.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_facade_security_network.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_facade_security_session.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_fail_fast.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_llm.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_llm_budget.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_llm_production.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_llm_streaming.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_loop.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_loop_detector.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_prompt_isolation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_registry.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_retry_budget.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_streaming.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_structured_logging.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_tab_cap.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_task_02.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_agent/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/test_behavioral.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/test_dwell.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/test_hardening.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/test_human_config_dwell.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/test_navigation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/test_orchestrator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_behavioral/test_session_seed.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_benchmark/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_benchmark/test_efficiency.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_benchmarks/test_browser_benchmark.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_benchmarks/test_stress_real_world.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_cdp.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_cdp_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_cloak_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_cloak_docs.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_cloak_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_discovery.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_engine_protocol.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_fetch.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_injectors.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_page.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_patchright_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_playwright_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_selenium_backend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_session.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_browser/test_shutdown.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_cascade.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_cascade_governor.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_circuit_breaker.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_client.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_compressor.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_cost_estimator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_credential_pool.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_governor.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_budget/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_cli/test_interactive.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_cli/test_script.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_cli/test_stealth_check.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_cli/test_stealth_validate.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_cli/test_unified_cli.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_diagnostics.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_e2e/test_report_schema.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_e2e/test_trend.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_audio.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_batch37_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_batch38_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_browser_apis.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_canvas.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_timing.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_ejecta/test_webrtc.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_events/test_event_bus.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_events/test_lifecycle_hooks.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_governance_docs.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_cache.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_controller.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_decorator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_injection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_page_change.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_presets.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_recovery.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_snapshot.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_interaction/test_vision.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_entrypoint.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_permissions.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_server_smoke.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_write_tools.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_mcp_write_tools_wave2.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_memory/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_memory/test_cli_config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_memory/test_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_memory/test_store.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recording/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recording/test_persistence.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recording/test_recorder.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recording/test_replayer.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_checkpoint.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_classifier.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_coordinator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_event_bus.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_format_validator.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_reflection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_retry_tracker.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_session_recovery.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_recovery/test_watchdogs.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_release/test_naming_consistency.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_release/test_smoke_published.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_results/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_results/test_batch40_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_results/test_categories.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_results/test_output.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_results/test_typed.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_results/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_results/test_validation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_runtime_correctness/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_runtime_correctness/test_runtime_fixes.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_approval.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_credential_vault.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_domain_filter.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_injection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_manager.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_policy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_redaction_pipeline.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_redactor.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_security/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_session/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_session/test_locale.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_session/test_proxy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_skills/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_skills/test_activation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_skills/test_integration.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_skills/test_markdown.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_skills/test_registry.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_skills/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_action_policy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_captcha.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_captcha_resolution.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_challenge_cache.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_challenge_config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_consistency/test_consistency.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_consistency_inject.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_diagnostics.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_e2e_lifecycle.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_e2e_reporting.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_fingerprint_scanner.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_fingerprint_score.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_headers.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_human.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_human_behavior_v2.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_ip_reputation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_kasada_detection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_manager.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_network_stealth_config.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_profiles.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_proxy.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_proxy_pool.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_stealth_bridge.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_turnstile_detection.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_user_agent_pool.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_stealth/test_validation.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_tracing/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_tracing/test_cost_analytics.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_tracing/test_flow_logger.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_tracing/test_middleware.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_tracing/test_session_db.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_tracing/test_sinks.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_tracing/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_verification/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_verification/test_ax_diff.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_verification/test_hasher.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_verification/test_types.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_verification/test_verifier.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/__init__.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/test_cache.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/test_controller.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/test_coords.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/test_factory.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/test_ocr.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/test_providers.py +0 -0
- {superbrowser_sdk-2.5.0 → superbrowser_sdk-2.7.0}/tests/test_vision/test_types.py +0 -0
|
@@ -5,6 +5,73 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.7.0] — 2026-06-26
|
|
9
|
+
|
|
10
|
+
### Added — MCP reload and history navigation tools (P3.0B)
|
|
11
|
+
|
|
12
|
+
- `reload`, `go_back`, `go_forward` are now navigation-tier MCP tools
|
|
13
|
+
(default-allowed, not action-budgeted). Each delegates to a new thin facade
|
|
14
|
+
method that calls the underlying Playwright page method.
|
|
15
|
+
- `go_back` and `go_forward` return a structured error when there is no
|
|
16
|
+
history entry to navigate to.
|
|
17
|
+
- Default advertised tools: 14 → 17; action mode: 20 → 23.
|
|
18
|
+
- Diagnostics remain session-wide after navigation.
|
|
19
|
+
|
|
20
|
+
## [2.6.0] — 2026-06-26
|
|
21
|
+
|
|
22
|
+
### Added — MCP switch_tab navigation tool (P3.0A)
|
|
23
|
+
|
|
24
|
+
- `switch_tab` is now a navigation-tier MCP tool (default-allowed, not
|
|
25
|
+
action-budgeted). Delegates to the existing `SuperBrowser.switch_tab(tab_id)`
|
|
26
|
+
facade method. Use `list_tabs` to discover tab IDs.
|
|
27
|
+
- Default advertised tools: 13 → 14; action mode: 19 → 20.
|
|
28
|
+
- Diagnostics remain session-wide after switching tabs; per-tab diagnostics
|
|
29
|
+
are not supported yet.
|
|
30
|
+
|
|
31
|
+
### Added — MCP inspect-output redaction (P2.3)
|
|
32
|
+
|
|
33
|
+
Inspect-tier MCP tools now redact detected secrets at the MCP serialization
|
|
34
|
+
boundary before returning content to the agent. Redaction is **on by default**
|
|
35
|
+
(matching `SecurityConfig.redaction_enabled=True`) and can be disabled via
|
|
36
|
+
`SB_MCP_REDACTION=0` (env) or `SecurityConfig(redaction_enabled=False)`
|
|
37
|
+
(programmatic).
|
|
38
|
+
|
|
39
|
+
**Tools redacted (9):** `extract_text`, `observe`, `current_url`, `list_tabs`,
|
|
40
|
+
`get_console_messages`, `get_page_errors`, `get_network_errors`, `list_requests`,
|
|
41
|
+
`get_request`.
|
|
42
|
+
|
|
43
|
+
**What gets redacted:**
|
|
44
|
+
- Text fields (text, message, stack, title, failure_text) — secret patterns
|
|
45
|
+
detected by `SecretRedactor` (API keys, JWTs, passwords, PEM keys, etc.) are
|
|
46
|
+
replaced with `[REDACTED:{type}:{hash6}]` markers.
|
|
47
|
+
- URL fields — two-pass: `redact_context()` redacts sensitive query-parameter
|
|
48
|
+
values (`[REDACTED:query_param]`), then `SecretRedactor` pattern-scans for
|
|
49
|
+
secrets in non-sensitive keys/fragments.
|
|
50
|
+
|
|
51
|
+
**What does NOT change:**
|
|
52
|
+
- Output shape (same keys/structure; only string values may contain markers).
|
|
53
|
+
- Python SDK consumers (`sb.extract()`, `sb.observe()`, `sb.diagnostics`) —
|
|
54
|
+
redaction applies only at the MCP boundary, not the SDK path.
|
|
55
|
+
- `screenshot` (visual content), `browser_status` (no sensitive content).
|
|
56
|
+
- DiagnosticsBuffer capture behavior, facade outputs.
|
|
57
|
+
|
|
58
|
+
### Compatibility notes
|
|
59
|
+
|
|
60
|
+
- This is a **behavior change** for MCP consumers: inspect-tier output that
|
|
61
|
+
previously contained raw secrets will now contain redaction markers. Set
|
|
62
|
+
`SB_MCP_REDACTION=0` to restore raw output.
|
|
63
|
+
|
|
64
|
+
### Fixed — Release tooling
|
|
65
|
+
|
|
66
|
+
- `scripts/verify_release_artifact.py` now supports sdist (`.tar.gz`) artifacts
|
|
67
|
+
via `tarfile`, in addition to wheels (`.whl`) via `zipfile`. Previously the
|
|
68
|
+
verifier was wheel-only and threw `BadZipFile` on any sdist (hit during both
|
|
69
|
+
the v2.4.0 and v2.5.0 releases). Shared checks (distribution name, version,
|
|
70
|
+
extras, isolated install, import, CLI, README/docs scan) run for both archive
|
|
71
|
+
types; wheel-only checks (entry points, module shadowing guard) are skipped
|
|
72
|
+
for sdists with a clear "skipped" message. Unsupported archive types now fail
|
|
73
|
+
with a clear error instead of an opaque `BadZipFile`.
|
|
74
|
+
|
|
8
75
|
## [2.5.0] — 2026-06-25
|
|
9
76
|
|
|
10
77
|
### Added — MCP Server P2: Diagnostics Pack
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superbrowser-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: Anti-detection agent browser SDK — stealth, budget governance, security guardrails, and structured error recovery behind one async facade
|
|
5
5
|
Project-URL: Homepage, https://github.com/Octo-Lex/Super-Browser
|
|
6
6
|
Project-URL: Documentation, https://github.com/Octo-Lex/Super-Browser#readme
|
|
@@ -101,6 +101,36 @@ if result.ok:
|
|
|
101
101
|
print(result.data.final_url) # "https://example.com/"
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
+
#### `reload(*, wait_until="domcontentloaded") → ActionResult`
|
|
105
|
+
|
|
106
|
+
Reload the current page.
|
|
107
|
+
|
|
108
|
+
| Parameter | Type | Default | Description |
|
|
109
|
+
|---|---|---|---|
|
|
110
|
+
| `wait_until` | `str` | `"domcontentloaded"` | Playwright load event to wait for. |
|
|
111
|
+
|
|
112
|
+
**Returns:** `ActionResult` with `data.url` (the page URL after reload).
|
|
113
|
+
|
|
114
|
+
#### `go_back(*, wait_until="domcontentloaded") → ActionResult`
|
|
115
|
+
|
|
116
|
+
Go back one step in browser history.
|
|
117
|
+
|
|
118
|
+
| Parameter | Type | Default | Description |
|
|
119
|
+
|---|---|---|---|
|
|
120
|
+
| `wait_until` | `str` | `"domcontentloaded"` | Playwright load event to wait for. |
|
|
121
|
+
|
|
122
|
+
**Returns:** `ActionResult` with `data.url`, or `ok=False` if there is no previous history entry.
|
|
123
|
+
|
|
124
|
+
#### `go_forward(*, wait_until="domcontentloaded") → ActionResult`
|
|
125
|
+
|
|
126
|
+
Go forward one step in browser history.
|
|
127
|
+
|
|
128
|
+
| Parameter | Type | Default | Description |
|
|
129
|
+
|---|---|---|---|
|
|
130
|
+
| `wait_until` | `str` | `"domcontentloaded"` | Playwright load event to wait for. |
|
|
131
|
+
|
|
132
|
+
**Returns:** `ActionResult` with `data.url`, or `ok=False` if there is no next history entry.
|
|
133
|
+
|
|
104
134
|
### Interaction
|
|
105
135
|
|
|
106
136
|
#### `click(target, *, description=None) → ActionResult`
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# Design Note: Shared Inspect-Output Redaction
|
|
2
|
+
|
|
3
|
+
> **Status:** Design proposal for review. No implementation yet.
|
|
4
|
+
> **Scope:** P2.3 — define the redaction boundary before more default-readable MCP surfaces are added.
|
|
5
|
+
> **Date:** 2026-06-25
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
The inspect-tier MCP tools return raw page/browser content to the agent with no
|
|
10
|
+
redaction:
|
|
11
|
+
|
|
12
|
+
- `extract_text` — returns page text as-is
|
|
13
|
+
- `observe` — returns URL, title, element counts (text in serialized form)
|
|
14
|
+
- `get_console_messages` — returns console output as-is
|
|
15
|
+
- `get_page_errors` — returns error messages + stack traces as-is
|
|
16
|
+
- `list_requests` / `get_request` — returns header **names** only (by P2 design),
|
|
17
|
+
but URLs, failure text, and console/error content are unredacted
|
|
18
|
+
- `get_network_errors` — returns failed request URLs + failure text as-is
|
|
19
|
+
|
|
20
|
+
This is consistent today (all inspect tools have the same "no redaction"
|
|
21
|
+
posture), and it was the deliberate P2 decision: ship diagnostics unredacted for
|
|
22
|
+
parity with `extract_text`, then unify redaction across all inspect tools as a
|
|
23
|
+
follow-up. **This document is that follow-up.**
|
|
24
|
+
|
|
25
|
+
The risk: console messages, page errors, and URLs routinely contain secrets
|
|
26
|
+
(API keys in console logs, tokens in redirect URLs, credentials in error
|
|
27
|
+
messages). An agent that reads these via MCP and passes them to an LLM leaks
|
|
28
|
+
secrets into the model context.
|
|
29
|
+
|
|
30
|
+
## Existing machinery (reuse, don't rebuild)
|
|
31
|
+
|
|
32
|
+
The codebase already has a complete redaction layer:
|
|
33
|
+
|
|
34
|
+
| Component | Location | What it does |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `SecretRedactor` | `security/redactor.py:61` | Pattern-based redaction of secrets in text (API keys, tokens, passwords, JWTs, etc.) |
|
|
37
|
+
| `redact_args()` | `security/action_redaction.py:55` | Key-name + value-pattern redaction on dicts |
|
|
38
|
+
| `redact_result_dict()` | `security/action_redaction.py:108` | Redacts `ActionResult.to_dict()` output (`data` + `error` fields) |
|
|
39
|
+
| `redact_context()` | `security/action_redaction.py:81` | Scrubs sensitive query params from URLs |
|
|
40
|
+
| `_SENSITIVE_KEYS` | `security/action_redaction.py:12` | Frozenset of sensitive key names (password, token, secret, cookie, auth, etc.) |
|
|
41
|
+
| `configure_redaction()` | `security/action_redaction.py:45` | Sets the default redactor from a `SecurityConfig` |
|
|
42
|
+
| `SecurityManager.check_action()` | `security/manager.py:111` | Runs redaction on action params when `redaction_enabled=True` (default) |
|
|
43
|
+
|
|
44
|
+
**Critical gap:** `redact_result_dict()` is wired into `ActionResult.to_dict()`
|
|
45
|
+
(`results/types.py:235`) — the **Python SDK serialization path**. But the MCP
|
|
46
|
+
server's `_serialize_action_result()` (`mcp_server.py:432`) manually builds a
|
|
47
|
+
payload from `ok`/`data`/`error`/`meta` and does **not** call
|
|
48
|
+
`ActionResult.to_dict()` or `redact_result_dict()`. So the same `ActionResult`
|
|
49
|
+
is redacted when serialized via the Python SDK but **not** when returned via
|
|
50
|
+
MCP. Additionally, the diagnostics handlers (`_tool_get_console_messages`, etc.)
|
|
51
|
+
and `_tool_current_url` build response dicts directly, bypassing
|
|
52
|
+
`ActionResult` and `_serialize_action_result()` entirely.
|
|
53
|
+
|
|
54
|
+
## Design principles
|
|
55
|
+
|
|
56
|
+
1. **Do not destroy utility by default.** Redaction should mask known secret
|
|
57
|
+
patterns, not collapse all text. A redacted console message should still
|
|
58
|
+
show the message structure with secrets replaced by the existing markers
|
|
59
|
+
(`[REDACTED:{secret_type}:{hash6}]` or `[REDACTED:query_param]`).
|
|
60
|
+
|
|
61
|
+
2. **Policy-driven, not always-on.** Redaction should be controlled by the
|
|
62
|
+
`SecurityConfig` (which is already `redaction_enabled=True` by default). The
|
|
63
|
+
MCP server constructs a `SecurityManager` in `run_server()`; the same config
|
|
64
|
+
should govern inspect-output redaction. An operator who wants raw output
|
|
65
|
+
(e.g. for debugging) can set `redaction_enabled=False`.
|
|
66
|
+
|
|
67
|
+
3. **Redact at the MCP serialization boundary, not inside the browser.** The
|
|
68
|
+
browser captures raw content; redaction happens when the MCP server
|
|
69
|
+
serializes the response for the agent. This keeps the SDK fast path
|
|
70
|
+
unredacted (Python SDK consumers get raw data) while the agent-facing MCP
|
|
71
|
+
boundary applies the policy.
|
|
72
|
+
|
|
73
|
+
4. **Masking format is documented and stable.** The existing redaction
|
|
74
|
+
machinery emits two marker formats, both preserved as-is:
|
|
75
|
+
- `SecretRedactor`: `[REDACTED:{secret_type}:{hash6}]` — e.g.
|
|
76
|
+
`[REDACTED:openai_key:abc123]` (includes the secret type and a 6-char
|
|
77
|
+
SHA-256 prefix for deduplication).
|
|
78
|
+
- `redact_context()`: `[REDACTED:query_param]` — for sensitive query
|
|
79
|
+
parameter values.
|
|
80
|
+
Agents can detect that redaction occurred without seeing the secret.
|
|
81
|
+
|
|
82
|
+
5. **No output-shape change.** Redaction replaces string values in place; it
|
|
83
|
+
does not add, remove, or rename keys. A redacted `get_console_messages`
|
|
84
|
+
response has the same `{ok, messages, count}` shape — only `messages[i].text`
|
|
85
|
+
values may be masked.
|
|
86
|
+
|
|
87
|
+
## Scope: which tools, what content
|
|
88
|
+
|
|
89
|
+
### In scope (redaction applied)
|
|
90
|
+
|
|
91
|
+
| Tool | Content to redact | Mechanism |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `extract_text` | extracted text body | `SecretRedactor.redact()` on the text string |
|
|
94
|
+
| `observe` | title, URL | URL redaction (see below); `SecretRedactor.redact()` on title |
|
|
95
|
+
| `current_url` | page URL | URL redaction (see below) |
|
|
96
|
+
| `list_tabs` | tab URLs, tab titles | URL redaction on each tab URL; `SecretRedactor.redact()` on titles |
|
|
97
|
+
| `get_console_messages` | `text` field per entry | `SecretRedactor.redact()` on each `text` |
|
|
98
|
+
| `get_page_errors` | `message`, `stack` fields | `SecretRedactor.redact()` on each |
|
|
99
|
+
| `get_network_errors` | `url`, `failure_text` | URL redaction on URL; `SecretRedactor.redact()` on failure_text |
|
|
100
|
+
| `list_requests` | `url` per entry | URL redaction on each URL |
|
|
101
|
+
| `get_request` | `url`, `failure_text` | URL redaction on URL; `SecretRedactor.redact()` on failure_text |
|
|
102
|
+
|
|
103
|
+
**URL redaction** (two-pass, applied to all URL fields):
|
|
104
|
+
1. `redact_context(url)` — redacts query parameters whose key names match
|
|
105
|
+
`_SENSITIVE_KEYS` (token, access_token, api_key, cookie, etc.).
|
|
106
|
+
2. `SecretRedactor.redact(result_url)` — pattern-scans the remaining URL for
|
|
107
|
+
secret substrings in non-sensitive query keys, fragments, or URL-like
|
|
108
|
+
strings (e.g. `?code=sk-...`, `?next=https://...token...`).
|
|
109
|
+
3. Preserve scheme, host, and path where possible; redact only secret
|
|
110
|
+
substrings and sensitive query values.
|
|
111
|
+
|
|
112
|
+
This two-pass approach is necessary because `redact_context()` alone only
|
|
113
|
+
catches secrets in *named* sensitive parameters. Secrets in innocuously-named
|
|
114
|
+
query values (`?code=sk-...`) or embedded in redirect URLs would leak through
|
|
115
|
+
without the `SecretRedactor` pattern scan.
|
|
116
|
+
|
|
117
|
+
### Already redacted (no change)
|
|
118
|
+
|
|
119
|
+
| Content | Current state |
|
|
120
|
+
|---|---|
|
|
121
|
+
| Request/response header values | Not exposed (P2: `header_names` keys only) |
|
|
122
|
+
| Response bodies | Not exposed (P2: excluded) |
|
|
123
|
+
| Navigate URL/params | Redacted by `SecurityManager.check_action()` (navigation-tier) |
|
|
124
|
+
| Action tool arguments | Redacted by `SecurityManager.check_action()` (action-tier) |
|
|
125
|
+
|
|
126
|
+
### Out of scope
|
|
127
|
+
|
|
128
|
+
- **`browser_status`** — returns runtime status (running, backend name). No
|
|
129
|
+
sensitive page content expected.
|
|
130
|
+
- **`screenshot`** — visual content; secret-detection in image data is a
|
|
131
|
+
different problem (OCR + pattern matching). Deferred.
|
|
132
|
+
- **Redaction of element HTML/attributes in `observe`.** `observe` returns
|
|
133
|
+
counts and metadata, not raw HTML. If a future tool exposes HTML, it joins
|
|
134
|
+
this scope.
|
|
135
|
+
- **Per-tool redaction policy overrides.** All inspect tools share one policy
|
|
136
|
+
(the `SecurityConfig`). Per-tool granular control is deferred.
|
|
137
|
+
|
|
138
|
+
## Architecture
|
|
139
|
+
|
|
140
|
+
### Option A (recommended): shared MCP redaction helper
|
|
141
|
+
|
|
142
|
+
Add a single helper in `mcp_server.py` that applies redaction to any
|
|
143
|
+
inspect-tier response dict before serialization:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
def _redact_inspect_output(payload: dict[str, Any]) -> dict[str, Any]:
|
|
147
|
+
"""Apply redaction policy to inspect-tier tool output.
|
|
148
|
+
|
|
149
|
+
Redacts string values in known-sensitive fields (text, message, url, etc.)
|
|
150
|
+
using the server's SecurityConfig. No-op if redaction is disabled or no
|
|
151
|
+
SecurityManager is configured.
|
|
152
|
+
"""
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Each inspect handler calls `_redact_inspect_output(payload)` before returning.
|
|
156
|
+
The helper uses the existing `SecretRedactor` + `redact_context()` machinery —
|
|
157
|
+
no new redaction logic.
|
|
158
|
+
|
|
159
|
+
**Why this over alternatives:** it's the narrowest change (one helper, called
|
|
160
|
+
from each handler), it reuses all existing machinery, and it keeps redaction at
|
|
161
|
+
the MCP boundary (principle #3).
|
|
162
|
+
|
|
163
|
+
### Option B (not recommended): wire `redact_result_dict` into `_serialize_action_result`
|
|
164
|
+
|
|
165
|
+
This would redact any `ActionResult` returned via MCP. But most inspect tools
|
|
166
|
+
don't return an `ActionResult` (they build dicts directly), so it wouldn't cover
|
|
167
|
+
`get_console_messages`, `list_requests`, etc. Incomplete.
|
|
168
|
+
|
|
169
|
+
### Option C (not recommended): redact inside `DiagnosticsBuffer` / the facade
|
|
170
|
+
|
|
171
|
+
This would redact at capture time, contaminating the buffer with masked values.
|
|
172
|
+
An SDK consumer using `sb.diagnostics` directly would get redacted data even if
|
|
173
|
+
they want raw. Violates principle #3.
|
|
174
|
+
|
|
175
|
+
## Sensitive classes (what gets redacted)
|
|
176
|
+
|
|
177
|
+
Reuse the existing `SecretRedactor` pattern set (`security/redactor.py`), which
|
|
178
|
+
covers:
|
|
179
|
+
|
|
180
|
+
- API keys (Anthropic, OpenAI, OpenRouter, GitHub, AWS, Google, Slack, Stripe)
|
|
181
|
+
- JWTs
|
|
182
|
+
- Passwords
|
|
183
|
+
- PEM/private keys
|
|
184
|
+
- Database URLs
|
|
185
|
+
- Generic tokens
|
|
186
|
+
|
|
187
|
+
Plus `_SENSITIVE_KEYS` for key-name matching (cookie, auth, session_id, etc.).
|
|
188
|
+
|
|
189
|
+
### Not redacted (by default)
|
|
190
|
+
|
|
191
|
+
- **Emails and phone numbers.** Not secrets in the same risk class as API keys.
|
|
192
|
+
Can be added as a configurable pattern layer if needed, but deferred to avoid
|
|
193
|
+
false positives that break utility.
|
|
194
|
+
- **IP addresses.** Same reasoning — operational data, not credentials.
|
|
195
|
+
- **Payment card numbers (PAN).** The `SecretRedactor` does not currently detect
|
|
196
|
+
these. Could be added as a custom pattern via `SecurityConfig.custom_secret_patterns`.
|
|
197
|
+
|
|
198
|
+
## Compatibility
|
|
199
|
+
|
|
200
|
+
- **Default behavior changes:** with `redaction_enabled=True` (the default),
|
|
201
|
+
inspect output now has secrets masked. This is a **behavior change** for
|
|
202
|
+
existing MCP consumers who relied on raw output. Documented in CHANGELOG.
|
|
203
|
+
- **Output shape unchanged:** same keys, same structure. Only string values may
|
|
204
|
+
contain redaction markers (`[REDACTED:{secret_type}:{hash6}]` from
|
|
205
|
+
`SecretRedactor`, or `[REDACTED:query_param]` from `redact_context()`).
|
|
206
|
+
- **Disabling:**
|
|
207
|
+
- **Current programmatic path:** pass
|
|
208
|
+
`SecurityManager(SecurityConfig(redaction_enabled=False))` into
|
|
209
|
+
`run_server(..., security_manager=...)`. Note that `run_server()` accepts a
|
|
210
|
+
`SecurityManager`, not a `SecurityConfig`; `_build_default_security_manager()`
|
|
211
|
+
constructs a default `SecurityConfig` internally using only domain
|
|
212
|
+
allow/block lists from env.
|
|
213
|
+
- **Proposed operator/CLI path:** add `SB_MCP_REDACTION=0|false|off` env
|
|
214
|
+
toggle in the implementation PR, parsed by `_build_default_security_manager()`
|
|
215
|
+
alongside the existing domain-list env vars. This gives operators a simple
|
|
216
|
+
opt-out without constructing a custom `SecurityManager`.
|
|
217
|
+
- **Backward-compat for SDK consumers:** Python SDK users calling
|
|
218
|
+
`sb.extract()` / `sb.observe()` directly are unaffected — redaction applies
|
|
219
|
+
only at the MCP serialization boundary.
|
|
220
|
+
|
|
221
|
+
## Test plan
|
|
222
|
+
|
|
223
|
+
### Unit tests (shared helper)
|
|
224
|
+
|
|
225
|
+
- `_redact_inspect_output` masks a known API key in a text field
|
|
226
|
+
- `_redact_inspect_output` masks a token in a URL query param
|
|
227
|
+
- `_redact_inspect_output` is a no-op when redaction is disabled
|
|
228
|
+
- `_redact_inspect_output` is a no-op when no secret patterns are present
|
|
229
|
+
- Output shape preserved (same keys, same structure)
|
|
230
|
+
|
|
231
|
+
### Tool-specific fixture tests
|
|
232
|
+
|
|
233
|
+
- `extract_text`: fixture with an API key in the text → redacted in response
|
|
234
|
+
- `observe`: fixture with a secret in title → redacted; URL query param redacted
|
|
235
|
+
- `current_url`: fixture/current page URL with a token query param → URL redacted
|
|
236
|
+
- `list_tabs`: fixture/tab list with secret-bearing URL/title → URL/title redacted
|
|
237
|
+
- `get_console_messages`: fixture with a token in console text → redacted
|
|
238
|
+
- `get_page_errors`: fixture with a secret in error message → redacted
|
|
239
|
+
- `get_network_errors`: fixture with failed request URL + failure_text secret → both redacted
|
|
240
|
+
- `list_requests`: fixture with a secret in URL query param → URL redacted
|
|
241
|
+
- `get_request`: fixture with a secret in failure_text → redacted
|
|
242
|
+
|
|
243
|
+
### Negative tests
|
|
244
|
+
|
|
245
|
+
- Non-secret text passes through unchanged (no false positives on normal prose)
|
|
246
|
+
- Redaction disabled → raw output (existing behavior)
|
|
247
|
+
|
|
248
|
+
## Implementation order (after design approval)
|
|
249
|
+
|
|
250
|
+
```text
|
|
251
|
+
1. Add _redact_inspect_output() helper in mcp_server.py
|
|
252
|
+
2. Wire into the 9 inspect-tier handlers (extract_text, observe, current_url,
|
|
253
|
+
list_tabs, 5 diagnostics)
|
|
254
|
+
3. Add SB_MCP_REDACTION env toggle (proposed in this design)
|
|
255
|
+
4. Unit tests for the helper
|
|
256
|
+
5. Fixture tests per tool
|
|
257
|
+
6. CHANGELOG [Unreleased] — behavior change note
|
|
258
|
+
7. Verify: real-browser e2e with a test page that logs a fake API key
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Resolved questions (from design review)
|
|
262
|
+
|
|
263
|
+
1. **Should `observe`'s URL be redacted?** **Yes.** Apply the two-pass URL
|
|
264
|
+
redaction (query-param names + secret pattern scan) while preserving scheme,
|
|
265
|
+
host, and path. The same policy applies to `current_url`, `list_tabs`,
|
|
266
|
+
diagnostics request URLs, and any future inspect-tier URL fields.
|
|
267
|
+
|
|
268
|
+
2. **Should redaction be on by default in the MCP server?** **Yes.** Default-on
|
|
269
|
+
matches the existing `SecurityConfig(redaction_enabled=True)` default and is
|
|
270
|
+
the safer boundary for agent-facing MCP output. A documented opt-out is
|
|
271
|
+
required (both programmatic and env-based), because this is a behavior
|
|
272
|
+
change for MCP consumers.
|
|
273
|
+
|
|
274
|
+
3. **Should console stack traces be truncated?** **No.** Use pattern-only
|
|
275
|
+
redaction by default. Preserve paths, line numbers, and stack structure;
|
|
276
|
+
redact detected secret substrings only. Truncation would hurt diagnostic
|
|
277
|
+
utility and should be a separate optional limit, not the default.
|
|
@@ -5,8 +5,8 @@ Super Browser exposes its browser inspection and control surface over the
|
|
|
5
5
|
agents (Claude, Cursor, etc.) can observe and interact with a page without
|
|
6
6
|
scripting Python.
|
|
7
7
|
|
|
8
|
-
The stdio server advertises **
|
|
9
|
-
diagnostics +
|
|
8
|
+
The stdio server advertises **seventeen tools by default** (six inspect + five
|
|
9
|
+
diagnostics + six navigation) — enough to read a URL end-to-end and explain
|
|
10
10
|
why a read failed. When action mode is enabled, it advertises **six additional
|
|
11
11
|
action tools**; every action call is checked by
|
|
12
12
|
`MCPSessionPolicy` and `SecurityManager` before it can reach the browser.
|
|
@@ -31,12 +31,12 @@ python -m patchright install chromium
|
|
|
31
31
|
Either of:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
superbrowser-mcp # default:
|
|
35
|
-
superbrowser-mcp --allow-actions #
|
|
34
|
+
superbrowser-mcp # default: 17 tools (inspect + diagnostics + navigation)
|
|
35
|
+
superbrowser-mcp --allow-actions # 23 tools (adds the action tier)
|
|
36
36
|
python -m super_browser.mcp_server
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Both start a **stdio** server. The default server advertises
|
|
39
|
+
Both start a **stdio** server. The default server advertises 17 tools and
|
|
40
40
|
recognizes (but refuses) action-tool calls with a structured policy refusal.
|
|
41
41
|
|
|
42
42
|
Action mode can also be enabled via the environment:
|
|
@@ -137,15 +137,21 @@ only.
|
|
|
137
137
|
|
|
138
138
|
### Navigation tier (always advertised)
|
|
139
139
|
|
|
140
|
-
Navigation mutates browser state (page acquisition) but is
|
|
141
|
-
because reading requires
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
Navigation mutates browser state (page/context acquisition) but is
|
|
141
|
+
default-allowed because reading requires page/context acquisition. `navigate`
|
|
142
|
+
is checked and audited at the MCP boundary when a SecurityManager is
|
|
143
|
+
configured. `switch_tab` delegates to the facade, which applies its configured
|
|
144
|
+
facade security policy. Navigation tools do **not** consume the action budget
|
|
145
|
+
and do **not** require action mode.
|
|
144
146
|
|
|
145
147
|
| Tool | Args | Behavior |
|
|
146
148
|
|---|---|---|
|
|
147
149
|
| `navigate` | `url` (required), `wait_until` (optional) | Go to a URL. URL is passed to `SecurityManager` for injection detection, secret redaction, and domain allow/block enforcement. |
|
|
148
150
|
| `wait_for` | exactly one of `selector` / `text` / `url` / `load_state`; `timeout_ms` (optional, 100–60000, default 10000) | Wait for a page condition before the next read. |
|
|
151
|
+
| `switch_tab` | `tab_id` (required, integer) | Switch the active browser tab by ID (from `list_tabs`). Changes the page the agent reads from. Diagnostics remain session-wide after switching; per-tab diagnostics are not supported yet. |
|
|
152
|
+
| `reload` | `wait_until` (optional) | Reload the current page. Returns the URL after reload. |
|
|
153
|
+
| `go_back` | `wait_until` (optional) | Go back one step in browser history. Returns a structured error if there is no previous entry. |
|
|
154
|
+
| `go_forward` | `wait_until` (optional) | Go forward one step in browser history. Returns a structured error if there is no next entry. |
|
|
149
155
|
|
|
150
156
|
`wait_for` accepts exactly one condition per call (deterministic single
|
|
151
157
|
results; compound waits can be added later as an explicit AND mode).
|
|
@@ -227,7 +233,7 @@ restricts the survivors.
|
|
|
227
233
|
|
|
228
234
|
The default server behavior partitions the surface by risk:
|
|
229
235
|
|
|
230
|
-
- **`list_tools()`** advertises only the Inspect + Navigation tiers (
|
|
236
|
+
- **`list_tools()`** advertises only the Inspect + Navigation tiers (17 tools).
|
|
231
237
|
- **`call_tool()`** still recognizes action-tool names and returns a structured
|
|
232
238
|
policy refusal (`refusal.reason = "actions are disabled"`), not an "Unknown
|
|
233
239
|
tool" error.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "superbrowser-sdk"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.7.0"
|
|
8
8
|
description = "Anti-detection agent browser SDK — stealth, budget governance, security guardrails, and structured error recovery behind one async facade"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|