Root cause: camoufox-browser@0.1.0 bundles camoufox-js@0.9.3 which downloads a BROKEN alpha binary (v150.0.2-alpha.26, missing libmozglue.dylib) on macOS. The newer camoufox-js@0.11.0 (Jun 4 2026) downloads STABLE builds. Changes: 1. PINNED VERSIONS (constants at top of file): - CAMOUFOX_JS_VERSION = "0.11.0" — for fetching browser binary - CAMOUFOX_BROWSER_VERSION = "0.1.0" — for daemon IPC protocol 2. run_fetch() — uses 'npx --yes camoufox-js@0.11.0 fetch' instead of 'camoufox-browser@latest install' (which called old camoufox-js) 3. Both packages share ~/Library/Caches/camoufox/ — fetch writes correct binary + version.json, daemon reads same cache 4. Removed Docker HTTP transport — no longer needed, daemon works on macOS 5. Removed reqwest dep from gyandoot-agent + gyandoot-browser 6. install.sh updated: uses camoufox-js@0.11.0 fetch + pinned npm package 7. install.sh verifies version.json exists, not just binary Clean build: 0 errors, 0 warnings No Docker dependency. No @latest. Pinned and stable.
340 lines
12 KiB
Bash
Executable File
340 lines
12 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# GyanDoot v2.0 — Cross-platform installer
|
|
# Detects OS, architecture, and installs the gyandoot binary + camofox-browser.
|
|
# For full documentation, visit: https://git.gyannetra.in/gnpl_admin/gyandoot-v2
|
|
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
YELLOW='\033[1;33m'
|
|
RED='\033[0;31m'
|
|
NC='\033[0m'
|
|
|
|
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
|
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|
err() { echo -e "${RED}[ERR]${NC} $*" >&2; exit 1; }
|
|
|
|
detect_architecture() {
|
|
local arch
|
|
arch="$(uname -m)"
|
|
case "$arch" in
|
|
x86_64|amd64) echo "x86_64" ;;
|
|
aarch64|arm64) echo "aarch64" ;;
|
|
*) err "Unsupported architecture: $arch" ;;
|
|
esac
|
|
}
|
|
|
|
detect_os() {
|
|
local os
|
|
os="$(uname -s)"
|
|
case "$os" in
|
|
Linux) echo "linux" ;;
|
|
Darwin) echo "darwin" ;;
|
|
CYGWIN*|MINGW*|MSYS*) echo "windows" ;;
|
|
*) err "Unsupported OS: $os" ;;
|
|
esac
|
|
}
|
|
|
|
# ── WSL Detection ──────────────────────────────────────────────────────────
|
|
# Detect if we're running inside Windows Subsystem for Linux.
|
|
# /proc/version contains "microsoft" or "wsl" (case-insensitive) on WSL.
|
|
detect_wsl() {
|
|
if [ -f /proc/version ] && grep -qiE 'microsoft|wsl' /proc/version 2>/dev/null; then
|
|
return 0 # true — we are in WSL
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# ── Linux System Dependencies ──────────────────────────────────────────────
|
|
# Camoufox (Playwright-based) needs ~30 system libraries on Linux/WSL.
|
|
# Without these, the browser daemon crashes silently with
|
|
# "Failed to connect: No such file or directory (os error 2)".
|
|
# See: https://playwright.dev/docs/troubleshooting#system-dependencies
|
|
CAMOUFOX_LINUX_DEPS=(
|
|
libgtk-3-0
|
|
libnss3
|
|
libnspr4
|
|
libatk1.0-0t64
|
|
libatk-bridge2.0-0t64
|
|
libcups2t64
|
|
libdrm2
|
|
libxkbcommon0
|
|
libxcomposite1
|
|
libxdamage1
|
|
libxfixes3
|
|
libxrandr2
|
|
libgbm1
|
|
libpango-1.0-0
|
|
libcairo2
|
|
libasound2t64
|
|
libxcb-shm0
|
|
libx11-xcb1
|
|
libx11-6
|
|
libxcb1
|
|
libxext6
|
|
libxcursor1
|
|
libxi6
|
|
libfreetype6
|
|
libfontconfig1
|
|
libxshmfence1
|
|
libxrender1
|
|
libdbus-1-3
|
|
)
|
|
|
|
install_rust_if_needed() {
|
|
if ! command -v cargo &>/dev/null; then
|
|
info "Rust toolchain not found. Installing..."
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
|
source "$HOME/.cargo/env"
|
|
ok "Rust installed"
|
|
else
|
|
ok "Rust already installed ($(cargo --version))"
|
|
fi
|
|
}
|
|
|
|
install_node_if_needed() {
|
|
if ! command -v node &>/dev/null; then
|
|
info "Node.js not found. Installing via nvm..."
|
|
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
|
|
[ -s "$HOME/.nvm/nvm.sh" ] && \. "$HOME/.nvm/nvm.sh"
|
|
nvm install 22
|
|
ok "Node.js installed ($(node --version))"
|
|
else
|
|
ok "Node.js already installed ($(node --version))"
|
|
fi
|
|
}
|
|
|
|
# ── Linux System Deps Installer ────────────────────────────────────────────
|
|
install_linux_deps() {
|
|
if [ "$(uname -s)" != "Linux" ]; then
|
|
return 0 # Not Linux, skip
|
|
fi
|
|
|
|
# Check if we're in WSL (Windows Subsystem for Linux)
|
|
if detect_wsl; then
|
|
info "WSL detected. Checking Linux system dependencies..."
|
|
fi
|
|
|
|
# Check which packages are already installed
|
|
local missing=()
|
|
if command -v dpkg-query &>/dev/null; then
|
|
for pkg in "${CAMOUFOX_LINUX_DEPS[@]}"; do
|
|
if ! dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed"; then
|
|
# Handle libasound2 vs libasound2t64 and similar t64 variants
|
|
# Try without 't64' suffix as fallback
|
|
local alt_pkg="${pkg%t64}"
|
|
if [ "$alt_pkg" != "$pkg" ] && dpkg-query -W -f='${Status}' "$alt_pkg" 2>/dev/null | grep -q "install ok installed"; then
|
|
continue # alt version is already installed
|
|
fi
|
|
missing+=("$pkg")
|
|
fi
|
|
done
|
|
else
|
|
# Can't check, just try to install all
|
|
missing=("${CAMOUFOX_LINUX_DEPS[@]}")
|
|
fi
|
|
|
|
if [ ${#missing[@]} -eq 0 ]; then
|
|
info "All Linux system dependencies already installed"
|
|
return 0
|
|
fi
|
|
|
|
info "Installing ${#missing[@]} missing Linux system dependencies..."
|
|
if command -v apt-get &>/dev/null; then
|
|
if command -v sudo &>/dev/null; then
|
|
sudo apt-get update -qq 2>/dev/null || true
|
|
sudo apt-get install -y -qq "${missing[@]}" 2>/dev/null || {
|
|
# If some packages failed, retry with auto-detected alternatives
|
|
warn "Some packages had issues. Retrying with apt --fix..."
|
|
sudo apt-get --fix-broken install -y -qq 2>/dev/null || true
|
|
# Try installing without t64 variants as fallback
|
|
local fallback=()
|
|
for pkg in "${missing[@]}"; do
|
|
local alt="${pkg%t64}"
|
|
if [ "$alt" != "$pkg" ]; then
|
|
fallback+=("$alt")
|
|
fi
|
|
done
|
|
if [ ${#fallback[@]} -gt 0 ]; then
|
|
sudo apt-get install -y -qq "${fallback[@]}" 2>/dev/null || true
|
|
fi
|
|
}
|
|
else
|
|
apt-get update -qq 2>/dev/null || true
|
|
apt-get install -y -qq "${missing[@]}" 2>/dev/null || true
|
|
fi
|
|
ok "Linux system dependencies installed"
|
|
elif command -v dnf &>/dev/null; then
|
|
info "Detected dnf package manager"
|
|
sudo dnf install -y nss nspr atk at-spi2-atk cups-libs libdrm libXcomposite \
|
|
libXdamage libXrandr mesa-libgbm pango alsa-lib libxkbcommon libxcb \
|
|
libX11-xcb libX11 libXext libXcursor libXfixes libXi gtk3 cairo-gobject 2>/dev/null || true
|
|
ok "Linux system dependencies installed"
|
|
elif command -v yum &>/dev/null; then
|
|
info "Detected yum package manager"
|
|
sudo yum install -y nss nspr atk at-spi2-atk cups-libs libdrm libXcomposite \
|
|
libXdamage libXrandr mesa-libgbm pango alsa-lib libxkbcommon 2>/dev/null || true
|
|
ok "Linux system dependencies installed"
|
|
else
|
|
warn "No supported package manager (apt-get/dnf/yum). You may need to install system dependencies manually."
|
|
warn "Required packages: ${CAMOUFOX_LINUX_DEPS[*]}"
|
|
fi
|
|
}
|
|
|
|
install_camofox_browser() {
|
|
info "Installing camofox-browser (anti-detection browser)..."
|
|
|
|
# Step 1: Install Linux system dependencies (needed by Playwright/Camoufox)
|
|
install_linux_deps
|
|
|
|
# Step 2: Install the npm package
|
|
if command -v npx &>/dev/null || command -v npm &>/dev/null; then
|
|
info "Installing npm package..."
|
|
npm install -g camoufox-browser@0.1.0 2>&1 | tail -3
|
|
|
|
info "Downloading Camoufox browser binary (this may take a while, ~662MB)..."
|
|
npx camoufox-js@0.11.0 fetch 2>&1 | tail -5
|
|
|
|
# Verify the browser binary was actually downloaded
|
|
if ls ~/.cache/camoufox/camoufox 2>/dev/null; then
|
|
ok "Camoufox browser binary downloaded (~/.cache/camoufox/)"
|
|
else
|
|
warn "Browser binary not found at ~/.cache/camoufox/. May need manual 'npx camoufox-js@0.11.0 fetch'"
|
|
fi
|
|
|
|
ok "Camoufox browser npm package installed"
|
|
elif command -v docker &>/dev/null; then
|
|
info "Installing via Docker..."
|
|
docker run -d --name camoufox -p 9377:9377 \
|
|
-e CAMOUFOX_WS_PORT=9377 \
|
|
--restart unless-stopped \
|
|
ghcr.io/nousresearch/camoufox-browser:latest 2>&1 | tail -3
|
|
ok "Camoufox browser installed (Docker)"
|
|
else
|
|
warn "Neither npm nor docker found. Install manually: npm install -g camoufox-browser@0.1.0"
|
|
fi
|
|
}
|
|
|
|
build_release() {
|
|
local root_dir
|
|
root_dir="$(cd "$(dirname "$0")" && pwd)"
|
|
info "Building GyanDoot v2.0 in release mode..."
|
|
cd "$root_dir"
|
|
if [ ! -f "$root_dir/Cargo.toml" ]; then
|
|
local probe
|
|
probe="$(pwd)"
|
|
while [ "$probe" != "/" ]; do
|
|
if [ -f "$probe/Cargo.toml" ] && grep -q '\[workspace\]' "$probe/Cargo.toml" 2>/dev/null; then
|
|
root_dir="$probe"
|
|
cd "$root_dir"
|
|
info "Found workspace root at $root_dir"
|
|
break
|
|
fi
|
|
probe="$(dirname "$probe")"
|
|
done
|
|
fi
|
|
cargo build --release
|
|
ok "Build complete ($(du -sh target/release/gyandoot | cut -f1))"
|
|
}
|
|
|
|
install_binary() {
|
|
local root_dir
|
|
root_dir="$(cd "$(dirname "$0")" && pwd)"
|
|
local target_dir="$root_dir/target/release"
|
|
local bin_name="gyandoot"
|
|
|
|
if [ ! -f "$target_dir/$bin_name" ]; then
|
|
err "Binary not found at $target_dir/$bin_name"
|
|
fi
|
|
|
|
local install_dir="/usr/local/bin"
|
|
if [ ! -w "$install_dir" ]; then
|
|
info "Need sudo to install to $install_dir"
|
|
sudo cp "$target_dir/$bin_name" "$install_dir/$bin_name"
|
|
sudo chmod +x "$install_dir/$bin_name"
|
|
else
|
|
cp "$target_dir/$bin_name" "$install_dir/$bin_name"
|
|
chmod +x "$install_dir/$bin_name"
|
|
fi
|
|
ok "Installed to $install_dir/$bin_name"
|
|
}
|
|
|
|
print_post_install() {
|
|
echo ""
|
|
ok "GyanDoot v2.0 installed successfully!"
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " Quick Start:"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " gyandoot --help Show all commands"
|
|
echo " gyandoot init Create config"
|
|
echo " gyandoot setup Interactive setup wizard"
|
|
echo " gyandoot run Start interactive agent"
|
|
echo ""
|
|
echo " Browser Tools (anti-detection browsing):"
|
|
echo " gyandoot browser health Check camofox status"
|
|
echo " gyandoot browser search <query>"
|
|
echo " gyandoot browser browse <url>"
|
|
echo ""
|
|
echo " Service Management:"
|
|
echo " gyandoot service install Auto-start on boot"
|
|
echo " gyandoot service remove Remove system service"
|
|
echo " gyandoot service status Check service status"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
if detect_wsl; then
|
|
echo " ⚠️ WSL detected — Node.js must be installed INSIDE WSL."
|
|
echo " (The Windows-side Node.js is not accessible from WSL.)"
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
prompt_service_install() {
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " Optional: Auto-start GyanDoot on Boot?"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " GyanDoot can run as a system service and"
|
|
echo " start automatically when your computer boots."
|
|
echo " This keeps the gateway server running in the background."
|
|
echo ""
|
|
echo " (You can also do this later with: gyandoot service install)"
|
|
echo ""
|
|
read -r -p " Install system service? [y/N]: " response
|
|
}
|
|
|
|
main() {
|
|
local os arch
|
|
os=$(detect_os)
|
|
arch=$(detect_architecture)
|
|
info "Detected: $os / $arch"
|
|
if detect_wsl; then
|
|
info "WSL (Windows Subsystem for Linux) detected — will install Linux dependencies"
|
|
fi
|
|
|
|
install_rust_if_needed
|
|
install_node_if_needed
|
|
install_camofox_browser
|
|
|
|
build_release
|
|
install_binary
|
|
|
|
# Optional: install GyanDoot system service (auto-start on boot)
|
|
prompt_service_install
|
|
case "$response" in
|
|
[yY]|[yY][eE][sS])
|
|
info "Installing GyanDoot system service..."
|
|
gyandoot service install 2>&1 || warn "Service install failed (run 'gyandoot service install' later)"
|
|
;;
|
|
*)
|
|
info "Skipping service install (use 'gyandoot service install' later)"
|
|
;;
|
|
esac
|
|
|
|
print_post_install
|
|
}
|
|
|
|
main "$@" |