@dbalabka/chrome-wsl 0.3.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -18
- package/chrome-wsl +301 -11
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
# Chrome Start From WSL Helper for MCP
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
A lightweight shell script that **automates Chrome DevTools MCP setup** from **WSL** by launching **Windows Chrome** with remote debugging enabled and transparently proxying traffic from WSL using `socat`.
|
|
4
|
+
|
|
5
|
+
No Linux Chrome, no gWSL, no manual Windows networking setup.
|
|
6
|
+
|
|
7
|
+
## What It Does
|
|
8
|
+
|
|
9
|
+
* 🤖 Automatically bridges **WSL → Windows Chrome DevTools (9222)** using `socat`
|
|
10
|
+
* ✅ Validates required **Windows portproxy and firewall rules**
|
|
11
|
+
* 🚀 Launches **existing Windows Chrome** with remote debugging and a temporary profile
|
|
12
|
+
* 🧹 Cleans up easily with a stop command and leaves no permanent system changes
|
|
13
|
+
|
|
14
|
+
## Key Features
|
|
15
|
+
|
|
16
|
+
* **Fully automated**: one command to get Chrome DevTools MCP working from WSL
|
|
17
|
+
* **Lightweight**: simple, readable shell script
|
|
18
|
+
* **Uses your existing Windows Chrome** — no Linux Chrome or gWSL required
|
|
19
|
+
* **Clean & reversible**: minimal system changes, easy to uninstall
|
|
14
20
|
|
|
15
21
|
## Prerequisites
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
|
|
23
|
+
* Windows Chrome already installed
|
|
24
|
+
* WSL environment
|
|
25
|
+
* The script will install one small dependency (`socat`) automatically for port proxying
|
|
26
|
+
|
|
19
27
|
|
|
20
28
|
## Usage
|
|
21
29
|
|
|
@@ -35,6 +43,8 @@ npx @dbalabka/chrome-wsl
|
|
|
35
43
|
```
|
|
36
44
|
- Runs directly via npm without cloning; default entrypoint is `chrome-wsl` (matching the package name).
|
|
37
45
|
|
|
46
|
+
> ℹ️️ Note: Must be run from WSL. Docker is supported only for proxying (no Chrome launch).
|
|
47
|
+
|
|
38
48
|
#### Example
|
|
39
49
|
```sh
|
|
40
50
|
❯ npx @dbalabka/chrome-wsl
|
|
@@ -64,10 +74,14 @@ Then run:
|
|
|
64
74
|
chrome-wsl --uninstall
|
|
65
75
|
```
|
|
66
76
|
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
- Chrome
|
|
70
|
-
|
|
77
|
+
## Docker
|
|
78
|
+
|
|
79
|
+
`chrome-wsl` can also take care of starting a proxy inside the Docker container and allow to access the MCP server from localhost. It helps to use the same Chrome DevTools MCP configuration for agents running inside the docker container as well as outside.
|
|
80
|
+
```shell
|
|
81
|
+
npx @dbalabka/chrome-wsl --container=<name>
|
|
82
|
+
npx @dbalabka/chrome-wsl --stop --container=<name>
|
|
83
|
+
npx @dbalabka/chrome-wsl --uninstall --container=<name>
|
|
84
|
+
```
|
|
71
85
|
|
|
72
86
|
## Chrome DevTools MCP configuration for agents
|
|
73
87
|
|
|
@@ -83,5 +97,13 @@ args = ["-y", "chrome-devtools-mcp@latest", "--browser-url=http://127.0.0.1:9222
|
|
|
83
97
|
startup_timeout_sec = 20.0
|
|
84
98
|
```
|
|
85
99
|
|
|
100
|
+
To run Codex inside the container and use the same MCP configuration and authorisation token, mount the Codex configuration folder inside the docker container using the following docker composer settings:
|
|
101
|
+
```shell
|
|
102
|
+
services:
|
|
103
|
+
app:
|
|
104
|
+
volumes:
|
|
105
|
+
- ~/.codex:/home/vscode/.codex
|
|
106
|
+
```
|
|
107
|
+
|
|
86
108
|
## License
|
|
87
109
|
MIT License. See `LICENSE` for details.
|
package/chrome-wsl
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Compatible with bash and zsh.
|
|
3
|
+
PACKAGE_VERSION="0.4.0"
|
|
3
4
|
set -e
|
|
4
5
|
set -u
|
|
5
6
|
if command -v setopt >/dev/null 2>&1; then
|
|
@@ -12,15 +13,25 @@ PORT=9222
|
|
|
12
13
|
WINDOWS_CHROME_PATH='C:\Program Files\Google\Chrome\Application\chrome.exe'
|
|
13
14
|
FIREWALL_RULE_NAME='Chrome Remote Debug'
|
|
14
15
|
PID_FILE="/tmp/start-chrome-wsl.pids"
|
|
16
|
+
HOST_IP=""
|
|
17
|
+
BROWSER_VERSION=""
|
|
15
18
|
OK_MARK="✅"
|
|
19
|
+
WARN_MARK="❗"
|
|
16
20
|
ERR_MARK="❌"
|
|
17
21
|
|
|
18
22
|
ok() {
|
|
19
|
-
|
|
23
|
+
local prefix="${CONTAINER_LABEL:+[${CONTAINER_LABEL}] }"
|
|
24
|
+
echo "${OK_MARK} ${prefix}$*"
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
err() {
|
|
23
|
-
|
|
28
|
+
local prefix="${CONTAINER_LABEL:+[${CONTAINER_LABEL}] }"
|
|
29
|
+
echo "${ERR_MARK} ${prefix}$*" >&2
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
warn() {
|
|
33
|
+
local prefix="${CONTAINER_LABEL:+[${CONTAINER_LABEL}] }"
|
|
34
|
+
echo "${WARN_MARK} ${prefix}$*" >&2
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
set_pid() {
|
|
@@ -63,6 +74,66 @@ stop_socat() {
|
|
|
63
74
|
fi
|
|
64
75
|
}
|
|
65
76
|
|
|
77
|
+
debug_socat_info() {
|
|
78
|
+
echo "socat status:"
|
|
79
|
+
if command -v socat >/dev/null 2>&1; then
|
|
80
|
+
echo " version: $(socat -V 2>&1 | head -n 1)"
|
|
81
|
+
else
|
|
82
|
+
echo " version: not installed"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
local pattern="socat TCP-LISTEN:${PORT},fork,reuseaddr"
|
|
86
|
+
if pgrep -af "$pattern" >/dev/null 2>&1; then
|
|
87
|
+
pgrep -af "$pattern" | while read -r line; do
|
|
88
|
+
echo " process: ${line}"
|
|
89
|
+
done
|
|
90
|
+
else
|
|
91
|
+
echo " process: not running"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
local socat_pid
|
|
95
|
+
socat_pid=$(get_pid "SOCAT_PID")
|
|
96
|
+
if [[ -n "${socat_pid:-}" ]]; then
|
|
97
|
+
echo " tracked pid: ${socat_pid}"
|
|
98
|
+
else
|
|
99
|
+
echo " tracked pid: none"
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
if [[ -f /tmp/socat-9222.log ]]; then
|
|
103
|
+
echo " log: /tmp/socat-9222.log"
|
|
104
|
+
else
|
|
105
|
+
echo " log: not found"
|
|
106
|
+
fi
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
debug_linux_listeners() {
|
|
110
|
+
echo "Linux listeners on port ${PORT}:"
|
|
111
|
+
if command -v ss >/dev/null 2>&1; then
|
|
112
|
+
if ss -lntp 2>/dev/null | awk -v port=":${PORT}" '$0 ~ port {print " " $0}' | head -n 50; then
|
|
113
|
+
return 0
|
|
114
|
+
fi
|
|
115
|
+
fi
|
|
116
|
+
if command -v lsof >/dev/null 2>&1; then
|
|
117
|
+
if lsof -nP -iTCP:"${PORT}" -sTCP:LISTEN 2>/dev/null | awk 'NR==1 {print " " $0; next} {print " " $0}'; then
|
|
118
|
+
return 0
|
|
119
|
+
fi
|
|
120
|
+
fi
|
|
121
|
+
echo " unavailable (no permissions or tools)"
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
debug_windows_listeners() {
|
|
125
|
+
echo "Windows listeners on port ${PORT}:"
|
|
126
|
+
run_powershell "netstat -ano | Select-String -Pattern \"LISTENING\" | Select-String -Pattern \":${PORT}\" | ForEach-Object { \" \" + \$_.Line }"
|
|
127
|
+
run_powershell "if (-not (netstat -ano | Select-String -Pattern \"LISTENING\" | Select-String -Pattern \":${PORT}\")) { Write-Output ' none' }"
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
debug_windows_rules() {
|
|
131
|
+
echo "Portproxy rules for port ${PORT}:"
|
|
132
|
+
run_powershell "\$lines = netsh interface portproxy show all | Select-String -SimpleMatch '${PORT}' | ForEach-Object { \$_.Line }; if (\$lines) { \$lines } else { ' none' }"
|
|
133
|
+
echo "Firewall rules for port ${PORT}:"
|
|
134
|
+
run_powershell "\$port='${PORT}'; \$rules = Get-NetFirewallRule -ErrorAction SilentlyContinue | Where-Object { \$filter = Get-NetFirewallPortFilter -AssociatedNetFirewallRule \$_ -ErrorAction SilentlyContinue; \$filter -and (\$filter.LocalPort -contains \$port) }; if (\$rules) { \$rules | ForEach-Object { \" {0} enabled={1} direction={2} action={3} profile={4}\" -f \$_.DisplayName, \$_.Enabled, \$_.Direction, \$_.Action, \$_.Profile } } else { ' none' }"
|
|
135
|
+
}
|
|
136
|
+
|
|
66
137
|
run_powershell() {
|
|
67
138
|
# Runs a PowerShell command from WSL. If RUN_AS_ADMIN=1, invoke via Start-Process -Verb RunAs
|
|
68
139
|
# and capture output through a temp script/output file to mirror direct execution.
|
|
@@ -90,13 +161,25 @@ run_powershell() {
|
|
|
90
161
|
fi
|
|
91
162
|
}
|
|
92
163
|
|
|
164
|
+
CONFIRM_MARK="❔"
|
|
93
165
|
confirm() {
|
|
94
166
|
local prompt=$1
|
|
95
167
|
local reply
|
|
96
|
-
|
|
168
|
+
local prefix="${CONTAINER_LABEL:+[${CONTAINER_LABEL}] }"
|
|
169
|
+
if [[ -r /dev/tty ]]; then
|
|
170
|
+
read -r -p "${CONFIRM_MARK} ${prefix}${prompt} [y/N] " reply </dev/tty
|
|
171
|
+
else
|
|
172
|
+
read -r -p "${CONFIRM_MARK} ${prefix}${prompt} [y/N] " reply
|
|
173
|
+
fi
|
|
97
174
|
[[ "${reply}" =~ ^[Yy]$ ]]
|
|
98
175
|
}
|
|
99
176
|
|
|
177
|
+
version_suffix() {
|
|
178
|
+
if [[ -n "${BROWSER_VERSION:-}" ]]; then
|
|
179
|
+
printf " (Chrome %s)" "$BROWSER_VERSION"
|
|
180
|
+
fi
|
|
181
|
+
}
|
|
182
|
+
|
|
100
183
|
chrome_running() {
|
|
101
184
|
run_powershell "if (Get-Process -Name chrome -ErrorAction SilentlyContinue) { exit 0 } else { exit 1 }"
|
|
102
185
|
}
|
|
@@ -118,6 +201,46 @@ port_listening_info() {
|
|
|
118
201
|
run_powershell "\$conns = Get-NetTCPConnection -LocalPort ${PORT} -ErrorAction SilentlyContinue | Select-Object -Property LocalAddress,LocalPort,RemoteAddress,RemotePort,State,OwningProcess; foreach (\$c in \$conns) { \$p = Get-Process -Id \$c.OwningProcess -ErrorAction SilentlyContinue; \$name = if (\$p) { \$p.Name } else { 'unknown' }; Write-Output (\"{0}:{1} owner={2} pid={3} state={4}\" -f \$c.LocalAddress, \$c.LocalPort, \$name, \$c.OwningProcess, \$c.State) }"
|
|
119
202
|
}
|
|
120
203
|
|
|
204
|
+
get_browser_version() {
|
|
205
|
+
local host_ip=${1:-$HOST_IP}
|
|
206
|
+
[[ -z "${host_ip:-}" ]] && return 0
|
|
207
|
+
curl -s "http://${host_ip}:${PORT}/json/version" \
|
|
208
|
+
| sed -n "s/.*\"Browser\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p" \
|
|
209
|
+
| head -n 1
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
get_protocol_version() {
|
|
213
|
+
local host_ip=${1:-$HOST_IP}
|
|
214
|
+
[[ -z "${host_ip:-}" ]] && return 0
|
|
215
|
+
curl -s "http://${host_ip}:${PORT}/json/version" \
|
|
216
|
+
| sed -n "s/.*\"Protocol-Version\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p" \
|
|
217
|
+
| head -n 1
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
check_devtools_access_wsl() {
|
|
221
|
+
local url_local="http://127.0.0.1:${PORT}/json/version"
|
|
222
|
+
local url_host="http://${HOST_IP}:${PORT}/json/version"
|
|
223
|
+
local json browser protocol
|
|
224
|
+
|
|
225
|
+
json=$(curl -s --max-time 2 "$url_local" || true)
|
|
226
|
+
if [[ -z "${json:-}" ]]; then
|
|
227
|
+
warn "Chrome DevTools not reachable at ${url_local} from WSL."
|
|
228
|
+
json=$(curl -s --max-time 2 "$url_host" || true)
|
|
229
|
+
if [[ -z "${json:-}" ]]; then
|
|
230
|
+
err "Chrome DevTools not reachable at ${url_host} from WSL."
|
|
231
|
+
return 1
|
|
232
|
+
fi
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
browser=$(echo "$json" | sed -n "s/.*\"Browser\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p" | head -n 1)
|
|
236
|
+
protocol=$(echo "$json" | sed -n "s/.*\"Protocol-Version\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p" | head -n 1)
|
|
237
|
+
if [[ -n "${browser:-}" || -n "${protocol:-}" ]]; then
|
|
238
|
+
ok "DevTools reachable from WSL: ${browser:-unknown} (Protocol ${protocol:-unknown})."
|
|
239
|
+
else
|
|
240
|
+
warn "DevTools reachable from WSL, but version info was not parsed."
|
|
241
|
+
fi
|
|
242
|
+
}
|
|
243
|
+
|
|
121
244
|
get_wsl_host_ip() {
|
|
122
245
|
local host_ip
|
|
123
246
|
host_ip=$(ip route | awk '/^default via / {print $3; exit}')
|
|
@@ -132,12 +255,38 @@ check_portproxy() {
|
|
|
132
255
|
local host_ip=$1
|
|
133
256
|
local output regex
|
|
134
257
|
output=$(run_powershell "netsh interface portproxy show all" | tr -d '\r')
|
|
135
|
-
|
|
258
|
+
|
|
259
|
+
echo "$output" | awk 'NF>=4 && $2 ~ /^[0-9]+$/ {print $1, $2, $3, $4}' | while read -r listen_addr listen_port connect_addr connect_port; do
|
|
260
|
+
if [[ "$listen_port" == "$PORT" && "$listen_addr" != "$host_ip" ]]; then
|
|
261
|
+
if confirm "Remove portproxy ${listen_addr}:${listen_port} -> ${connect_addr}:${connect_port} (conflicts with ${host_ip}:${PORT})?"; then
|
|
262
|
+
if RUN_AS_ADMIN=1 run_powershell "netsh interface portproxy delete v4tov4 listenaddress=${listen_addr} listenport=${listen_port}"; then
|
|
263
|
+
ok "Removed conflicting portproxy ${listen_addr}:${listen_port}."
|
|
264
|
+
else
|
|
265
|
+
warn "Failed to remove conflicting portproxy ${listen_addr}:${listen_port}."
|
|
266
|
+
fi
|
|
267
|
+
else
|
|
268
|
+
warn "Keeping conflicting portproxy ${listen_addr}:${listen_port}."
|
|
269
|
+
fi
|
|
270
|
+
fi
|
|
271
|
+
done
|
|
272
|
+
|
|
273
|
+
output=$(run_powershell "netsh interface portproxy show all" | tr -d '\r')
|
|
274
|
+
regex="${host_ip//./\.}[[:space:]]+${PORT}[[:space:]]+127\.0\.0\.1[[:space:]]+${PORT}"
|
|
136
275
|
if echo "$output" | grep -Eq "$regex"; then
|
|
137
276
|
ok "Portproxy ${host_ip}:${PORT} -> 127.0.0.1:${PORT} is configured."
|
|
138
277
|
return 0
|
|
139
278
|
fi
|
|
140
279
|
|
|
280
|
+
warn "Portproxy on ${host_ip}:${PORT} is missing; attempting to create it (may prompt for admin)."
|
|
281
|
+
if RUN_AS_ADMIN=1 run_powershell "netsh interface portproxy add v4tov4 listenaddress=${host_ip} listenport=${PORT} connectaddress=127.0.0.1 connectport=${PORT}"; then
|
|
282
|
+
output=$(run_powershell "netsh interface portproxy show all" | tr -d '
|
|
283
|
+
')
|
|
284
|
+
if echo "$output" | grep -Eq "$regex"; then
|
|
285
|
+
ok "Created portproxy ${host_ip}:${PORT} -> 127.0.0.1:${PORT}."
|
|
286
|
+
return 0
|
|
287
|
+
fi
|
|
288
|
+
fi
|
|
289
|
+
|
|
141
290
|
cat <<EOF
|
|
142
291
|
${ERR_MARK} Portproxy on ${host_ip}:${PORT} is missing.
|
|
143
292
|
Run this in an **admin PowerShell** window:
|
|
@@ -154,7 +303,7 @@ check_firewall_rule() {
|
|
|
154
303
|
return 0
|
|
155
304
|
fi
|
|
156
305
|
|
|
157
|
-
|
|
306
|
+
warn "Firewall rule \"${FIREWALL_RULE_NAME}\" is missing; attempting to create it (may prompt for admin)."
|
|
158
307
|
if RUN_AS_ADMIN=1 run_powershell "New-NetFirewallRule -DisplayName \"${FIREWALL_RULE_NAME}\" -Direction Inbound -LocalPort ${PORT} -Protocol TCP -Action Allow" \
|
|
159
308
|
&& run_powershell "${rule_check_cmd}"; then
|
|
160
309
|
ok "Created firewall rule \"${FIREWALL_RULE_NAME}\"."
|
|
@@ -209,13 +358,40 @@ uninstall_socat() {
|
|
|
209
358
|
fi
|
|
210
359
|
}
|
|
211
360
|
|
|
361
|
+
# Remove portproxy entry
|
|
362
|
+
uninstall_portproxy() {
|
|
363
|
+
local host_ip=${1:-$HOST_IP}
|
|
364
|
+
if [[ -z "${host_ip:-}" ]]; then
|
|
365
|
+
host_ip=$(get_wsl_host_ip)
|
|
366
|
+
fi
|
|
367
|
+
local output regex
|
|
368
|
+
output=$(run_powershell "netsh interface portproxy show all" | tr -d '\r')
|
|
369
|
+
regex="${host_ip//./\\.}[[:space:]]+${PORT}[[:space:]]+127\\.0\\.0\\.1[[:space:]]+${PORT}"
|
|
370
|
+
if ! echo "$output" | grep -Eq "$regex"; then
|
|
371
|
+
ok "Portproxy ${host_ip}:${PORT} is already absent."
|
|
372
|
+
return 0
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
if ! confirm "Remove portproxy ${host_ip}:${PORT} -> 127.0.0.1:${PORT}?"; then
|
|
376
|
+
ok "Skipped portproxy removal."
|
|
377
|
+
return 0
|
|
378
|
+
fi
|
|
379
|
+
|
|
380
|
+
if RUN_AS_ADMIN=1 run_powershell "netsh interface portproxy delete v4tov4 listenaddress=${host_ip} listenport=${PORT}" \
|
|
381
|
+
&& ! (run_powershell "netsh interface portproxy show all" | tr -d '\r' | grep -Eq "$regex"); then
|
|
382
|
+
ok "Removed portproxy ${host_ip}:${PORT} -> 127.0.0.1:${PORT}."
|
|
383
|
+
else
|
|
384
|
+
err "Failed to remove portproxy ${host_ip}:${PORT}."
|
|
385
|
+
fi
|
|
386
|
+
}
|
|
387
|
+
|
|
212
388
|
ensure_socat() {
|
|
213
389
|
if command -v socat >/dev/null 2>&1; then
|
|
214
390
|
ok "socat is already installed."
|
|
215
391
|
return 0
|
|
216
392
|
fi
|
|
217
393
|
|
|
218
|
-
|
|
394
|
+
warn "socat not found. Installing via apt..."
|
|
219
395
|
sudo apt-get update
|
|
220
396
|
sudo apt-get install -y socat
|
|
221
397
|
}
|
|
@@ -232,6 +408,40 @@ start_socat() {
|
|
|
232
408
|
ok "Started socat (logging to /tmp/socat-9222.log)."
|
|
233
409
|
}
|
|
234
410
|
|
|
411
|
+
is_docker() {
|
|
412
|
+
[[ -f /.dockerenv ]] && return 0
|
|
413
|
+
grep -qaE 'docker|containerd|kubepods' /proc/1/cgroup 2>/dev/null
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
container_exec() {
|
|
417
|
+
local container=$1; shift
|
|
418
|
+
local script_path
|
|
419
|
+
script_path=$(readlink -f "$0")
|
|
420
|
+
ensure_docker
|
|
421
|
+
local tty_flag="-i"
|
|
422
|
+
if [ -t 0 ]; then
|
|
423
|
+
tty_flag="-it"
|
|
424
|
+
fi
|
|
425
|
+
if ! cat "$script_path" | docker exec -i "${container}" sh -c "cat > /tmp/chrome-wsl.sh"; then
|
|
426
|
+
err "Failed to copy script into container ${container}."
|
|
427
|
+
exit 1
|
|
428
|
+
fi
|
|
429
|
+
local inner_cmd="CONTAINER_LABEL=${container} chmod +x /tmp/chrome-wsl.sh && CONTAINER_LABEL=${container} /tmp/chrome-wsl.sh $*"
|
|
430
|
+
docker exec ${tty_flag} "${container}" sh -lc "${inner_cmd}"
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
get_docker_host_ip() {
|
|
434
|
+
getent hosts host.docker.internal 2>/dev/null | awk '{print $1; exit}'
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
ensure_docker() {
|
|
438
|
+
if command -v docker >/dev/null 2>&1; then
|
|
439
|
+
return 0
|
|
440
|
+
fi
|
|
441
|
+
err "Docker CLI is required for --container."
|
|
442
|
+
exit 1
|
|
443
|
+
}
|
|
444
|
+
|
|
235
445
|
stop_chrome() {
|
|
236
446
|
local chrome_pid
|
|
237
447
|
chrome_pid=$(get_pid "CHROME_PID")
|
|
@@ -280,28 +490,108 @@ start_chrome() {
|
|
|
280
490
|
fi
|
|
281
491
|
}
|
|
282
492
|
|
|
493
|
+
ensure_wsl() {
|
|
494
|
+
if grep -qEi 'Microsoft|WSL' /proc/version >/dev/null 2>&1; then
|
|
495
|
+
return 0
|
|
496
|
+
fi
|
|
497
|
+
err "This tool must be run inside WSL; exiting."
|
|
498
|
+
exit 1
|
|
499
|
+
}
|
|
500
|
+
|
|
283
501
|
main() {
|
|
284
|
-
|
|
502
|
+
local container="" uninstall_flag=0 stop_flag=0 debug_flag=0
|
|
503
|
+
for arg in "$@"; do
|
|
504
|
+
case "$arg" in
|
|
505
|
+
--container=*) container=${arg#*=} ;;
|
|
506
|
+
--uninstall) uninstall_flag=1 ;;
|
|
507
|
+
--stop) stop_flag=1 ;;
|
|
508
|
+
--debug) debug_flag=1 ;;
|
|
509
|
+
esac
|
|
510
|
+
done
|
|
511
|
+
|
|
512
|
+
if [[ "${1-}" == "--version" || "${1-}" == "-V" ]]; then
|
|
513
|
+
echo "chrome-wsl ${PACKAGE_VERSION:-unknown}"
|
|
514
|
+
exit 0
|
|
515
|
+
fi
|
|
516
|
+
|
|
517
|
+
if is_docker && [[ -n "$container" ]]; then
|
|
518
|
+
err "--container is only supported when running in WSL, not inside Docker."
|
|
519
|
+
exit 1
|
|
520
|
+
fi
|
|
521
|
+
|
|
522
|
+
if is_docker; then
|
|
523
|
+
if [[ $debug_flag -eq 1 ]]; then
|
|
524
|
+
debug_socat_info
|
|
525
|
+
exit 0
|
|
526
|
+
fi
|
|
527
|
+
|
|
528
|
+
if [[ $uninstall_flag -eq 1 ]]; then
|
|
529
|
+
uninstall_socat
|
|
530
|
+
exit 0
|
|
531
|
+
fi
|
|
532
|
+
|
|
533
|
+
if [[ $stop_flag -eq 1 ]]; then
|
|
534
|
+
stop_socat
|
|
535
|
+
exit 0
|
|
536
|
+
fi
|
|
537
|
+
|
|
538
|
+
HOST_IP=$(get_docker_host_ip)
|
|
539
|
+
if [[ -z "${HOST_IP:-}" ]]; then
|
|
540
|
+
err "Could not resolve host.docker.internal inside Docker."
|
|
541
|
+
exit 1
|
|
542
|
+
fi
|
|
543
|
+
|
|
544
|
+
ensure_socat
|
|
545
|
+
start_socat "$HOST_IP"
|
|
546
|
+
exit 0
|
|
547
|
+
fi
|
|
548
|
+
|
|
549
|
+
ensure_wsl
|
|
550
|
+
|
|
551
|
+
if [[ $debug_flag -eq 1 ]]; then
|
|
552
|
+
debug_windows_rules
|
|
553
|
+
debug_windows_listeners
|
|
554
|
+
debug_linux_listeners
|
|
555
|
+
debug_socat_info
|
|
556
|
+
if [[ -n "$container" ]]; then
|
|
557
|
+
container_exec "$container" --debug
|
|
558
|
+
fi
|
|
559
|
+
exit 0
|
|
560
|
+
fi
|
|
561
|
+
|
|
562
|
+
if [[ $uninstall_flag -eq 1 ]]; then
|
|
563
|
+
uninstall_portproxy
|
|
285
564
|
uninstall_firewall_rule
|
|
286
565
|
uninstall_socat
|
|
566
|
+
if [[ -n "$container" ]]; then
|
|
567
|
+
container_exec "$container" --uninstall
|
|
568
|
+
fi
|
|
287
569
|
exit 0
|
|
288
570
|
fi
|
|
289
571
|
|
|
290
|
-
if [[
|
|
572
|
+
if [[ $stop_flag -eq 1 ]]; then
|
|
291
573
|
stop_chrome
|
|
292
574
|
stop_socat
|
|
575
|
+
if [[ -n "$container" ]]; then
|
|
576
|
+
container_exec "$container" --stop
|
|
577
|
+
fi
|
|
293
578
|
exit 0
|
|
294
579
|
fi
|
|
295
580
|
|
|
296
|
-
|
|
297
|
-
host_ip
|
|
581
|
+
HOST_IP=$(get_wsl_host_ip)
|
|
582
|
+
local host_ip="$HOST_IP"
|
|
298
583
|
ok "Detected Windows host IP: ${host_ip}"
|
|
299
584
|
|
|
300
585
|
check_portproxy "$host_ip" || exit 1
|
|
301
586
|
check_firewall_rule || exit 1
|
|
587
|
+
start_chrome
|
|
302
588
|
ensure_socat
|
|
303
589
|
start_socat "$host_ip"
|
|
304
|
-
|
|
590
|
+
check_devtools_access_wsl || true
|
|
591
|
+
|
|
592
|
+
if [[ -n "$container" ]]; then
|
|
593
|
+
container_exec "$container"
|
|
594
|
+
fi
|
|
305
595
|
}
|
|
306
596
|
|
|
307
597
|
main "$@"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbalabka/chrome-wsl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "WSL helper to start Windows Chrome with remote debugging and socat port forwarding.",
|
|
5
5
|
"bin": "./chrome-wsl",
|
|
6
6
|
"files": [
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|