File size: 6,757 Bytes
6a7089a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | #!/usr/bin/env bash
set -euo pipefail
# Pinchtab Installer for macOS and Linux
# Usage: curl -fsSL https://pinchtab.com/install.sh | bash
BOLD='\033[1m'
ACCENT='\033[38;2;251;191;36m' # yellow #fbbf24
INFO='\033[38;2;136;146;176m' # muted #8892b0
SUCCESS='\033[38;2;0;229;204m' # cyan #00e5cc
ERROR='\033[38;2;230;57;70m' # red #e63946
MUTED='\033[38;2;90;100;128m' # text-muted #5a6480
NC='\033[0m' # No Color
TAGLINE="12MB binary. Zero config. Accessibility-first browser control."
cleanup_tmpfiles() {
local f
for f in "${TMPFILES[@]:-}"; do
rm -rf "$f" 2>/dev/null || true
done
}
trap cleanup_tmpfiles EXIT
TMPFILES=()
LOGFILE=""
mktempfile() {
local f
f="$(mktemp)"
TMPFILES+=("$f")
echo "$f"
}
setup_logfile() {
LOGFILE="$(mktempfile)"
}
ui_info() {
local msg="$*"
echo -e "${MUTED}·${NC} ${msg}"
}
ui_success() {
local msg="$*"
echo -e "${SUCCESS}✓${NC} ${msg}"
}
ui_error() {
local msg="$*"
echo -e "${ERROR}✗${NC} ${msg}"
}
ui_section() {
local title="$1"
echo ""
echo -e "${ACCENT}${BOLD}${title}${NC}"
}
detect_os() {
OS="unknown"
if [[ "$OSTYPE" == "darwin"* ]]; then
OS="macos"
elif [[ "$OSTYPE" == "linux-gnu"* ]] || [[ -n "${WSL_DISTRO_NAME:-}" ]]; then
OS="linux"
fi
if [[ "$OS" == "unknown" ]]; then
ui_error "Unsupported operating system"
echo "This installer supports macOS and Linux (including WSL)."
exit 1
fi
ui_success "Detected: $OS"
}
print_banner() {
echo -e "${ACCENT}${BOLD}"
echo " 🦀 Pinchtab Installer"
echo -e "${NC}${INFO} ${TAGLINE}${NC}"
echo ""
}
check_node() {
if ! command -v node &> /dev/null; then
ui_error "Node.js 18+ is required but not found"
echo "Install from https://nodejs.org or via your package manager"
exit 1
fi
local version
version="$(node -v 2>/dev/null | cut -dv -f2 | cut -d. -f1)"
if [[ -z "$version" || "$version" -lt 18 ]]; then
ui_error "Node.js 18+ is required, but found $(node -v)"
exit 1
fi
ui_success "Node.js $(node -v) found"
}
check_npm() {
if ! command -v npm &> /dev/null; then
ui_error "npm is required but not found"
exit 1
fi
ui_success "npm $(npm -v) found"
}
check_chrome() {
local chrome_found=false
local chrome_path=""
# Check common Chrome/Chromium locations
local candidates=(
"google-chrome"
"google-chrome-stable"
"chromium"
"chromium-browser"
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
"/Applications/Chromium.app/Contents/MacOS/Chromium"
"/usr/bin/google-chrome"
"/usr/bin/google-chrome-stable"
"/usr/bin/chromium"
"/usr/bin/chromium-browser"
)
for candidate in "${candidates[@]}"; do
if command -v "$candidate" &> /dev/null || [[ -f "$candidate" ]]; then
chrome_found=true
chrome_path="$candidate"
break
fi
done
if [[ "$chrome_found" == true ]]; then
ui_success "Chrome/Chromium found: $chrome_path"
else
ui_error "Chrome or Chromium not found"
echo ""
echo "Pinchtab requires Chrome or Chromium to be installed."
echo ""
if [[ "$OS" == "macos" ]]; then
echo "Install Chrome or Chromium:"
echo " • Chrome: https://www.google.com/chrome/"
echo " • Chromium (via Homebrew): brew install chromium"
else
echo "Install Chrome or Chromium:"
echo ""
echo " Debian/Ubuntu/Raspberry Pi:"
echo " sudo apt update && sudo apt install -y chromium-browser"
echo ""
echo " Fedora/RHEL:"
echo " sudo dnf install -y chromium"
echo ""
echo " Arch Linux:"
echo " sudo pacman -S chromium"
echo ""
echo " Or download Chrome: https://www.google.com/chrome/"
fi
echo ""
echo "After installing Chrome/Chromium, run this installer again."
exit 1
fi
}
install_pinchtab() {
ui_section "Installing Pinchtab"
if npm install -g pinchtab > "$LOGFILE" 2>&1; then
ui_success "Pinchtab installed successfully"
return 0
else
local exit_code=$?
ui_error "npm install failed"
echo ""
# Check for permission error
if grep -q "EACCES\|permission denied" "$LOGFILE"; then
echo "This is a permission error. Try one of these:"
echo ""
echo " Option 1: Use nvm (recommended)"
echo " curl https://github.com/nvm-sh/nvm/raw/master/install.sh | bash"
echo " nvm install node"
echo " npm install -g pinchtab"
echo ""
echo " Option 2: Use user prefix (no sudo needed)"
echo " npm install -g --prefix \"\$HOME/.local\" pinchtab"
echo " export PATH=\"\$HOME/.local/bin:\$PATH\" # Add to ~/.bashrc or ~/.zshrc"
echo ""
echo " Option 3: Fix npm permissions globally"
echo " mkdir ~/.npm-global"
echo " npm config set prefix '~/.npm-global'"
echo " export PATH=~/.npm-global/bin:\$PATH # Add to ~/.bashrc or ~/.zshrc"
echo ""
else
echo "Install log:"
cat "$LOGFILE"
fi
exit 1
fi
}
verify_installation() {
if ! command -v pinchtab &> /dev/null; then
ui_error "Pinchtab binary not found in PATH after install"
echo "Try: npm install -g pinchtab"
exit 1
fi
local version
version="$(pinchtab --version 2>/dev/null || echo 'unknown')"
ui_success "Pinchtab ready: $version"
}
show_next_steps() {
ui_section "Next steps"
echo ""
echo " Start the server:"
echo -e " ${MUTED}pinchtab${NC}"
echo ""
echo " In another terminal, test it:"
echo -e " ${MUTED}curl http://localhost:9867/health${NC}"
echo ""
echo " Or navigate & snapshot:"
echo -e " ${MUTED}pinchtab nav https://httpbin.org/html${NC}"
echo -e " ${MUTED}pinchtab snap${NC} (pipe to 'jq .count' if you have jq installed)"
echo ""
echo " Documentation:"
echo -e " ${MUTED}https://pinchtab.com${NC}"
echo ""
}
main() {
print_banner
setup_logfile
detect_os
check_node
check_npm
check_chrome
install_pinchtab
verify_installation
show_next_steps
ui_section "Installation complete!"
echo -e "Run ${ACCENT}${BOLD}pinchtab${NC} to start 🦀"
echo ""
}
main "$@"
|