#!/usr/bin/env bash # Kilo + APAW One-Command Installer for Linux # Usage: curl -fsSL https://git.softuniq.eu/UniqueSoft/APAW/raw/branch/dev/install.sh | bash # OR: ./install.sh set -euo pipefail REPO_URL="https://git.softuniq.eu/UniqueSoft/APAW" INSTALL_DIR="${APAW_DIR:-$HOME/APAW}" VSCODE_EXTENSION="kilocode.kilo-code" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' info() { printf "${BLUE}[INFO]${NC} %s\n" "$*"; } ok() { printf "${GREEN}[OK]${NC} %s\n" "$*"; } warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$*"; } err() { printf "${RED}[ERR]${NC} %s\n" "$*" >&2; } detect_distro() { if [ -f /etc/os-release ]; then . /etc/os-release echo "$ID" else echo "unknown" fi } install_vscode() { if command -v code &>/dev/null || command -v codium &>/dev/null; then ok "VS Code / VSCodium already installed" return 0 fi local dist dist=$(detect_distro) info "Installing VS Code for distro: $dist" export DEBIAN_FRONTEND=noninteractive export NEEDRESTART_MODE=a case "$dist" in ubuntu|debian|pop|mint|elementary|zorin) sudo apt-get update -qq sudo apt-get install -y -qq wget gpg apt-transport-https wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/packages.microsoft.gpg sudo install -D -o root -g root -m 644 /tmp/packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list' sudo apt-get update -qq sudo apt-get install -y -qq code ;; fedora|rhel|centos|rocky|almalinux) sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo' sudo dnf install -y code ;; arch|manjaro|endeavouros) if command -v yay &>/dev/null; then yay -S --noconfirm visual-studio-code-bin elif command -v paru &>/dev/null; then paru -S --noconfirm visual-studio-code-bin else sudo pacman -Sy --noconfirm git base-devel git clone --depth=1 https://aur.archlinux.org/visual-studio-code-bin.git /tmp/vscode-aur (cd /tmp/vscode-aur && makepkg -si --noconfirm) fi ;; alpine) sudo apk add --no-cache curl curl -L -o /tmp/vscode.tar.gz "https://code.visualstudio.com/sha/download?build=stable&os=linux-x64" sudo mkdir -p /usr/share/vscode sudo tar -xzf /tmp/vscode.tar.gz -C /usr/share/vscode --strip-components=1 sudo ln -sf /usr/share/vscode/bin/code /usr/local/bin/code ;; *) warn "Unknown distro, trying snap install..." if command -v snap &>/dev/null; then sudo snap install code --classic else err "Cannot auto-install VS Code on '$dist'. Please install it manually, then re-run this script." exit 1 fi ;; esac ok "VS Code installed" } install_node_bun() { if command -v bun &>/dev/null; then ok "Bun already installed: $(bun --version)" return 0 fi if command -v node &>/dev/null && command -v npm &>/dev/null; then ok "Node.js already installed: $(node --version)" else info "Installing Node.js via NodeSource..." local dist dist=$(detect_distro) case "$dist" in ubuntu|debian|pop|mint) sudo apt-get install -y -qq curl ca-certificates gnupg curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash - sudo apt-get install -y -qq nodejs ;; fedora|rhel|rocky|almalinux) sudo dnf install -y nodejs npm ;; arch|manjaro) sudo pacman -Sy --noconfirm nodejs npm ;; alpine) sudo apk add --no-cache nodejs npm ;; *) warn "Installing Node via n..." curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n | sudo bash -s lts ;; esac fi info "Installing Bun..." curl -fsSL https://bun.sh/install | bash export PATH="$HOME/.bun/bin:$PATH" # Make bun available immediately and persistently if ! grep -q '.bun/bin' ~/.bashrc 2>/dev/null; then echo 'export PATH="$HOME/.bun/bin:$PATH"' >> ~/.bashrc fi if [ -f ~/.profile ] && ! grep -q '.bun/bin' ~/.profile 2>/dev/null; then echo 'export PATH="$HOME/.bun/bin:$PATH"' >> ~/.profile fi if [ -d /etc/profile.d ] && [ "$EUID" -eq 0 ]; then echo 'export PATH="/root/.bun/bin:$PATH"' > /etc/profile.d/bun.sh chmod 644 /etc/profile.d/bun.sh fi ok "Bun installed: $(bun --version)" } install_docker() { if command -v docker &>/dev/null && command -v docker-compose &>/dev/null; then ok "Docker + Docker Compose already installed" return 0 fi info "Installing Docker..." curl -fsSL https://get.docker.com | sh sudo usermod -aG docker "$USER" 2>/dev/null || true ok "Docker installed (re-login may be needed for group permissions)" } install_git() { if command -v git &>/dev/null; then ok "Git already installed: $(git --version)" return 0 fi local dist dist=$(detect_distro) info "Installing Git..." case "$dist" in ubuntu|debian|pop|mint|elementary) sudo apt-get update -qq && sudo apt-get install -y -qq git ;; fedora|rhel|centos|rocky|almalinux) sudo dnf install -y git ;; arch|manjaro) sudo pacman -Sy --noconfirm git ;; alpine) sudo apk add --no-cache git ;; *) err "Cannot auto-install git on '$dist'. Please install manually." exit 1 ;; esac ok "Git installed" } install_vscode_extension() { local bin="" if command -v code &>/dev/null; then bin="code" elif command -v codium &>/dev/null; then bin="codium" else warn "VS Code binary not found, skipping extension install" return 1 fi info "Installing Kilo Code extension ($VSCODE_EXTENSION)..." # 1. Install for current user (no custom --user-data-dir so it lands in standard location) "$bin" --install-extension "$VSCODE_EXTENSION" --force || { warn "Marketplace failed, trying OpenVSX..." "$bin" --install-extension "https://open-vsx.org/extension/kilocode/kilo-code" --force || warn "Extension install failed for current user." } # 2. If root, also install for every regular user with a home directory if [ "$EUID" -eq 0 ]; then local ext_dir="/usr/share/code/resources/app/extensions" [ -d "$ext_dir" ] || ext_dir="/usr/share/vscode/resources/app/extensions" [ -d "$ext_dir" ] || ext_dir="" for user_home in /home/*; do [ -d "$user_home" ] || continue local user_name user_name=$(basename "$user_home") # Only real users with uid >= 1000 local user_uid user_uid=$(id -u "$user_name" 2>/dev/null || echo 0) [ "$user_uid" -ge 1000 ] || continue info "Installing Kilo Code extension for user: $user_name ..." su - "$user_name" -c "$bin --install-extension $VSCODE_EXTENSION --force" || { warn "Marketplace failed for $user_name, trying OpenVSX..." su - "$user_name" -c "$bin --install-extension https://open-vsx.org/extension/kilocode/kilo-code --force" || warn "Extension install failed for $user_name." } done # 3. Try system-wide install (copy into VS Code's bundled extensions) if [ -n "$ext_dir" ] && [ -d "$ext_dir" ]; then local current_user_ext current_user_ext=$(ls -d "$HOME/.vscode/extensions/kilocode.kilo-code-"* 2>/dev/null | head -1) if [ -n "$current_user_ext" ] && [ ! -d "$ext_dir/kilocode.kilo-code" ]; then info "Copying extension to system-wide directory..." cp -r "$current_user_ext" "$ext_dir/" && ok "System-wide extension installed" || warn "System-wide copy failed (permissions)." fi fi fi ok "Kilo Code extension installed" } clone_apaw() { if [ -d "$INSTALL_DIR/.git" ]; then info "APAW repo already exists at $INSTALL_DIR, pulling latest..." (cd "$INSTALL_DIR" && git pull --ff-only) else info "Cloning APAW into $INSTALL_DIR..." git clone "$REPO_URL" "$INSTALL_DIR" fi ok "APAW repo ready at $INSTALL_DIR" } setup_apaw() { info "Setting up APAW dependencies..." cd "$INSTALL_DIR" bun install || npm install if [ ! -f .env ]; then cp .env.example .env 2>/dev/null || true fi ok "APAW dependencies installed" } print_summary() { local dist dist=$(detect_distro) echo "" echo "========================================" echo " Kilo + APAW Installation Complete" echo "========================================" local vscode_ver="N/A" if command -v code &>/dev/null; then vscode_ver=$(code --version 2>/dev/null | head -1 || echo "VS Code") elif command -v codium &>/dev/null; then vscode_ver=$(codium --version 2>/dev/null | head -1 || echo "VSCodium") fi ok "VS Code: $vscode_ver" ok "Kilo Ext: $VSCODE_EXTENSION" if [ "$EUID" -eq 0 ]; then ok "Kilo Users: root + all regular users (/home/*)" fi ok "Node: $(node --version 2>/dev/null || echo 'N/A')" ok "Bun: $(bun --version 2>/dev/null || echo 'N/A')" ok "Docker: $(docker --version 2>/dev/null || echo 'N/A')" ok "Git: $(git --version 2>/dev/null || echo 'N/A')" ok "APAW Path: $INSTALL_DIR" echo "" info "Next steps:" echo " cd $INSTALL_DIR" echo " code ." echo "" if [ "$EUID" -eq 0 ]; then echo " For root GUI sessions, if sandbox errors:" echo " code --no-sandbox ." echo "" fi if [ "$dist" != "unknown" ] && ! id -nG "$USER" | grep -qw docker; then warn "Docker group change requires re-login. Run: newgrp docker" fi } main() { echo "========================================" echo " Kilo + APAW Linux Installer" echo "========================================" echo "" install_git install_node_bun install_docker install_vscode install_vscode_extension clone_apaw setup_apaw print_summary } main "$@"