webtap-tool 0.5.0__tar.gz → 0.5.2__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.
Potentially problematic release.
This version of webtap-tool might be problematic. Click here for more details.
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/CHANGELOG.md +28 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/PKG-INFO +1 -1
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/pyproject.toml +1 -1
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/javascript.py +25 -7
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/selections.py +2 -2
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/setup/extension.py +8 -1
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/.gitignore +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/ARCHITECTURE.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/README.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/data/filters.json +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/extension/content.js +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/extension/manifest.json +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/extension/sidepanel.html +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/extension/sidepanel.js +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/llms.txt +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/VISION.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/__init__.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/api.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/app.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/cdp/README.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/cdp/__init__.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/cdp/query.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/cdp/schema/README.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/cdp/schema/cdp_protocol.json +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/cdp/schema/cdp_version.json +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/cdp/session.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/DEVELOPER_GUIDE.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/TIPS.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/__init__.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/_builders.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/_tips.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/_utils.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/body.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/connection.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/console.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/events.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/fetch.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/filters.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/inspect.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/launch.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/navigation.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/network.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/server.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/commands/setup.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/filters.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/README.md +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/__init__.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/body.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/console.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/dom.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/fetch.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/main.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/network.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/setup/__init__.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/setup/chrome.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/setup/desktop.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/setup/filters.py +0 -0
- {webtap_tool-0.5.0 → webtap_tool-0.5.2}/src/webtap/services/setup/platform.py +0 -0
|
@@ -15,6 +15,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
15
|
|
|
16
16
|
### Removed
|
|
17
17
|
|
|
18
|
+
## [0.5.2] - 2025-10-09
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- **setup-extension**: Update to download new side panel files (content.js, sidepanel.html, sidepanel.js) instead of old popup files
|
|
26
|
+
- **setup-extension --force**: Now properly cleans old extension directory before downloading new files
|
|
27
|
+
- **selections() command**: Updated error message to reference "side panel" instead of "popup"
|
|
28
|
+
|
|
29
|
+
### Removed
|
|
30
|
+
|
|
31
|
+
## [0.5.1] - 2025-10-09
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **js() persist parameter**: New `persist` parameter to control variable scope across calls (default: False)
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- **js() default scope**: Fresh scope by default (IIFE wrapping) to prevent const/let redeclaration errors
|
|
38
|
+
- **js() selection wrapping**: Selection parameter always uses fresh scope to avoid element redeclaration
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- **js() redeclaration errors**: Fixed "Identifier 'element' has already been declared" when using selection parameter multiple times
|
|
42
|
+
- **js() const/let errors**: Fixed redeclaration errors when running multiple js() calls with const/let
|
|
43
|
+
|
|
44
|
+
### Removed
|
|
45
|
+
|
|
18
46
|
## [0.5.0] - 2025-10-09
|
|
19
47
|
|
|
20
48
|
### Added
|
|
@@ -15,26 +15,39 @@ mcp_desc = get_mcp_description("js")
|
|
|
15
15
|
},
|
|
16
16
|
fastmcp={"type": "tool", "description": mcp_desc} if mcp_desc else {"type": "tool"},
|
|
17
17
|
)
|
|
18
|
-
def js(
|
|
18
|
+
def js(
|
|
19
|
+
state,
|
|
20
|
+
code: str,
|
|
21
|
+
selection: int = None, # pyright: ignore[reportArgumentType]
|
|
22
|
+
persist: bool = False,
|
|
23
|
+
wait_return: bool = True,
|
|
24
|
+
await_promise: bool = False,
|
|
25
|
+
) -> dict:
|
|
19
26
|
"""Execute JavaScript in the browser with optional element selection.
|
|
20
27
|
|
|
21
28
|
Args:
|
|
22
29
|
code: JavaScript code to execute (use 'element' variable if selection provided)
|
|
23
30
|
selection: Browser element selection number (e.g., 1 for #1) - makes element available
|
|
31
|
+
persist: Keep variables in global scope across calls (default: False, uses fresh scope)
|
|
24
32
|
wait_return: Wait for and return result (default: True)
|
|
25
33
|
await_promise: Await promises before returning (default: False)
|
|
26
34
|
|
|
27
35
|
Examples:
|
|
36
|
+
# Default: fresh scope (no redeclaration errors)
|
|
37
|
+
js("const x = 1") # ✓ x isolated
|
|
38
|
+
js("const x = 2") # ✓ No error, fresh scope
|
|
28
39
|
js("document.title") # Get page title
|
|
29
|
-
js("document.body.innerText.length") # Get text length
|
|
30
|
-
js("console.log('test')", wait_return=False) # Fire and forget
|
|
31
40
|
js("[...document.links].map(a => a.href)") # Get all links
|
|
32
41
|
|
|
33
|
-
# With browser element selection
|
|
34
|
-
js("element.offsetWidth", selection=1) # Use element #1
|
|
42
|
+
# With browser element selection (always fresh scope)
|
|
43
|
+
js("element.offsetWidth", selection=1) # Use element #1
|
|
35
44
|
js("element.classList", selection=2) # Use element #2
|
|
36
45
|
js("element.getBoundingClientRect()", selection=1)
|
|
37
46
|
|
|
47
|
+
# Persistent scope: keep variables across calls
|
|
48
|
+
js("var data = fetch('/api')", persist=True) # data persists
|
|
49
|
+
js("data.json()", persist=True) # Access data from previous call
|
|
50
|
+
|
|
38
51
|
# Async operations
|
|
39
52
|
js("fetch('/api').then(r => r.json())", await_promise=True)
|
|
40
53
|
|
|
@@ -74,8 +87,13 @@ def js(state, code: str, selection: int = None, wait_return: bool = True, await_
|
|
|
74
87
|
if not js_path:
|
|
75
88
|
return error_response(f"Selection #{selection} has no jsPath")
|
|
76
89
|
|
|
77
|
-
# Wrap code with element variable
|
|
78
|
-
|
|
90
|
+
# Wrap code with element variable in fresh scope (IIFE)
|
|
91
|
+
# Selection always uses fresh scope to avoid element redeclaration errors
|
|
92
|
+
code = f"(() => {{ const element = {js_path}; return ({code}); }})()"
|
|
93
|
+
elif not persist:
|
|
94
|
+
# Default: wrap in IIFE for fresh scope (avoids const/let redeclaration errors)
|
|
95
|
+
code = f"(() => {{ return ({code}); }})()"
|
|
96
|
+
# else: persist=True, use code as-is (global scope)
|
|
79
97
|
|
|
80
98
|
result = state.cdp.execute(
|
|
81
99
|
"Runtime.evaluate", {"expression": code, "returnByValue": wait_return, "awaitPromise": await_promise}
|
|
@@ -38,8 +38,8 @@ def selections(state, expr: str = None) -> dict: # pyright: ignore[reportArgume
|
|
|
38
38
|
"No browser selections available",
|
|
39
39
|
suggestions=[
|
|
40
40
|
"Use the Chrome extension to select elements",
|
|
41
|
-
"Click 'Start Selection Mode' in the extension
|
|
42
|
-
"Select elements on the page
|
|
41
|
+
"Click 'Start Selection Mode' in the extension side panel",
|
|
42
|
+
"Select elements on the page",
|
|
43
43
|
],
|
|
44
44
|
)
|
|
45
45
|
|
|
@@ -12,7 +12,7 @@ logger = logging.getLogger(__name__)
|
|
|
12
12
|
|
|
13
13
|
# GitHub URLs for extension files
|
|
14
14
|
EXTENSION_BASE_URL = "https://raw.githubusercontent.com/angelsen/tap-tools/main/packages/webtap/extension"
|
|
15
|
-
EXTENSION_FILES = ["manifest.json", "
|
|
15
|
+
EXTENSION_FILES = ["manifest.json", "content.js", "sidepanel.html", "sidepanel.js"]
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class ExtensionSetupService:
|
|
@@ -46,6 +46,13 @@ class ExtensionSetupService:
|
|
|
46
46
|
# Ensure base directories exist
|
|
47
47
|
ensure_directories()
|
|
48
48
|
|
|
49
|
+
# If force, clean out old extension files first
|
|
50
|
+
if force and self.extension_dir.exists():
|
|
51
|
+
import shutil
|
|
52
|
+
|
|
53
|
+
shutil.rmtree(self.extension_dir)
|
|
54
|
+
logger.info(f"Cleaned old extension directory: {self.extension_dir}")
|
|
55
|
+
|
|
49
56
|
# Create extension directory
|
|
50
57
|
self.extension_dir.mkdir(parents=True, exist_ok=True)
|
|
51
58
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|