junso-browser 0.2.12 → 0.3.0
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 +59 -2
- package/bin/junso-browser.js +11 -1
- package/dist/mcp.js +50 -41
- package/dist/server.js +90 -9
- package/package.json +2 -1
- package/scripts/install.sh +216 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "junso-browser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Standalone CloakBrowser host — runs fingerprinted stealth-Chromium per profile, exposes each over a token-authed CDP gateway + interactive viewport, and ships an optional MCP server so any client gets browser tools with no local browser.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"bin",
|
|
12
12
|
"dist",
|
|
13
|
+
"scripts",
|
|
13
14
|
"README.md"
|
|
14
15
|
],
|
|
15
16
|
"engines": {
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# junso-browser installer — one command installs everything the host needs.
|
|
3
|
+
#
|
|
4
|
+
# curl -fsSL https://raw.githubusercontent.com/<you>/junso-browser/master/scripts/install.sh | bash
|
|
5
|
+
# # or, from a clone: bash scripts/install.sh [flags]
|
|
6
|
+
#
|
|
7
|
+
# Automates DEPLOY.md: Bun → Chromium system libs → the package (both bins) →
|
|
8
|
+
# cloak browser prefetch → token → (optional) systemd service. Idempotent: re-running
|
|
9
|
+
# upgrades/repairs in place. Linux (apt/dnf/yum/pacman/zypper/apk) + macOS.
|
|
10
|
+
#
|
|
11
|
+
# Flags / env (flags win):
|
|
12
|
+
# --version <v> package version to install (default: latest) JB_VERSION
|
|
13
|
+
# --token <t> host token (default: generated) JUNSO_BROWSER_TOKEN
|
|
14
|
+
# --host <h> bind host (default: 127.0.0.1) JUNSO_BROWSER_HOST
|
|
15
|
+
# --port <p> bind port (default: 8790) JUNSO_BROWSER_PORT
|
|
16
|
+
# --public-url <u> CDP URL handed to clients, e.g. ws://IP:8790 JUNSO_BROWSER_PUBLIC_URL
|
|
17
|
+
# --twocaptcha <k> 2captcha key (enables browser_solve_captcha) TWOCAPTCHA_KEY
|
|
18
|
+
# --systemd install + enable a systemd service (needs root/sudo) JB_SYSTEMD=1
|
|
19
|
+
# --service-user <u> user the service runs as (default: current/root) JB_SERVICE_USER
|
|
20
|
+
# --local install from the current checkout instead of npm JB_LOCAL=1
|
|
21
|
+
# --no-cloak skip the ~200MB cloak browser prefetch JB_NO_CLOAK=1
|
|
22
|
+
# --no-libs skip apt/dnf Chromium system libs JB_NO_LIBS=1
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
# ---- defaults / arg parse ------------------------------------------------
|
|
26
|
+
VERSION="${JB_VERSION:-latest}"
|
|
27
|
+
TOKEN="${JUNSO_BROWSER_TOKEN:-}"
|
|
28
|
+
HOST="${JUNSO_BROWSER_HOST:-127.0.0.1}"
|
|
29
|
+
PORT="${JUNSO_BROWSER_PORT:-8790}"
|
|
30
|
+
PUBLIC_URL="${JUNSO_BROWSER_PUBLIC_URL:-}"
|
|
31
|
+
TWOCAPTCHA="${TWOCAPTCHA_KEY:-}"
|
|
32
|
+
DO_SYSTEMD="${JB_SYSTEMD:-0}"
|
|
33
|
+
SERVICE_USER="${JB_SERVICE_USER:-}"
|
|
34
|
+
LOCAL="${JB_LOCAL:-0}"
|
|
35
|
+
NO_CLOAK="${JB_NO_CLOAK:-0}"
|
|
36
|
+
NO_LIBS="${JB_NO_LIBS:-0}"
|
|
37
|
+
NO_INSTALL="${JB_NO_INSTALL:-0}"
|
|
38
|
+
|
|
39
|
+
while [ $# -gt 0 ]; do
|
|
40
|
+
case "$1" in
|
|
41
|
+
--version) VERSION="$2"; shift 2;;
|
|
42
|
+
--token) TOKEN="$2"; shift 2;;
|
|
43
|
+
--host) HOST="$2"; shift 2;;
|
|
44
|
+
--port) PORT="$2"; shift 2;;
|
|
45
|
+
--public-url) PUBLIC_URL="$2"; shift 2;;
|
|
46
|
+
--twocaptcha) TWOCAPTCHA="$2"; shift 2;;
|
|
47
|
+
--systemd) DO_SYSTEMD=1; shift;;
|
|
48
|
+
--service-user) SERVICE_USER="$2"; shift 2;;
|
|
49
|
+
--local) LOCAL=1; shift;;
|
|
50
|
+
--no-install) NO_INSTALL=1; shift;;
|
|
51
|
+
--no-cloak) NO_CLOAK=1; shift;;
|
|
52
|
+
--no-libs) NO_LIBS=1; shift;;
|
|
53
|
+
-h|--help) sed -n '2,30p' "$0"; exit 0;;
|
|
54
|
+
*) echo "unknown flag: $1" >&2; exit 1;;
|
|
55
|
+
esac
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
say() { printf '\033[1;36m[junso-browser]\033[0m %s\n' "$*"; }
|
|
59
|
+
warn() { printf '\033[1;33m[junso-browser]\033[0m %s\n' "$*" >&2; }
|
|
60
|
+
die() { printf '\033[1;31m[junso-browser]\033[0m %s\n' "$*" >&2; exit 1; }
|
|
61
|
+
|
|
62
|
+
SUDO=""
|
|
63
|
+
if [ "$(id -u)" -ne 0 ]; then
|
|
64
|
+
if command -v sudo >/dev/null 2>&1; then SUDO="sudo"; fi
|
|
65
|
+
fi
|
|
66
|
+
OS="$(uname -s)"
|
|
67
|
+
|
|
68
|
+
# ---- 1. Bun --------------------------------------------------------------
|
|
69
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
70
|
+
say "installing Bun…"
|
|
71
|
+
curl -fsSL https://bun.sh/install | bash >/dev/null
|
|
72
|
+
fi
|
|
73
|
+
export BUN_INSTALL="${BUN_INSTALL:-$HOME/.bun}"
|
|
74
|
+
export PATH="$BUN_INSTALL/bin:$PATH"
|
|
75
|
+
command -v bun >/dev/null 2>&1 || die "Bun install failed — see https://bun.sh"
|
|
76
|
+
say "Bun $(bun --version)"
|
|
77
|
+
|
|
78
|
+
# ---- 2. Chromium system libs (Linux) -------------------------------------
|
|
79
|
+
install_libs() {
|
|
80
|
+
[ "$NO_LIBS" = "1" ] && { say "skipping system libs (--no-libs)"; return; }
|
|
81
|
+
[ "$OS" != "Linux" ] && return
|
|
82
|
+
if command -v apt-get >/dev/null 2>&1; then
|
|
83
|
+
say "installing Chromium libs (apt)…"
|
|
84
|
+
$SUDO apt-get update -qq
|
|
85
|
+
$SUDO apt-get install -y -qq \
|
|
86
|
+
libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libgbm1 \
|
|
87
|
+
libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
|
|
88
|
+
libgtk-3-0 libasound2 libpangocairo-1.0-0 libxss1 fonts-liberation ca-certificates >/dev/null
|
|
89
|
+
elif command -v dnf >/dev/null 2>&1; then
|
|
90
|
+
say "installing Chromium libs (dnf)…"
|
|
91
|
+
$SUDO dnf install -y -q nss atk at-spi2-atk cups-libs libdrm mesa-libgbm \
|
|
92
|
+
libxkbcommon libXcomposite libXdamage libXfixes libXrandr gtk3 alsa-lib \
|
|
93
|
+
pango libXScrnSaver liberation-fonts ca-certificates >/dev/null
|
|
94
|
+
elif command -v pacman >/dev/null 2>&1; then
|
|
95
|
+
say "installing Chromium libs (pacman)…"
|
|
96
|
+
$SUDO pacman -Sy --noconfirm --needed nss atk at-spi2-atk cups libdrm mesa \
|
|
97
|
+
libxkbcommon libxcomposite libxdamage libxfixes libxrandr gtk3 alsa-lib \
|
|
98
|
+
pango libxss ttf-liberation ca-certificates >/dev/null
|
|
99
|
+
elif command -v zypper >/dev/null 2>&1; then
|
|
100
|
+
say "installing Chromium libs (zypper)…"
|
|
101
|
+
$SUDO zypper -q install -y mozilla-nss libatk-1_0-0 libcups2 libdrm2 libgbm1 \
|
|
102
|
+
libxkbcommon0 libXcomposite1 libXdamage1 libXfixes3 libXrandr2 gtk3-tools \
|
|
103
|
+
libasound2 libpango-1_0-0 libXss1 liberation-fonts ca-certificates >/dev/null || true
|
|
104
|
+
elif command -v apk >/dev/null 2>&1; then
|
|
105
|
+
say "installing Chromium libs (apk)…"
|
|
106
|
+
$SUDO apk add --no-progress nss atk at-spi2-atk cups-libs libdrm mesa-gbm \
|
|
107
|
+
libxkbcommon libxcomposite libxdamage libxfixes libxrandr gtk+3.0 alsa-lib \
|
|
108
|
+
pango libxscrnsaver ttf-liberation ca-certificates >/dev/null
|
|
109
|
+
else
|
|
110
|
+
warn "no known package manager — install Chromium libs manually (see docs/DEPLOY.md)"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
install_libs
|
|
114
|
+
|
|
115
|
+
# ---- 3. The package (both bins) ------------------------------------------
|
|
116
|
+
if [ "$NO_INSTALL" = "1" ]; then
|
|
117
|
+
say "skipping package install (--no-install; configuring the existing install)"
|
|
118
|
+
elif [ "$LOCAL" = "1" ]; then
|
|
119
|
+
SRC_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
120
|
+
say "installing from local checkout: $SRC_DIR"
|
|
121
|
+
( cd "$SRC_DIR" && bun install >/dev/null && bun run build >/dev/null )
|
|
122
|
+
bun add -g "$SRC_DIR" >/dev/null
|
|
123
|
+
else
|
|
124
|
+
say "installing junso-browser@$VERSION (global)…"
|
|
125
|
+
bun add -g "junso-browser@$VERSION" >/dev/null
|
|
126
|
+
fi
|
|
127
|
+
HOST_BIN="$BUN_INSTALL/bin/junso-browser"
|
|
128
|
+
[ -x "$HOST_BIN" ] || HOST_BIN="$(command -v junso-browser || true)"
|
|
129
|
+
[ -n "$HOST_BIN" ] || die "junso-browser bin not found after install"
|
|
130
|
+
say "installed: $($HOST_BIN version 2>/dev/null || echo '?') ($HOST_BIN)"
|
|
131
|
+
|
|
132
|
+
# ---- 4. Cloak browser prefetch -------------------------------------------
|
|
133
|
+
if [ "$NO_CLOAK" = "1" ]; then
|
|
134
|
+
say "skipping cloak prefetch (--no-cloak; it self-downloads on first launch)"
|
|
135
|
+
else
|
|
136
|
+
say "prefetching cloak stealth-Chromium (~200MB)…"
|
|
137
|
+
bunx cloakbrowser install >/dev/null 2>&1 || warn "cloak prefetch failed — it will self-download on first launch"
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# ---- 5. Token ------------------------------------------------------------
|
|
141
|
+
gen_token() {
|
|
142
|
+
if command -v openssl >/dev/null 2>&1; then openssl rand -hex 24
|
|
143
|
+
else bun -e 'console.log([...crypto.getRandomValues(new Uint8Array(24))].map(b=>b.toString(16).padStart(2,"0")).join(""))'
|
|
144
|
+
fi
|
|
145
|
+
}
|
|
146
|
+
if [ -z "$TOKEN" ]; then
|
|
147
|
+
if [ "$HOST" != "127.0.0.1" ] && [ "$HOST" != "localhost" ]; then
|
|
148
|
+
TOKEN="$(gen_token)"; say "generated token (public host requires one)"
|
|
149
|
+
else
|
|
150
|
+
say "no token (loopback host = open in dev; pass --token to require one)"
|
|
151
|
+
fi
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# ---- 6. systemd service (optional) ---------------------------------------
|
|
155
|
+
if [ "$DO_SYSTEMD" = "1" ]; then
|
|
156
|
+
[ "$OS" = "Linux" ] || die "--systemd is Linux-only"
|
|
157
|
+
command -v systemctl >/dev/null 2>&1 || die "systemd not found"
|
|
158
|
+
[ -n "$TOKEN" ] || { [ "$HOST" = "127.0.0.1" ] || die "a token is required for a non-loopback systemd service"; }
|
|
159
|
+
SVC_USER="${SERVICE_USER:-$(id -un)}"
|
|
160
|
+
SVC_HOME="$(eval echo "~$SVC_USER")"
|
|
161
|
+
UNIT="/etc/systemd/system/junso-browser.service"
|
|
162
|
+
say "writing $UNIT (user=$SVC_USER)…"
|
|
163
|
+
{
|
|
164
|
+
echo "[Unit]"
|
|
165
|
+
echo "Description=junso-browser"
|
|
166
|
+
echo "After=network.target"
|
|
167
|
+
echo ""
|
|
168
|
+
echo "[Service]"
|
|
169
|
+
echo "User=$SVC_USER"
|
|
170
|
+
echo "Environment=HOME=$SVC_HOME"
|
|
171
|
+
echo "Environment=JUNSO_BROWSER_HOST=$HOST"
|
|
172
|
+
echo "Environment=JUNSO_BROWSER_PORT=$PORT"
|
|
173
|
+
[ -n "$TOKEN" ] && echo "Environment=JUNSO_BROWSER_TOKEN=$TOKEN"
|
|
174
|
+
[ -n "$PUBLIC_URL" ] && echo "Environment=JUNSO_BROWSER_PUBLIC_URL=$PUBLIC_URL"
|
|
175
|
+
# NOTE: TWOCAPTCHA_KEY is intentionally NOT written to the host env — the 2captcha key is
|
|
176
|
+
# supplied per-connection by the client (x-twocaptcha-key header), so the secret stays with
|
|
177
|
+
# the connector. The --twocaptcha flag only populates the printed client config below.
|
|
178
|
+
echo "ExecStart=$BUN_INSTALL/bin/bun $HOST_BIN"
|
|
179
|
+
echo "Restart=always"
|
|
180
|
+
echo "RestartSec=2"
|
|
181
|
+
echo ""
|
|
182
|
+
echo "[Install]"
|
|
183
|
+
echo "WantedBy=multi-user.target"
|
|
184
|
+
} | $SUDO tee "$UNIT" >/dev/null
|
|
185
|
+
$SUDO systemctl daemon-reload
|
|
186
|
+
$SUDO systemctl enable --now junso-browser >/dev/null 2>&1 || $SUDO systemctl restart junso-browser
|
|
187
|
+
sleep 2
|
|
188
|
+
say "service started — $($SUDO systemctl is-active junso-browser 2>/dev/null || echo '?')"
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# ---- 7. Done — print how to use ------------------------------------------
|
|
192
|
+
echo
|
|
193
|
+
say "✅ install complete"
|
|
194
|
+
HEALTH_HOST="$HOST"; [ "$HOST" = "0.0.0.0" ] && HEALTH_HOST="127.0.0.1"
|
|
195
|
+
if [ "$DO_SYSTEMD" = "1" ]; then
|
|
196
|
+
echo " health: curl -s http://$HEALTH_HOST:$PORT/health"
|
|
197
|
+
else
|
|
198
|
+
echo " run it: JUNSO_BROWSER_HOST=$HOST JUNSO_BROWSER_PORT=$PORT \\"
|
|
199
|
+
[ -n "$TOKEN" ] && echo " JUNSO_BROWSER_TOKEN=$TOKEN \\"
|
|
200
|
+
[ -n "$PUBLIC_URL" ] && echo " JUNSO_BROWSER_PUBLIC_URL=$PUBLIC_URL \\"
|
|
201
|
+
[ -n "$TWOCAPTCHA" ] && echo " TWOCAPTCHA_KEY=$TWOCAPTCHA \\"
|
|
202
|
+
echo " junso-browser"
|
|
203
|
+
fi
|
|
204
|
+
[ -n "$TOKEN" ] && echo " token: $TOKEN"
|
|
205
|
+
echo
|
|
206
|
+
echo " Add to an MCP client as a URL (HTTP MCP, no local install — needs >=0.3.0):"
|
|
207
|
+
MCP_BASE="${PUBLIC_URL:-http://$HEALTH_HOST:$PORT}"
|
|
208
|
+
# present the http(s) form of the public URL for the /mcp endpoint
|
|
209
|
+
MCP_URL="$(printf '%s' "$MCP_BASE" | sed -e 's#^ws://#http://#' -e 's#^wss://#https://#')"
|
|
210
|
+
# the 2captcha key (if any) is supplied BY THE CONNECTOR via the x-twocaptcha-key header — not stored on the host
|
|
211
|
+
HDRS=""
|
|
212
|
+
[ -n "$TOKEN" ] && HDRS="\"Authorization\": \"Bearer $TOKEN\""
|
|
213
|
+
[ -n "$TWOCAPTCHA" ] && HDRS="$HDRS${HDRS:+, }\"x-twocaptcha-key\": \"$TWOCAPTCHA\""
|
|
214
|
+
echo " { \"type\": \"http\", \"url\": \"$MCP_URL/mcp\"$([ -n "$HDRS" ] && echo ", \"headers\": { $HDRS }") }"
|
|
215
|
+
echo
|
|
216
|
+
echo " Or the stdio MCP on the client: npx -y -p junso-browser junso-browser-mcp"
|