#!/bin/bash # # CodeVibe Installer # One command to set up CodeVibe for all AI coding agents. # # Usage: # curl -fsSL https://quantiya.ai/codevibe/install.sh | bash # # What this script does: # 1. Checks prerequisites (curl, git) # 2. Installs missing dependencies (Node.js, tmux, Claude Code) # 3. Installs @quantiya/codevibe (wrapper commands for all agents) # 4. Registers the CodeVibe marketplace with Claude Code # 5. Installs the CodeVibe Claude plugin # 6. Attempts sign-in via browser # 7. Prints next steps # set -eo pipefail # Colors PURPLE='\033[0;35m' GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' BOLD='\033[1m' DIM='\033[2m' NC='\033[0m' info() { echo -e "${PURPLE}▸${NC} $1"; } ok() { echo -e "${GREEN}✓${NC} $1"; } warn() { echo -e "${YELLOW}!${NC} $1"; } fail() { echo -e "${RED}✗${NC} $1"; exit 1; } echo "" echo -e "${BOLD}${PURPLE}CodeVibe Installer${NC}" echo -e "${DIM}Control Claude Code, Gemini CLI, and Codex CLI from your phone.${NC}" echo "" # ─── Sudo helper (skip if already root) ────────────────────────────── SUDO="" if [ "$(id -u)" -ne 0 ] && command -v sudo >/dev/null 2>&1; then SUDO="sudo" fi # ─── Detect OS ─────────────────────────────────────────────────────── OS="unknown" ARCH="$(uname -m)" case "$(uname -s)" in Darwin) OS="macos" ;; Linux) OS="linux" ;; *) fail "Unsupported OS: $(uname -s). CodeVibe supports macOS and Linux." ;; esac # Detect Linux package manager LINUX_PKG="" if [ "$OS" = "linux" ]; then if command -v apt-get >/dev/null 2>&1; then LINUX_PKG="apt" elif command -v dnf >/dev/null 2>&1; then LINUX_PKG="dnf" elif command -v yum >/dev/null 2>&1; then LINUX_PKG="yum" elif command -v pacman >/dev/null 2>&1; then LINUX_PKG="pacman" fi fi ok "Detected $OS ($ARCH)" # ─── Prerequisites (curl, git) ─────────────────────────────────────── MISSING_PREREQS="" if ! command -v curl >/dev/null 2>&1; then MISSING_PREREQS="curl" fi if ! command -v git >/dev/null 2>&1; then MISSING_PREREQS="$MISSING_PREREQS git" fi if [ -n "$MISSING_PREREQS" ]; then if [ "$OS" = "macos" ]; then # curl and git come with Xcode Command Line Tools on macOS # xcode-select --install is async (opens a dialog), so we can't wait for it fail "Missing:$MISSING_PREREQS. Install Xcode Command Line Tools first: xcode-select --install" elif [ "$LINUX_PKG" = "apt" ]; then info "Installing missing prerequisites:$MISSING_PREREQS..." $SUDO apt-get update -qq && $SUDO apt-get install -y -qq curl git elif [ "$LINUX_PKG" = "dnf" ]; then $SUDO dnf install -y curl git elif [ "$LINUX_PKG" = "yum" ]; then $SUDO yum install -y curl git elif [ "$LINUX_PKG" = "pacman" ]; then $SUDO pacman -S --noconfirm curl git else fail "Please install curl and git manually, then re-run this script." fi fi # ─── Homebrew (macOS only) ─────────────────────────────────────────── if [ "$OS" = "macos" ] && ! command -v brew >/dev/null 2>&1; then info "Installing Homebrew..." NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Add Homebrew to PATH for this session if [ "$ARCH" = "arm64" ]; then eval "$(/opt/homebrew/bin/brew shellenv)" else eval "$(/usr/local/bin/brew shellenv)" fi ok "Homebrew installed" fi # ─── Node.js + npm ─────────────────────────────────────────────────── install_node() { if [ "$OS" = "macos" ]; then info "Installing Node.js via Homebrew..." brew install node elif [ "$LINUX_PKG" = "apt" ]; then info "Installing Node.js 22.x via NodeSource..." curl -fsSL https://deb.nodesource.com/setup_22.x -o /tmp/nodesource_setup.sh ${SUDO:+$SUDO -E} bash /tmp/nodesource_setup.sh $SUDO apt-get install -y nodejs rm -f /tmp/nodesource_setup.sh elif [ "$LINUX_PKG" = "dnf" ]; then info "Installing Node.js via dnf..." $SUDO dnf install -y nodejs npm elif [ "$LINUX_PKG" = "yum" ]; then info "Installing Node.js 22.x via NodeSource..." curl -fsSL https://rpm.nodesource.com/setup_22.x -o /tmp/nodesource_setup.sh ${SUDO:+$SUDO} bash /tmp/nodesource_setup.sh $SUDO yum install -y nodejs rm -f /tmp/nodesource_setup.sh elif [ "$LINUX_PKG" = "pacman" ]; then info "Installing Node.js via pacman..." $SUDO pacman -S --noconfirm nodejs npm else fail "Could not install Node.js automatically. Install manually from https://nodejs.org" fi } if command -v node >/dev/null 2>&1; then NODE_VERSION=$(node -v | sed 's/v//') NODE_MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1) # Detect version managers if [ -n "$NVM_DIR" ] || command -v nvm >/dev/null 2>&1; then NODE_MGR="nvm" elif command -v fnm >/dev/null 2>&1; then NODE_MGR="fnm" elif command -v asdf >/dev/null 2>&1 && asdf plugin list 2>/dev/null | grep -q nodejs; then NODE_MGR="asdf" else NODE_MGR="" fi if [ "$NODE_MAJOR" -lt 18 ]; then if [ -n "$NODE_MGR" ]; then warn "Node.js $NODE_VERSION is too old (18+ required). Detected version manager: $NODE_MGR." echo "" if [ "$NODE_MGR" = "nvm" ]; then echo " nvm install 22 && nvm use 22" elif [ "$NODE_MGR" = "fnm" ]; then echo " fnm install 22 && fnm use 22" elif [ "$NODE_MGR" = "asdf" ]; then echo " asdf install nodejs 22.0.0 && asdf global nodejs 22.0.0" fi echo "" fail "Re-run this script after switching Node.js version." else warn "Node.js $NODE_VERSION is too old (18+ required)" install_node ok "Node.js $(node -v) installed" fi else ok "Node.js $NODE_VERSION" fi else install_node ok "Node.js $(node -v) installed" fi # ─── tmux ──────────────────────────────────────────────────────────── if command -v tmux >/dev/null 2>&1; then ok "tmux $(tmux -V 2>/dev/null | sed 's/tmux //' || echo '')" else if [ "$OS" = "macos" ]; then info "Installing tmux via Homebrew..." brew install tmux elif [ "$LINUX_PKG" = "apt" ]; then info "Installing tmux via apt..." $SUDO apt-get install -y tmux elif [ "$LINUX_PKG" = "dnf" ]; then info "Installing tmux via dnf..." $SUDO dnf install -y tmux elif [ "$LINUX_PKG" = "yum" ]; then info "Installing tmux via yum..." $SUDO yum install -y tmux elif [ "$LINUX_PKG" = "pacman" ]; then info "Installing tmux via pacman..." $SUDO pacman -S --noconfirm tmux else fail "Could not install tmux automatically. See https://github.com/tmux/tmux/wiki/Installing" fi ok "tmux installed" fi # ─── Claude Code ───────────────────────────────────────────────────── if command -v claude >/dev/null 2>&1; then ok "Claude Code detected" else info "Installing Claude Code..." NPM_SUDO="" if [ "$OS" = "linux" ] && [ "$(id -u)" -ne 0 ]; then NPM_SUDO="$SUDO" fi if $NPM_SUDO npm install -g --force @anthropic-ai/claude-code; then if command -v claude >/dev/null 2>&1; then ok "Claude Code installed" else warn "Claude Code installed but not in PATH — you may need to restart your terminal" fi else warn "Failed to install Claude Code. Install manually: npm install -g @anthropic-ai/claude-code" fi fi echo "" # ─── Install CodeVibe ──────────────────────────────────────────────── info "Installing @quantiya/codevibe..." NPM_SUDO="" if [ "$OS" = "linux" ] && [ "$(id -u)" -ne 0 ]; then NPM_SUDO="$SUDO" fi if $NPM_SUDO npm install -g --force @quantiya/codevibe; then ok "CodeVibe installed" else fail "Failed to install @quantiya/codevibe" fi # Verify commands are available if ! command -v codevibe-claude >/dev/null 2>&1; then NPM_BIN=$(npm prefix -g)/bin warn "codevibe-claude not found in PATH — add npm global bin:" echo "" echo " export PATH=\"$NPM_BIN:\$PATH\"" echo "" echo " Add to your ~/.zshrc or ~/.bashrc, then restart your terminal." echo "" # Add to PATH for this session so login works export PATH="$NPM_BIN:$PATH" fi echo "" # ─── Claude Code Plugin ───────────────────────────────────────────── if command -v claude >/dev/null 2>&1; then info "Setting up Claude Code plugin..." # Register marketplace — check output for real errors vs "already registered" MARKETPLACE_OUTPUT=$(claude plugin marketplace add https://github.com/hendryyeh/quantiya-codevibe-marketplace 2>&1) || true if echo "$MARKETPLACE_OUTPUT" | grep -qi "already\|success"; then ok "Marketplace registered" elif [ -z "$MARKETPLACE_OUTPUT" ]; then ok "Marketplace registered" else warn "Marketplace registration issue: $MARKETPLACE_OUTPUT" fi # Install plugin — check output for real errors vs "already installed" PLUGIN_OUTPUT=$(claude plugin install codevibe-claude@codevibe-marketplace 2>&1) || true if echo "$PLUGIN_OUTPUT" | grep -qi "already\|success"; then ok "Claude plugin installed" elif [ -z "$PLUGIN_OUTPUT" ]; then ok "Claude plugin installed" else warn "Plugin install issue: $PLUGIN_OUTPUT" fi echo "" fi # ─── Detect other agents ───────────────────────────────────────────── if command -v gemini >/dev/null 2>&1; then ok "Gemini CLI detected — codevibe-gemini ready" fi if command -v codex >/dev/null 2>&1; then ok "Codex CLI detected — codevibe-codex ready" fi # ─── Authentication ────────────────────────────────────────────────── # Detect headless/SSH environment (no browser available) IS_HEADLESS=false if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] || [ -n "$SSH_CONNECTION" ]; then IS_HEADLESS=true elif [ -z "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ] && [ "$OS" = "linux" ]; then IS_HEADLESS=true fi echo "" if [ "$IS_HEADLESS" = true ]; then warn "Headless environment detected (SSH or no display) — skipping browser sign-in." echo "" echo " Run this on a machine with a browser to sign in:" echo -e " ${PURPLE}codevibe login${NC}" echo "" else info "Attempting sign-in (opens browser)..." echo -e " ${DIM}Sign in with Apple or Google. This account syncs across all agents and your phone.${NC}" echo "" if command -v codevibe-claude >/dev/null 2>&1; then codevibe-claude login 2>/dev/null || codevibe login 2>/dev/null || { warn "Auto sign-in failed. Run manually: codevibe login" } elif command -v codevibe >/dev/null 2>&1; then codevibe login 2>/dev/null || { warn "Auto sign-in failed. Run manually: codevibe login" } else warn "Could not find login command. After fixing PATH, run: codevibe login" fi fi echo "" # ─── Done ──────────────────────────────────────────────────────────── echo -e "${BOLD}${GREEN}Setup complete!${NC}" echo "" echo " Next steps:" echo "" echo " 1. Download the app on your phone:" echo -e " ${DIM}Android:${NC} https://play.google.com/store/apps/details?id=ai.quantiya.app.codevibe" echo -e " ${DIM}iOS:${NC} https://apps.apple.com/app/id6756500217" echo "" echo " 2. Sign in on your phone with the same account" echo "" echo " 3. Start a session:" echo -e " ${PURPLE}codevibe-claude${NC} # for Claude Code" echo -e " ${PURPLE}codevibe-gemini${NC} # for Gemini CLI" echo -e " ${PURPLE}codevibe-codex${NC} # for Codex CLI" echo "" echo " Your session will appear on your phone automatically." echo "" echo -e " ${PURPLE}https://quantiya.ai/codevibe${NC}" echo ""