superbrowser-sdk 2.7.0__tar.gz → 2.9.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.
Files changed (619) hide show
  1. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/CHANGELOG.md +56 -0
  2. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/PKG-INFO +1 -1
  3. superbrowser_sdk-2.9.0/docs/design/mcp_tool_metadata.md +199 -0
  4. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/mcp.md +23 -5
  5. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/pyproject.toml +1 -1
  6. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/__init__.py +1 -1
  7. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/facade.py +42 -2
  8. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/controller.py +114 -0
  9. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/mcp_server.py +202 -6
  10. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_controller_rebinding.py +3 -2
  11. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_diagnostics.py +2 -2
  12. superbrowser_sdk-2.9.0/tests/test_mcp_interaction.py +246 -0
  13. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_navigation.py +8 -8
  14. superbrowser_sdk-2.9.0/tests/test_mcp_observe_targets.py +329 -0
  15. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_server.py +5 -4
  16. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.env.example +0 -0
  17. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/adversarial-v3.yml +0 -0
  18. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/adversarial.yml +0 -0
  19. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/benchmark.yml +0 -0
  20. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/dco.yml +0 -0
  21. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/e2e.yml +0 -0
  22. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/publish.yml +0 -0
  23. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/smoke.yml +0 -0
  24. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/stress.yml +0 -0
  25. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.github/workflows/test.yml +0 -0
  26. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.gitignore +0 -0
  27. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/.pre-commit-config.yaml +0 -0
  28. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/CONTRIBUTING.md +0 -0
  29. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/Dockerfile +0 -0
  30. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/LICENSE +0 -0
  31. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/README.md +0 -0
  32. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/Super-Browser.png +0 -0
  33. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/behavioral.html +0 -0
  34. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/dom-heavy.html +0 -0
  35. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/form.html +0 -0
  36. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/simple.html +0 -0
  37. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/benchmarks/v1.11.0-baseline-patchright.json +0 -0
  38. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/benchmarks/v1.11.0-baseline-patchright.md +0 -0
  39. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/conftest.py +0 -0
  40. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docker-compose.yml +0 -0
  41. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/agent-reliability.md +0 -0
  42. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/aiv/AIV_FRAMEWORK_v5.3.md +0 -0
  43. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/anti-detection-ejecta.md +0 -0
  44. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/api-ergonomics-audit.md +0 -0
  45. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/api-reference.md +0 -0
  46. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/api-stability.md +0 -0
  47. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/architecture.md +0 -0
  48. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/behavioral-synthesis.md +0 -0
  49. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/browser-networking.md +0 -0
  50. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/cloak-integration.md +0 -0
  51. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/consistency-engine.md +0 -0
  52. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/design/inspect_redaction.md +0 -0
  53. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/discovery/DISCOVERY-REPORT.md +0 -0
  54. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/error-catalog.md +0 -0
  55. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/fingerprint-scoring.md +0 -0
  56. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/fingerprint-validation.md +0 -0
  57. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/gap-analysis.md +0 -0
  58. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/human-behavior.md +0 -0
  59. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/memory.md +0 -0
  60. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/migration/v1-to-v2.md +0 -0
  61. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/migration/v1.8-to-v1.9.md +0 -0
  62. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/operating-doctrine.md +0 -0
  63. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/platform-abstraction.md +0 -0
  64. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/plugins.md +0 -0
  65. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/quickstart.md +0 -0
  66. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/recording.md +0 -0
  67. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/rfcs/README.md +0 -0
  68. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-decomposition.md +0 -0
  69. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-a-api-simplification.md +0 -0
  70. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-b-network-stealth.md +0 -0
  71. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-c-behavioral-realism.md +0 -0
  72. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-d-challenge-infrastructure.md +0 -0
  73. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-e-e2e-harness.md +0 -0
  74. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/stealth-coverage.md +0 -0
  75. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/docs/stealth-evidence.md +0 -0
  76. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/backend_selection.py +0 -0
  77. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/basic_usage.py +0 -0
  78. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/budget_tracking.py +0 -0
  79. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/cloak_stealth.py +0 -0
  80. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/error_handling.py +0 -0
  81. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/fingerprint_scan.py +0 -0
  82. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/human_behavior.py +0 -0
  83. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/multi_tab_workflow.py +0 -0
  84. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/session_persistence.py +0 -0
  85. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/examples/stealth_mode.py +0 -0
  86. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/adversarial_run.py +0 -0
  87. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/agent_efficiency_benchmark.py +0 -0
  88. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/browser_benchmark.py +0 -0
  89. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/e2e_trend.py +0 -0
  90. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/run_stealth_gauntlet.sh +0 -0
  91. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/smoke_published.py +0 -0
  92. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/stress_real_world.py +0 -0
  93. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/validate_e2e_report.py +0 -0
  94. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/scripts/verify_release_artifact.py +0 -0
  95. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/__main__.py +0 -0
  96. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/__init__.py +0 -0
  97. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/config.py +0 -0
  98. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/debug.py +0 -0
  99. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/delegator.py +0 -0
  100. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/diagnostics.py +0 -0
  101. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/__init__.py +0 -0
  102. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/anthropic_client.py +0 -0
  103. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/browser_transport.py +0 -0
  104. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/budget_aware.py +0 -0
  105. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/factory.py +0 -0
  106. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/openai_client.py +0 -0
  107. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/protocol.py +0 -0
  108. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/loop.py +0 -0
  109. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/loop_detector.py +0 -0
  110. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/plugins.py +0 -0
  111. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/registry.py +0 -0
  112. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/router.py +0 -0
  113. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/structured_logging.py +0 -0
  114. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/types.py +0 -0
  115. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/__init__.py +0 -0
  116. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/bezier.py +0 -0
  117. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/dwell.py +0 -0
  118. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/fitts.py +0 -0
  119. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/gauss.py +0 -0
  120. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/keyboard.py +0 -0
  121. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/mouse.py +0 -0
  122. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/navigation.py +0 -0
  123. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/orchestrator.py +0 -0
  124. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/prng.py +0 -0
  125. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/qwerty.py +0 -0
  126. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/scroll.py +0 -0
  127. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/session_seed.py +0 -0
  128. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/types.py +0 -0
  129. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/__init__.py +0 -0
  130. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/__init__.py +0 -0
  131. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/cdp_backend.py +0 -0
  132. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/patchright_backend.py +0 -0
  133. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/playwright_backend.py +0 -0
  134. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/selenium_backend.py +0 -0
  135. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/cdp.py +0 -0
  136. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/cloak_backend.py +0 -0
  137. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/cloud.py +0 -0
  138. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/config.py +0 -0
  139. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/discovery.py +0 -0
  140. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/engine.py +0 -0
  141. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/fetch.py +0 -0
  142. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/__init__.py +0 -0
  143. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/bidi_injector.py +0 -0
  144. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/cdp_injector.py +0 -0
  145. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/page_injector.py +0 -0
  146. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/page.py +0 -0
  147. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/session.py +0 -0
  148. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/shutdown.py +0 -0
  149. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/tabs.py +0 -0
  150. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/__init__.py +0 -0
  151. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/cascade.py +0 -0
  152. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/client.py +0 -0
  153. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/compressor.py +0 -0
  154. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/cost_estimator.py +0 -0
  155. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/credential_pool.py +0 -0
  156. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/governor.py +0 -0
  157. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/types.py +0 -0
  158. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/__init__.py +0 -0
  159. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/commands.py +0 -0
  160. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/interactive.py +0 -0
  161. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/script.py +0 -0
  162. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/config.py +0 -0
  163. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/events/__init__.py +0 -0
  164. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/events/bus.py +0 -0
  165. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/events/types.py +0 -0
  166. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/__init__.py +0 -0
  167. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/cache.py +0 -0
  168. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/decorator.py +0 -0
  169. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/presets.py +0 -0
  170. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/recovery.py +0 -0
  171. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/snapshot.py +0 -0
  172. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/types.py +0 -0
  173. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/vision.py +0 -0
  174. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/__init__.py +0 -0
  175. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/integration.py +0 -0
  176. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/store.py +0 -0
  177. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/types.py +0 -0
  178. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/plugins/__init__.py +0 -0
  179. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/plugins/decorators.py +0 -0
  180. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/plugins/hooks.py +0 -0
  181. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/py.typed +0 -0
  182. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/__init__.py +0 -0
  183. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/persistence.py +0 -0
  184. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/recorder.py +0 -0
  185. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/replayer.py +0 -0
  186. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/report.py +0 -0
  187. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/types.py +0 -0
  188. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/__init__.py +0 -0
  189. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/checkpoint.py +0 -0
  190. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/classifier.py +0 -0
  191. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/coordinator.py +0 -0
  192. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/event_bus.py +0 -0
  193. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/format_validator.py +0 -0
  194. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/reflection.py +0 -0
  195. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/retry_tracker.py +0 -0
  196. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/session_recovery.py +0 -0
  197. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/types.py +0 -0
  198. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/watchdogs.py +0 -0
  199. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/__init__.py +0 -0
  200. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/output.py +0 -0
  201. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/typed.py +0 -0
  202. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/types.py +0 -0
  203. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/validation.py +0 -0
  204. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/__init__.py +0 -0
  205. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/action_redaction.py +0 -0
  206. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/approval.py +0 -0
  207. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/credential_vault.py +0 -0
  208. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/domain_filter.py +0 -0
  209. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/gate.py +0 -0
  210. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/injection.py +0 -0
  211. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/manager.py +0 -0
  212. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/policy.py +0 -0
  213. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/redactor.py +0 -0
  214. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/types.py +0 -0
  215. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/session/__init__.py +0 -0
  216. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/session/proxy.py +0 -0
  217. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/__init__.py +0 -0
  218. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/activation.py +0 -0
  219. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/markdown.py +0 -0
  220. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/registry.py +0 -0
  221. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/types.py +0 -0
  222. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/__init__.py +0 -0
  223. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/action_policy.py +0 -0
  224. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/captcha.py +0 -0
  225. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/__init__.py +0 -0
  226. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/cache.py +0 -0
  227. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/pow.py +0 -0
  228. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/turnstile.py +0 -0
  229. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/__init__.py +0 -0
  230. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/dag.py +0 -0
  231. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/derive.py +0 -0
  232. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/errors.py +0 -0
  233. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/inject.py +0 -0
  234. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/inject_delivery.py +0 -0
  235. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/matrix.py +0 -0
  236. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/prng.py +0 -0
  237. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rule.py +0 -0
  238. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/__init__.py +0 -0
  239. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/audio.py +0 -0
  240. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/behavior.py +0 -0
  241. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/fonts.py +0 -0
  242. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/gpu.py +0 -0
  243. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/locale.py +0 -0
  244. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/navigator.py +0 -0
  245. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/screen.py +0 -0
  246. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/user_agent.py +0 -0
  247. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/diagnostics.py +0 -0
  248. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/__init__.py +0 -0
  249. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/audio.py +0 -0
  250. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/browser_apis.py +0 -0
  251. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/canvas.py +0 -0
  252. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/config.py +0 -0
  253. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/registry.py +0 -0
  254. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/timing.py +0 -0
  255. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/types.py +0 -0
  256. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/webrtc.py +0 -0
  257. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/fingerprint_scanner.py +0 -0
  258. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/fingerprint_score.py +0 -0
  259. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/headers.py +0 -0
  260. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/human.py +0 -0
  261. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/human_config.py +0 -0
  262. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ip_reputation.py +0 -0
  263. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/manager.py +0 -0
  264. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/__init__.py +0 -0
  265. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/linux-chrome-stable.json +0 -0
  266. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/macos-chrome-stable.json +0 -0
  267. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/macos-m4-chrome-stable.json +0 -0
  268. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/windows-chrome-stable.json +0 -0
  269. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/host_detect.py +0 -0
  270. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/schema.py +0 -0
  271. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/proxy.py +0 -0
  272. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/proxy_pool.py +0 -0
  273. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/report.py +0 -0
  274. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/scoring.py +0 -0
  275. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/tls_baselines.json +0 -0
  276. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/tls_fingerprint.py +0 -0
  277. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/types.py +0 -0
  278. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/user_agent_pool.py +0 -0
  279. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/__init__.py +0 -0
  280. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/checks.py +0 -0
  281. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/harness.py +0 -0
  282. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/report.py +0 -0
  283. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/suite.py +0 -0
  284. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/testing.py +0 -0
  285. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/__init__.py +0 -0
  286. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/cost_analytics.py +0 -0
  287. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/flow_logger.py +0 -0
  288. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/middleware.py +0 -0
  289. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/session_db.py +0 -0
  290. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/sinks.py +0 -0
  291. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/types.py +0 -0
  292. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/__init__.py +0 -0
  293. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/ax_diff.py +0 -0
  294. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/hasher.py +0 -0
  295. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/types.py +0 -0
  296. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/verifier.py +0 -0
  297. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/__init__.py +0 -0
  298. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/cache.py +0 -0
  299. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/controller.py +0 -0
  300. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/coords.py +0 -0
  301. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/factory.py +0 -0
  302. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/ocr.py +0 -0
  303. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/providers.py +0 -0
  304. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/types.py +0 -0
  305. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/stress/__init__.py +0 -0
  306. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/stress/server.py +0 -0
  307. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/__init__.py +0 -0
  308. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/__init__.py +0 -0
  309. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/conftest.py +0 -0
  310. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/controlled_server.py +0 -0
  311. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/report.py +0 -0
  312. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/scoring.py +0 -0
  313. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/targets.py +0 -0
  314. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_controlled_server.py +0 -0
  315. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_targets_unit.py +0 -0
  316. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_tier1_scanners.py +0 -0
  317. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_tier2_vendors.py +0 -0
  318. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_tier3_controlled.py +0 -0
  319. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/README.md +0 -0
  320. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/__init__.py +0 -0
  321. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/backends.py +0 -0
  322. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/behavioral_telemetry.py +0 -0
  323. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/core.py +0 -0
  324. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/engines/__init__.py +0 -0
  325. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/engines/scoring.py +0 -0
  326. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/harness.py +0 -0
  327. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/__init__.py +0 -0
  328. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/history.py +0 -0
  329. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/json_reporter.py +0 -0
  330. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/markdown_reporter.py +0 -0
  331. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/server.py +0 -0
  332. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/__init__.py +0 -0
  333. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/automation.py +0 -0
  334. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/behavioral.py +0 -0
  335. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/controlled.py +0 -0
  336. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/ejector.py +0 -0
  337. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/external.py +0 -0
  338. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/fingerprint.py +0 -0
  339. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/network.py +0 -0
  340. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/pytest.ini +0 -0
  341. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/run.py +0 -0
  342. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/__init__.py +0 -0
  343. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/conftest.py +0 -0
  344. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_backends.py +0 -0
  345. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_behavioral_telemetry.py +0 -0
  346. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_behavioral_telemetry_smoke.py +0 -0
  347. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_behavioral_vectors.py +0 -0
  348. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_core.py +0 -0
  349. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_external.py +0 -0
  350. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_harness_smoke.py +0 -0
  351. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_header_ordering.py +0 -0
  352. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_reporters.py +0 -0
  353. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_scoring.py +0 -0
  354. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_server.py +0 -0
  355. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_superbrowser_backend.py +0 -0
  356. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_vectors.py +0 -0
  357. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/conftest.py +0 -0
  358. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/__init__.py +0 -0
  359. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/conftest.py +0 -0
  360. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_01_example_nav.py +0 -0
  361. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_02_google_search.py +0 -0
  362. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_03_github_login.py +0 -0
  363. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_04_amazon_search.py +0 -0
  364. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_05_google_forms.py +0 -0
  365. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_06_google_flights.py +0 -0
  366. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_07_wikipedia_extract.py +0 -0
  367. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_08_reddit_spa.py +0 -0
  368. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_09_form_complex.py +0 -0
  369. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_10_signup_flow.py +0 -0
  370. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/__init__.py +0 -0
  371. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/conftest.py +0 -0
  372. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_behavioral_realism.py +0 -0
  373. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_challenge_detection.py +0 -0
  374. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_interaction.py +0 -0
  375. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_live_navigation.py +0 -0
  376. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_multi_tab.py +0 -0
  377. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_navigation.py +0 -0
  378. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_session_persistence.py +0 -0
  379. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_stealth_overhead.py +0 -0
  380. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/e2e_v1_3_journey.py +0 -0
  381. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/__init__.py +0 -0
  382. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/conftest.py +0 -0
  383. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_config_composition.py +0 -0
  384. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_engine_backends.py +0 -0
  385. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_error_paths.py +0 -0
  386. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_facade_smoke.py +0 -0
  387. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_full_lifecycle.py +0 -0
  388. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_multi_backend.py +0 -0
  389. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_performance_smoke.py +0 -0
  390. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_playwright_integration.py +0 -0
  391. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_public_api.py +0 -0
  392. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_session_persistence.py +0 -0
  393. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_stealth_abstraction.py +0 -0
  394. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v1100_features.py +0 -0
  395. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v150_features.py +0 -0
  396. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v160_features.py +0 -0
  397. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v170_features.py +0 -0
  398. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v180_features.py +0 -0
  399. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v190_features.py +0 -0
  400. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v191_features.py +0 -0
  401. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v192_features.py +0 -0
  402. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v193_features.py +0 -0
  403. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v194_features.py +0 -0
  404. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v195_features.py +0 -0
  405. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v1_3_features.py +0 -0
  406. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v1_4_features.py +0 -0
  407. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/pattern_validation.py +0 -0
  408. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/__init__.py +0 -0
  409. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/conftest.py +0 -0
  410. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_chrome_runtime.py +0 -0
  411. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_cli_switches.py +0 -0
  412. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_headless_indicators.py +0 -0
  413. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_live_sites.py +0 -0
  414. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_runtime_enable.py +0 -0
  415. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_tls_fingerprint.py +0 -0
  416. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_webdriver.py +0 -0
  417. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/__init__.py +0 -0
  418. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_action_timeout.py +0 -0
  419. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_browser_transport.py +0 -0
  420. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_debug_mode.py +0 -0
  421. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_default_tooling.py +0 -0
  422. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_delegator.py +0 -0
  423. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_error_screenshots.py +0 -0
  424. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade.py +0 -0
  425. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security.py +0 -0
  426. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_control.py +0 -0
  427. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_file_tab.py +0 -0
  428. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_network.py +0 -0
  429. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_session.py +0 -0
  430. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_fail_fast.py +0 -0
  431. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm.py +0 -0
  432. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm_budget.py +0 -0
  433. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm_production.py +0 -0
  434. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm_streaming.py +0 -0
  435. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_loop.py +0 -0
  436. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_loop_detector.py +0 -0
  437. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_prompt_isolation.py +0 -0
  438. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_registry.py +0 -0
  439. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_retry_budget.py +0 -0
  440. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_streaming.py +0 -0
  441. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_structured_logging.py +0 -0
  442. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_tab_cap.py +0 -0
  443. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_task_02.py +0 -0
  444. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_types.py +0 -0
  445. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/__init__.py +0 -0
  446. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_behavioral.py +0 -0
  447. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_dwell.py +0 -0
  448. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_hardening.py +0 -0
  449. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_human_config_dwell.py +0 -0
  450. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_navigation.py +0 -0
  451. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_orchestrator.py +0 -0
  452. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_session_seed.py +0 -0
  453. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_benchmark/__init__.py +0 -0
  454. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_benchmark/test_efficiency.py +0 -0
  455. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_benchmarks/test_browser_benchmark.py +0 -0
  456. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_benchmarks/test_stress_real_world.py +0 -0
  457. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/__init__.py +0 -0
  458. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cdp.py +0 -0
  459. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cdp_backend.py +0 -0
  460. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cloak_backend.py +0 -0
  461. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cloak_docs.py +0 -0
  462. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cloak_integration.py +0 -0
  463. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_config.py +0 -0
  464. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_discovery.py +0 -0
  465. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_engine_protocol.py +0 -0
  466. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_fetch.py +0 -0
  467. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_injectors.py +0 -0
  468. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_page.py +0 -0
  469. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_patchright_backend.py +0 -0
  470. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_playwright_backend.py +0 -0
  471. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_selenium_backend.py +0 -0
  472. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_session.py +0 -0
  473. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_shutdown.py +0 -0
  474. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/__init__.py +0 -0
  475. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_cascade.py +0 -0
  476. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_cascade_governor.py +0 -0
  477. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_circuit_breaker.py +0 -0
  478. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_client.py +0 -0
  479. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_compressor.py +0 -0
  480. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_cost_estimator.py +0 -0
  481. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_credential_pool.py +0 -0
  482. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_governor.py +0 -0
  483. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_types.py +0 -0
  484. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_interactive.py +0 -0
  485. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_script.py +0 -0
  486. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_stealth_check.py +0 -0
  487. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_stealth_validate.py +0 -0
  488. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_unified_cli.py +0 -0
  489. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_config.py +0 -0
  490. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_diagnostics.py +0 -0
  491. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_e2e/test_report_schema.py +0 -0
  492. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_e2e/test_trend.py +0 -0
  493. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_audio.py +0 -0
  494. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_batch37_integration.py +0 -0
  495. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_batch38_integration.py +0 -0
  496. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_browser_apis.py +0 -0
  497. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_canvas.py +0 -0
  498. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_integration.py +0 -0
  499. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_timing.py +0 -0
  500. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_webrtc.py +0 -0
  501. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_events/test_event_bus.py +0 -0
  502. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_events/test_lifecycle_hooks.py +0 -0
  503. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_governance_docs.py +0 -0
  504. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/__init__.py +0 -0
  505. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_cache.py +0 -0
  506. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_controller.py +0 -0
  507. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_decorator.py +0 -0
  508. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_injection.py +0 -0
  509. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_page_change.py +0 -0
  510. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_presets.py +0 -0
  511. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_recovery.py +0 -0
  512. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_snapshot.py +0 -0
  513. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_types.py +0 -0
  514. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_vision.py +0 -0
  515. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_entrypoint.py +0 -0
  516. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_permissions.py +0 -0
  517. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_redaction.py +0 -0
  518. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_server_smoke.py +0 -0
  519. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_write_tools.py +0 -0
  520. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_write_tools_wave2.py +0 -0
  521. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_memory/__init__.py +0 -0
  522. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_memory/test_cli_config.py +0 -0
  523. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_memory/test_integration.py +0 -0
  524. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_memory/test_store.py +0 -0
  525. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recording/__init__.py +0 -0
  526. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recording/test_persistence.py +0 -0
  527. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recording/test_recorder.py +0 -0
  528. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recording/test_replayer.py +0 -0
  529. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/__init__.py +0 -0
  530. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_checkpoint.py +0 -0
  531. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_classifier.py +0 -0
  532. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_coordinator.py +0 -0
  533. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_event_bus.py +0 -0
  534. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_format_validator.py +0 -0
  535. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_reflection.py +0 -0
  536. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_retry_tracker.py +0 -0
  537. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_session_recovery.py +0 -0
  538. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_types.py +0 -0
  539. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_watchdogs.py +0 -0
  540. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_release/test_naming_consistency.py +0 -0
  541. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_release/test_smoke_published.py +0 -0
  542. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_release/test_verify_artifact.py +0 -0
  543. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_results/__init__.py +0 -0
  544. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_batch40_integration.py +0 -0
  545. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_categories.py +0 -0
  546. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_output.py +0 -0
  547. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_typed.py +0 -0
  548. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_types.py +0 -0
  549. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_validation.py +0 -0
  550. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_runtime_correctness/__init__.py +0 -0
  551. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_runtime_correctness/test_runtime_fixes.py +0 -0
  552. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/__init__.py +0 -0
  553. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_approval.py +0 -0
  554. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_credential_vault.py +0 -0
  555. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_domain_filter.py +0 -0
  556. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_injection.py +0 -0
  557. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_manager.py +0 -0
  558. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_policy.py +0 -0
  559. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_redaction_pipeline.py +0 -0
  560. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_redactor.py +0 -0
  561. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_types.py +0 -0
  562. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_session/__init__.py +0 -0
  563. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_session/test_locale.py +0 -0
  564. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_session/test_proxy.py +0 -0
  565. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_skills/__init__.py +0 -0
  566. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_activation.py +0 -0
  567. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_integration.py +0 -0
  568. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_markdown.py +0 -0
  569. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_registry.py +0 -0
  570. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_types.py +0 -0
  571. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/__init__.py +0 -0
  572. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_action_policy.py +0 -0
  573. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_captcha.py +0 -0
  574. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_captcha_resolution.py +0 -0
  575. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_challenge_cache.py +0 -0
  576. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_challenge_config.py +0 -0
  577. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_consistency/test_consistency.py +0 -0
  578. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_consistency_inject.py +0 -0
  579. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_diagnostics.py +0 -0
  580. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_e2e_lifecycle.py +0 -0
  581. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_e2e_reporting.py +0 -0
  582. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_fingerprint_scanner.py +0 -0
  583. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_fingerprint_score.py +0 -0
  584. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_headers.py +0 -0
  585. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_human.py +0 -0
  586. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_human_behavior_v2.py +0 -0
  587. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_ip_reputation.py +0 -0
  588. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_kasada_detection.py +0 -0
  589. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_manager.py +0 -0
  590. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_network_stealth_config.py +0 -0
  591. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_profiles.py +0 -0
  592. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_proxy.py +0 -0
  593. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_proxy_pool.py +0 -0
  594. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_stealth_bridge.py +0 -0
  595. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_tls_fingerprint.py +0 -0
  596. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_turnstile_detection.py +0 -0
  597. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_types.py +0 -0
  598. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_user_agent_pool.py +0 -0
  599. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_validation.py +0 -0
  600. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/__init__.py +0 -0
  601. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_cost_analytics.py +0 -0
  602. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_flow_logger.py +0 -0
  603. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_middleware.py +0 -0
  604. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_session_db.py +0 -0
  605. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_sinks.py +0 -0
  606. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_types.py +0 -0
  607. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_verification/__init__.py +0 -0
  608. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_ax_diff.py +0 -0
  609. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_hasher.py +0 -0
  610. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_types.py +0 -0
  611. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_verifier.py +0 -0
  612. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/__init__.py +0 -0
  613. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_cache.py +0 -0
  614. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_controller.py +0 -0
  615. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_coords.py +0 -0
  616. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_factory.py +0 -0
  617. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_ocr.py +0 -0
  618. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_providers.py +0 -0
  619. {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_types.py +0 -0
@@ -5,6 +5,62 @@ 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.9.0] — 2026-06-27
9
+
10
+ ### Added — MCP observe actionable targets
11
+
12
+ `observe` now returns a `targets` array of actionable element references
13
+ extracted from the accessibility snapshot. Each target includes:
14
+
15
+ - `target` — a ref string (e.g. `@e0`) usable as the `target` argument for
16
+ coordinate-tier action tools: `click`, `fill`, `type_text`, `hover`,
17
+ `select_option`. Checkbox/radio targets map to `click` (toggle-like) because
18
+ `check`/`uncheck` are selector-tier only and cannot resolve `@refs`.
19
+ - `role` — the AX role (button, textbox, checkbox, combobox, link, etc.)
20
+ - `name` — the accessible name (subject to inspect-output redaction)
21
+ - `action_hint` — recommended action for the role (`click`, `fill`,
22
+ select_option)
23
+
24
+ Targets are capped at 50 interactive, non-disabled elements.
25
+ `targets_truncated` indicates when more exist. This closes the gap where
26
+ agents had to guess CSS selectors — they can now go `observe → action`
27
+ deterministically using the refs returned by `observe`.
28
+
29
+ ### Documentation — MCP tool metadata design note (P4)
30
+
31
+ Added `docs/design/mcp_tool_metadata.md` — a design note analyzing whether
32
+ MCP tool schemas, tiers, validation, and docs should be unified onto the
33
+ existing `ToolDefinition` registry. **Decision: defer full unification.** The
34
+ current `ToolDefinition` cannot express MCP-specific metadata (tiers, enums,
35
+ ranges, validation hooks, bool-as-int rejection) without lossy flattening. Keep
36
+ `mcp_server.py` as the MCP source of truth until tool count or a production
37
+ mismatch justifies change. Trigger conditions and three future options
38
+ documented.
39
+
40
+ ## [2.8.0] — 2026-06-26
41
+
42
+ ### Added — MCP interaction tools (P3.1)
43
+
44
+ Six new action-tier MCP tools for form and element interaction:
45
+
46
+ - `hover` — hover over an element (controller-backed, selector/coordinate/vision cascade)
47
+ - `select_option` — select an option in a `<select>` element (maps to controller `select`, supports `by`: text/value/label)
48
+ - `check` — check a checkbox or radio button (new controller method + cascade)
49
+ - `uncheck` — uncheck a checkbox (new controller method + cascade)
50
+ - `focus` — focus an element (new controller method, selector-tier only)
51
+ - `type_text` — type text character-by-character (per-keystroke), triggering JS key listeners. Unlike `fill` which sets the value atomically. Supports `delay_ms` (0–1000). (new controller method)
52
+
53
+ All six are action-tier: require `--allow-actions`, consume the action budget,
54
+ pass through `SecurityManager` + audit, and are absent from the default
55
+ advertised surface.
56
+
57
+ - Default advertised tools: remains 17
58
+ - Action-mode advertised tools: 23 → 29
59
+
60
+ New controller primitives (`check`, `uncheck`, `focus`, `type_text`) added to
61
+ `MultimodalController` with `@agent_action` decorators and `FrameInteractionTarget`
62
+ adapters. Registered in the facade's builtin-tool loop.
63
+
8
64
  ## [2.7.0] — 2026-06-26
9
65
 
10
66
  ### Added — MCP reload and history navigation tools (P3.0B)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superbrowser-sdk
3
- Version: 2.7.0
3
+ Version: 2.9.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
@@ -0,0 +1,199 @@
1
+ # Design Note: MCP Tool Metadata Unification
2
+
3
+ > **Status:** Design note. No implementation.
4
+ > **Decision:** Defer full unification. Document the metadata contract; keep
5
+ > `mcp_server.py` as the MCP source of truth until pressure justifies change.
6
+ > **Date:** 2026-06-26
7
+
8
+ ## Core question
9
+
10
+ Should Super-Browser extend `ToolDefinition` to become the single source of
11
+ truth for MCP schemas, tiers, validation, and docs — or should MCP remain
12
+ hand-curated until there is stronger pressure?
13
+
14
+ ## Current state (v2.8.0)
15
+
16
+ The MCP server advertises **29 tools** in action mode (17 default). Tool
17
+ metadata is maintained in three parallel places:
18
+
19
+ ```text
20
+ 1. ToolRegistry / ToolDefinition / ToolParameter (agent-loop path)
21
+ - src/super_browser/agent/registry.py
22
+ - Typed specs, handlers, JSON schemas, toolsets, security_level
23
+ - Used by AgentLoop for the embedded act() path
24
+
25
+ 2. MCP types.Tool definitions + _tool_* handlers (MCP path)
26
+ - src/super_browser/mcp_server.py
27
+ - Hand-maintained lists: PHASE1_TOOLS, NAVIGATION_AUX_TOOLS,
28
+ DIAGNOSTICS_TOOLS, INTERACTION_TOOLS, PHASE2B_TOOLS, PHASE2B_WAVE2_TOOLS
29
+ - Handlers wired by name-string convention: getattr(self, f"_tool_{name}")
30
+
31
+ 3. MCP tier names + validation + authorization path (MCP path)
32
+ - INSPECT_TOOL_NAMES, NAVIGATION_TOOL_NAMES, ACTION_TOOL_NAMES frozensets
33
+ - Tool-tier list membership determines advertised/default/action behavior
34
+ - _validate_navigation_args / _validate_action_args (hand-written Python)
35
+ - MCPAuthorizer / SecurityManager path for action authorization
36
+ ```
37
+
38
+ These three sources are synchronized manually. Tests assert advertised counts
39
+ and tier membership, but there is no compile-time guarantee they agree.
40
+
41
+ ## Problem
42
+
43
+ Duplication is growing. Each new MCP tool requires:
44
+
45
+ - A `types.Tool` definition (schema, description)
46
+ - A `_tool_*` handler method
47
+ - An entry in the right `*_TOOLS` list (which determines tier membership)
48
+ - An entry in `_validate_action_args` or `_validate_navigation_args` (hand-written validation)
49
+ - An entry in the `ACTION_TOOL_NAMES` / `NAVIGATION_TOOL_NAMES` frozenset
50
+ - Updates to count assertions across 4+ test files
51
+ - Updates to `docs/mcp.md` (tool table + counts)
52
+ - Updates to `CHANGELOG.md`
53
+
54
+ That is 8 touch points per tool. With 29 tools now and P5/P6 work still ahead,
55
+ the maintenance surface is real.
56
+
57
+ ## Why current ToolDefinition cannot serve as MCP source of truth
58
+
59
+ Fact-checked against `src/super_browser/agent/registry.py` (lines 17-63):
60
+
61
+ ### 1. Schema expressiveness is too flat
62
+
63
+ `ToolDefinition.to_json_schema()` produces a flat type system:
64
+ `str→string, int→integer, float→number, bool→boolean`. It cannot express:
65
+
66
+ - **Enums** — used heavily: `scroll.direction`, `wait_for.load_state`,
67
+ `select_option.by`, `reload.wait_until`
68
+ - **Defaults** — MCP uses `"default": false`, `"default": 10000`;
69
+ `ToolParameter` stores a default but `to_json_schema()` never emits it
70
+ - **Numeric ranges** — `wait_for.timeout_ms` (100–60000),
71
+ `type_text.delay_ms` (0–1000)
72
+ - **Bool-as-int rejection** — MCP validation explicitly rejects `bool` where
73
+ `int` is expected; `ToolParameter` has no concept of this
74
+ - **Nested objects / arrays** — MCP `inputSchema.properties` can nest
75
+
76
+ ### 2. Tier metadata is a different axis
77
+
78
+ `ToolDefinition.security_level` takes values `safe`/`sensitive`/`dangerous`
79
+ (a risk scale). MCP tiers are `inspect`/`navigation`/`action` (permission
80
+ buckets, assigned by list membership). There is no automatic mapping:
81
+
82
+ - `navigate` is `sensitive` but navigation-tier (default-allowed)
83
+ - `scroll` is `safe` but action-tier (gated)
84
+ - `screenshot` is `sensitive` but inspect-tier (no security check)
85
+
86
+ `ToolDefinition` has no `tier` field. Its `toolsets` field is a grouping
87
+ concept unrelated to MCP permission tiers.
88
+
89
+ ### 3. Validation hooks are hand-written Python
90
+
91
+ MCP argument validation (`_validate_navigation_args`,
92
+ `_validate_action_args`) contains logic that no schema can express:
93
+ non-empty string checks, bool-as-int rejection, range bounds, exactly-one-
94
+ condition constraints (`wait_for`). This logic cannot be generated from any
95
+ data structure — it requires executable validation hooks.
96
+
97
+ ### 4. Handler dispatch is name-string convention
98
+
99
+ MCP dispatches via `getattr(self, f"_tool_{name}")`. This is a runtime
100
+ convention with no type safety. `ToolDefinition.handler` is a callable
101
+ reference, but the MCP path doesn't use it — it uses its own dispatch table.
102
+
103
+ ## What MCP metadata would need (the full contract)
104
+
105
+ ```text
106
+ Per-tool metadata required:
107
+ - tool name (str)
108
+ - tier: inspect | navigation | action | high_risk
109
+ - advertised_by_default: bool (derived from tier)
110
+ - security_level: safe | sensitive | dangerous
111
+ - action_budget: consumes | does_not_consume
112
+ - input schema:
113
+ - parameter name
114
+ - type (str, int, bool, str-enum, ...)
115
+ - required: bool
116
+ - default value
117
+ - enum values (where applicable)
118
+ - numeric range (min, max)
119
+ - reject_bool_as_int: bool
120
+ - validation hook: callable(args) -> error | None
121
+ - handler binding: callable or name convention
122
+ - description (for MCP tool listing)
123
+ - redaction policy: which output fields to redact, text vs URL
124
+ ```
125
+
126
+ This is substantially richer than what `ToolDefinition` carries today.
127
+
128
+ ## Decision: defer full unification
129
+
130
+ ```text
131
+ Do not implement automatic MCP schema generation now.
132
+
133
+ Reasons:
134
+ 1. Current ToolDefinition cannot express MCP metadata without lossy flattening.
135
+ 2. Forcing MCP schemas through it would damage validation, enums, ranges.
136
+ 3. The maintenance pain (8 touch points per tool) is real but manageable
137
+ at 29 tools.
138
+ 4. A partial generator that can't express tier/validation/security
139
+ faithfully is worse than hand-curated — it would create a false sense
140
+ of single-source-of-truth while silently diverging.
141
+ ```
142
+
143
+ ## What to do instead
144
+
145
+ ### Now (no code change)
146
+
147
+ Keep `mcp_server.py` as the MCP source of truth. Document this design note
148
+ as the contract for what a future unification would require.
149
+
150
+ ### Trigger conditions for revisiting
151
+
152
+ Re-evaluate when any of these become true:
153
+
154
+ ```text
155
+ 1. MCP tool count exceeds ~40 (currently 29)
156
+ 2. A tool is added with the wrong tier and isn't caught until production
157
+ 3. Validation logic is duplicated between MCP and SDK paths
158
+ 4. A third consumer (e.g. external-agent API) needs the same metadata
159
+ ```
160
+
161
+ ### Future options (when triggered)
162
+
163
+ ```text
164
+ Option A — MCPToolDefinition wrapper:
165
+ A new dataclass that wraps ToolDefinition and adds MCP-specific fields
166
+ (tier, advertised_by_default, validation_hook, redaction_policy).
167
+ Pro: doesn't pollute the SDK registry.
168
+ Con: still two definitions per tool.
169
+
170
+ Option B — Extend ToolDefinition:
171
+ Add tier, enum_constraints, defaults, ranges, validation_hook fields.
172
+ Pro: true single source of truth.
173
+ Con: makes the SDK registry awkward for non-MCP consumers; schema migration.
174
+
175
+ Option C — Generate MCP from a new tool-spec module:
176
+ A dedicated mcp_tools.py that defines tool specs with full metadata,
177
+ generates types.Tool objects, validation functions, and docs entries.
178
+ Pro: MCP owns its own metadata; no SDK pollution.
179
+ Con: doesn't unify with the SDK registry (but that may be acceptable).
180
+ ```
181
+
182
+ The design note recommends **Option C** if/when triggered — it keeps MCP
183
+ and SDK concerns separate while reducing MCP's internal duplication.
184
+
185
+ ## Comparison to existing inspect-redaction design
186
+
187
+ The P2.3 redaction design (`docs/design/inspect_redaction.md`) took a
188
+ similar approach: document the boundary, reuse existing machinery, defer
189
+ per-tool overrides. This note follows the same pattern for tool metadata.
190
+
191
+ ## Summary
192
+
193
+ ```text
194
+ Problem: 8 touch points per MCP tool; metadata in 3+ places.
195
+ Root cause: ToolDefinition is too flat for MCP's needs.
196
+ Decision: Defer unification. Keep hand-curated MCP.
197
+ Trigger: ~40 tools, or a tier-mismatch production incident.
198
+ Preferred future path: Option C (dedicated MCP tool-spec module).
199
+ ```
@@ -7,7 +7,7 @@ scripting Python.
7
7
 
8
8
  The stdio server advertises **seventeen tools by default** (six inspect + five
9
9
  diagnostics + six navigation) — enough to read a URL end-to-end and explain
10
- why a read failed. When action mode is enabled, it advertises **six additional
10
+ why a read failed. When action mode is enabled, it advertises **twelve additional
11
11
  action tools**; every action call is checked by
12
12
  `MCPSessionPolicy` and `SecurityManager` before it can reach the browser.
13
13
 
@@ -32,7 +32,7 @@ Either of:
32
32
 
33
33
  ```bash
34
34
  superbrowser-mcp # default: 17 tools (inspect + diagnostics + navigation)
35
- superbrowser-mcp --allow-actions # 23 tools (adds the action tier)
35
+ superbrowser-mcp --allow-actions # 29 tools (adds the action tier)
36
36
  python -m super_browser.mcp_server
37
37
  ```
38
38
 
@@ -115,7 +115,7 @@ advertised; the third requires action mode; the fourth is not implemented.
115
115
  |---|---|---|---|
116
116
  | `browser_status` | none | Runtime status (running, backend). | No |
117
117
  | `current_url` | none | Current URL, or a structured "not started" state. | No |
118
- | `observe` | none | Page state: URL, title, interactive/total element counts. | Yes |
118
+ | `observe` | none | Page state: URL, title, interactive/total element counts, and a `targets` array of actionable element references (capped at 50). Each target includes `target` (a ref like `@e0`, usable as the `target` argument for coordinate-tier action tools: `click`, `fill`, `type_text`, `hover`, `select_option`), `role`, `name`, and `action_hint`. | Yes |
119
119
  | `extract_text` | `query` (required), `selector` (optional) | Text content, optionally scoped to a CSS selector. | Yes |
120
120
  | `screenshot` | `full_page` (optional, default `false`) | Base64 PNG of the viewport or full page. | Yes |
121
121
  | `list_tabs` | none | Snapshot of open tabs. | Yes |
@@ -162,7 +162,17 @@ results; compound waits can be added later as an explicit AND mode).
162
162
  navigate → wait_for → observe / extract_text / screenshot
163
163
  ```
164
164
 
165
- This is the default-mode loop an agent uses to read a page.
165
+ This is the default-mode loop an agent uses to read a page. `observe` returns
166
+ actionable targets (`@e0` refs) that can be passed directly as the `target`
167
+ argument to coordinate-tier action tools (`click`, `fill`, `type_text`,
168
+ `hover`, `select_option`):
169
+
170
+ ```text
171
+ navigate → wait_for → observe → click(target="@e0")
172
+ ```
173
+
174
+ The `targets` array is capped at 50; `targets_truncated` indicates whether more
175
+ interactive elements exist. Target names are subject to inspect-output redaction.
166
176
 
167
177
  #### Debugging workflow
168
178
 
@@ -192,9 +202,17 @@ entry, no side effects.
192
202
  | `fill` | `target` (required), `value` (required), `clear_first` (optional), `description` (optional) | SENSITIVE |
193
203
  | `open_tab` | `url` (optional) | SENSITIVE — URL passed to `SecurityManager` when provided |
194
204
  | `close_tab` | `tab_id` (required) | SENSITIVE |
205
+ | `hover` | `target` (required), `description` (optional) | SENSITIVE |
206
+ | `select_option` | `target` (required), `option` (required), `by` (optional: text/value/label), `description` (optional) | SENSITIVE |
207
+ | `check` | `target` (required), `description` (optional) | SENSITIVE |
208
+ | `uncheck` | `target` (required), `description` (optional) | SENSITIVE |
209
+ | `focus` | `target` (required), `description` (optional) | SENSITIVE |
210
+ | `type_text` | `target` (required), `text` (required), `delay_ms` (optional, 0–1000), `description` (optional) | SENSITIVE |
195
211
 
196
212
  `fill` sends only the literal value supplied by the caller. It does not
197
- retrieve, infer, store, or auto-fill credentials.
213
+ retrieve, infer, store, or auto-fill credentials. `type_text` types
214
+ character-by-character (per-keystroke), triggering JS key listeners — unlike
215
+ `fill` which sets the value atomically.
198
216
 
199
217
  #### Action workflow
200
218
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "superbrowser-sdk"
7
- version = "2.7.0"
7
+ version = "2.9.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" }
@@ -6,7 +6,7 @@ from super_browser.agent.types import StreamEvent as StreamEvent # noqa: F401
6
6
  from super_browser.config import Config as Config # noqa: F401
7
7
  from super_browser.results.types import ActionResult as ActionResult # noqa: F401
8
8
 
9
- __version__ = "2.7.0"
9
+ __version__ = "2.9.0"
10
10
 
11
11
  __all__ = [
12
12
  "SuperBrowser",
@@ -482,10 +482,49 @@ class SuperBrowser:
482
482
  snap = await self._controller.capture_ax_snapshot()
483
483
  interactive_count = sum(1 for n in snap.nodes.values() if n.is_interactive)
484
484
 
485
+ # Build actionable targets from the AX snapshot.
486
+ # The ref (e.g. "@e0") is directly usable as a `target` argument for
487
+ # click/fill/type_text/etc. — the controller's coordinate tier resolves
488
+ # @refs to element coordinates via the snapshot.
489
+ _ROLE_ACTION_MAP = {
490
+ "button": "click", "link": "click", "menuitem": "click",
491
+ "tab": "click", "treeitem": "click", "option": "click",
492
+ "textbox": "fill", "searchbox": "fill", "spinbutton": "fill",
493
+ "combobox": "select_option", "checkbox": "click", "radio": "click",
494
+ "slider": "fill", "switch": "click",
495
+ }
496
+
497
+ # Only include nodes whose center is resolvable (bounds present),
498
+ # because @refs are resolved via the coordinate tier. Nodes without
499
+ # bounds cannot be acted on and would produce a confusing target.
500
+ # Checkbox/radio map to "click" (not "check") because check/uncheck
501
+ # are selector-tier only and cannot resolve @refs.
502
+ all_interactive = [
503
+ n for n in snap.nodes.values()
504
+ if n.is_interactive and not n.disabled and n.center is not None
505
+ ]
506
+ _MAX_TARGETS = 50
507
+ capped = all_interactive[:_MAX_TARGETS]
508
+ targets = [
509
+ {
510
+ "target": n.ref if n.ref.startswith("@") else f"@{n.ref}",
511
+ "role": n.role,
512
+ "name": n.name,
513
+ "action_hint": _ROLE_ACTION_MAP.get(n.role, "click"),
514
+ }
515
+ for n in capped
516
+ ]
517
+
485
518
  return timed_action_result(
486
519
  ok=True,
487
520
  start_ns=start,
488
- data={"url": url, "title": title, "interactive_elements": interactive_count, "total_elements": len(snap.nodes)},
521
+ data={
522
+ "url": url, "title": title,
523
+ "interactive_elements": interactive_count,
524
+ "total_elements": len(snap.nodes),
525
+ "targets": targets,
526
+ "targets_truncated": len(all_interactive) > _MAX_TARGETS,
527
+ },
489
528
  )
490
529
 
491
530
  # -- Tab helper (CHK-07) --
@@ -1003,7 +1042,8 @@ class SuperBrowser:
1003
1042
  # self._controller, the registered tools still route to the current
1004
1043
  # controller. Raw bound methods would capture the old controller
1005
1044
  # instance and act on a stale page after tab switches.
1006
- for name in ("click", "fill", "select", "hover", "drag", "scroll", "keypress"):
1045
+ for name in ("click", "fill", "select", "hover", "drag", "scroll", "keypress",
1046
+ "check", "uncheck", "focus", "type_text"):
1007
1047
  method = getattr(self._controller, name, None)
1008
1048
  if method is not None and self._registry.get(name) is None:
1009
1049
  self._registry.register(self._make_controller_wrapper(name))
@@ -81,6 +81,18 @@ class FrameInteractionTarget:
81
81
  async def hover(self, selector: str) -> None:
82
82
  await self._frame.locator(selector).hover()
83
83
 
84
+ async def check(self, selector: str) -> None:
85
+ await self._frame.locator(selector).check()
86
+
87
+ async def uncheck(self, selector: str) -> None:
88
+ await self._frame.locator(selector).uncheck()
89
+
90
+ async def focus(self, selector: str) -> None:
91
+ await self._frame.locator(selector).focus()
92
+
93
+ async def type_text(self, selector: str, text: str, *, delay: int = 0) -> None:
94
+ await self._frame.locator(selector).type(text, delay=delay)
95
+
84
96
  async def drag_and_drop(self, source: str, target: str) -> None:
85
97
  src = self._frame.locator(source)
86
98
  dst = self._frame.locator(target)
@@ -328,6 +340,108 @@ class MultimodalController:
328
340
  result, _ = await self._cascade("hover", target, description, t1, t2, t3)
329
341
  return result
330
342
 
343
+ @agent_action(security_level="sensitive")
344
+ async def check(
345
+ self,
346
+ target: str,
347
+ *,
348
+ description: Optional[str] = None,
349
+ ) -> ActionResult:
350
+ """Check a checkbox or radio button.
351
+
352
+ Selector-tier only — coordinate/vision fallbacks would be toggle-like
353
+ (clicks that can uncheck an already-checked box), violating the
354
+ idempotent state-enforcing semantics implied by the tool name.
355
+ """
356
+
357
+ async def t1():
358
+ await self._interaction_target.check(target)
359
+ return action_result(ok=True, data={"target": target}, method=ActionMethod.SELECTOR)
360
+
361
+ result, _ = await self._cascade("check", target, description, t1)
362
+ return result
363
+
364
+ @agent_action(security_level="sensitive")
365
+ async def uncheck(
366
+ self,
367
+ target: str,
368
+ *,
369
+ description: Optional[str] = None,
370
+ ) -> ActionResult:
371
+ """Uncheck a checkbox.
372
+
373
+ Selector-tier only — same rationale as ``check``: coordinate/vision
374
+ fallbacks would be toggle-like, not state-enforcing.
375
+ """
376
+
377
+ async def t1():
378
+ await self._interaction_target.uncheck(target)
379
+ return action_result(ok=True, data={"target": target}, method=ActionMethod.SELECTOR)
380
+
381
+ result, _ = await self._cascade("uncheck", target, description, t1)
382
+ return result
383
+
384
+ @agent_action(security_level="sensitive")
385
+ async def focus(
386
+ self,
387
+ target: str,
388
+ *,
389
+ description: Optional[str] = None,
390
+ ) -> ActionResult:
391
+ """Focus an element."""
392
+
393
+ async def t1():
394
+ await self._interaction_target.focus(target)
395
+ return action_result(ok=True, data={"target": target}, method=ActionMethod.SELECTOR)
396
+
397
+ # Focus has no meaningful coordinate/vision fallback — a click would be
398
+ # a different action, not a focus. Only selector-tier.
399
+ result, _ = await self._cascade("focus", target, description, t1)
400
+ return result
401
+
402
+ @agent_action(security_level="sensitive")
403
+ async def type_text(
404
+ self,
405
+ target: str,
406
+ text: str,
407
+ *,
408
+ delay: int = 0,
409
+ description: Optional[str] = None,
410
+ ) -> ActionResult:
411
+ """Type text character-by-character (per-keystroke), unlike fill.
412
+
413
+ Triggers JS keydown/keypress/keyup listeners, suitable for autocomplete,
414
+ masked inputs, and debounce handlers.
415
+ """
416
+
417
+ async def t1():
418
+ await self._interaction_target.type_text(target, text, delay=delay)
419
+ return action_result(ok=True, data={"target": target, "text_length": len(text)}, method=ActionMethod.SELECTOR)
420
+
421
+ async def t2():
422
+ coords = await self._resolve_to_coordinates(target)
423
+ if coords is None:
424
+ return action_result(ok=False, error=ActionError(ErrorCategory.SELECTOR_NOT_FOUND, f"Cannot resolve '{target}'"))
425
+ # Click to focus, then type via CDP.
426
+ await self._cdp.send("Input.dispatchMouseEvent", {
427
+ "type": "mousePressed", "x": coords[0], "y": coords[1],
428
+ "button": "left", "clickCount": 1,
429
+ })
430
+ await self._cdp.send("Input.dispatchMouseEvent", {
431
+ "type": "mouseReleased", "x": coords[0], "y": coords[1],
432
+ "button": "left", "clickCount": 1,
433
+ })
434
+ for char in text:
435
+ await self._cdp.send("Input.dispatchKeyEvent", {
436
+ "type": "char", "text": char,
437
+ })
438
+ if delay:
439
+ await asyncio.sleep(delay / 1000)
440
+ return action_result(ok=True, data={"target": target, "method": "coordinate"}, method=ActionMethod.COORDINATE)
441
+
442
+ result, _ = await self._cascade("type_text", target, description, t1, t2)
443
+ return result
444
+
331
445
  @agent_action(security_level="dangerous")
332
446
  async def drag(
333
447
  self,