Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
738
vendor/ruvector/npm/packages/ruvbot/scripts/install.sh
vendored
Executable file
738
vendor/ruvector/npm/packages/ruvbot/scripts/install.sh
vendored
Executable file
@@ -0,0 +1,738 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# RuvBot Installer
|
||||
#
|
||||
# Usage:
|
||||
# curl -fsSL https://get.ruvector.dev/ruvbot | bash
|
||||
# curl -fsSL https://raw.githubusercontent.com/ruvnet/ruvector/main/npm/packages/ruvbot/scripts/install.sh | bash
|
||||
#
|
||||
# Options (via environment variables):
|
||||
# RUVBOT_VERSION - Specific version to install (default: latest)
|
||||
# RUVBOT_GLOBAL - Install globally (default: true)
|
||||
# RUVBOT_INIT - Run init after install (default: false)
|
||||
# RUVBOT_CHANNEL - Configure channel: slack, discord, telegram
|
||||
# RUVBOT_DEPLOY - Deploy target: local, docker, cloudrun, k8s
|
||||
# RUVBOT_WIZARD - Run interactive wizard (default: false)
|
||||
#
|
||||
# Examples:
|
||||
# # Basic install
|
||||
# curl -fsSL https://get.ruvector.dev/ruvbot | bash
|
||||
#
|
||||
# # Install specific version
|
||||
# RUVBOT_VERSION=0.1.3 curl -fsSL https://get.ruvector.dev/ruvbot | bash
|
||||
#
|
||||
# # Install and initialize
|
||||
# RUVBOT_INIT=true curl -fsSL https://get.ruvector.dev/ruvbot | bash
|
||||
#
|
||||
# # Install with Slack configuration
|
||||
# RUVBOT_CHANNEL=slack curl -fsSL https://get.ruvector.dev/ruvbot | bash
|
||||
#
|
||||
# # Install and deploy to Cloud Run
|
||||
# RUVBOT_DEPLOY=cloudrun curl -fsSL https://get.ruvector.dev/ruvbot | bash
|
||||
#
|
||||
# # Run full interactive wizard
|
||||
# RUVBOT_WIZARD=true curl -fsSL https://get.ruvector.dev/ruvbot | bash
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
MAGENTA='\033[0;35m'
|
||||
NC='\033[0m' # No Color
|
||||
BOLD='\033[1m'
|
||||
DIM='\033[2m'
|
||||
|
||||
# Configuration
|
||||
RUVBOT_VERSION="${RUVBOT_VERSION:-latest}"
|
||||
RUVBOT_GLOBAL="${RUVBOT_GLOBAL:-true}"
|
||||
RUVBOT_INIT="${RUVBOT_INIT:-false}"
|
||||
RUVBOT_CHANNEL="${RUVBOT_CHANNEL:-}"
|
||||
RUVBOT_DEPLOY="${RUVBOT_DEPLOY:-}"
|
||||
RUVBOT_WIZARD="${RUVBOT_WIZARD:-false}"
|
||||
|
||||
# Feature flags
|
||||
GCLOUD_AVAILABLE=false
|
||||
DOCKER_AVAILABLE=false
|
||||
KUBECTL_AVAILABLE=false
|
||||
|
||||
# Banner
|
||||
print_banner() {
|
||||
echo -e "${CYAN}"
|
||||
echo ' ____ ____ _ '
|
||||
echo ' | _ \ _ ___ _| __ ) ___ | |_ '
|
||||
echo ' | |_) | | | \ \ / / _ \ / _ \| __|'
|
||||
echo ' | _ <| |_| |\ V /| |_) | (_) | |_ '
|
||||
echo ' |_| \_\\__,_| \_/ |____/ \___/ \__|'
|
||||
echo -e "${NC}"
|
||||
echo -e "${BOLD}Enterprise-Grade Self-Learning AI Assistant${NC}"
|
||||
echo -e "${DIM}Military-strength security • 150x faster search • 12+ LLM models${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Logging functions
|
||||
info() { echo -e "${BLUE}ℹ${NC} $1"; }
|
||||
success() { echo -e "${GREEN}✓${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
||||
error() { echo -e "${RED}✗${NC} $1"; exit 1; }
|
||||
step() { echo -e "\n${MAGENTA}▸${NC} ${BOLD}$1${NC}"; }
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies() {
|
||||
step "Checking dependencies"
|
||||
|
||||
# Check Node.js
|
||||
if ! command -v node &> /dev/null; then
|
||||
error "Node.js is required but not installed. Install from https://nodejs.org"
|
||||
fi
|
||||
|
||||
NODE_VERSION=$(node -v | cut -d 'v' -f 2 | cut -d '.' -f 1)
|
||||
if [ "$NODE_VERSION" -lt 18 ]; then
|
||||
error "Node.js 18+ is required. Current: $(node -v)"
|
||||
fi
|
||||
success "Node.js $(node -v)"
|
||||
|
||||
# Check npm
|
||||
if ! command -v npm &> /dev/null; then
|
||||
error "npm is required but not installed"
|
||||
fi
|
||||
success "npm $(npm -v)"
|
||||
|
||||
# Check optional: gcloud
|
||||
if command -v gcloud &> /dev/null; then
|
||||
success "gcloud CLI $(gcloud --version 2>/dev/null | head -1 | awk '{print $4}')"
|
||||
GCLOUD_AVAILABLE=true
|
||||
else
|
||||
echo -e "${DIM} ○ gcloud CLI not found (optional for Cloud Run)${NC}"
|
||||
fi
|
||||
|
||||
# Check optional: docker
|
||||
if command -v docker &> /dev/null; then
|
||||
success "Docker $(docker --version | awk '{print $3}' | tr -d ',')"
|
||||
DOCKER_AVAILABLE=true
|
||||
else
|
||||
echo -e "${DIM} ○ Docker not found (optional for containerization)${NC}"
|
||||
fi
|
||||
|
||||
# Check optional: kubectl
|
||||
if command -v kubectl &> /dev/null; then
|
||||
success "kubectl $(kubectl version --client -o json 2>/dev/null | grep -o '"gitVersion": "[^"]*"' | cut -d'"' -f4)"
|
||||
KUBECTL_AVAILABLE=true
|
||||
else
|
||||
echo -e "${DIM} ○ kubectl not found (optional for Kubernetes)${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Install RuvBot
|
||||
install_ruvbot() {
|
||||
step "Installing RuvBot"
|
||||
|
||||
PACKAGE="ruvbot"
|
||||
if [ "$RUVBOT_VERSION" != "latest" ]; then
|
||||
PACKAGE="ruvbot@$RUVBOT_VERSION"
|
||||
info "Installing version $RUVBOT_VERSION"
|
||||
fi
|
||||
|
||||
if [ "$RUVBOT_GLOBAL" = "true" ]; then
|
||||
npm install -g "$PACKAGE" 2>/dev/null || sudo npm install -g "$PACKAGE"
|
||||
success "RuvBot installed globally"
|
||||
else
|
||||
npm install "$PACKAGE"
|
||||
success "RuvBot installed locally"
|
||||
fi
|
||||
|
||||
# Verify installation
|
||||
if command -v ruvbot &> /dev/null; then
|
||||
INSTALLED_VERSION=$(ruvbot --version 2>/dev/null || echo "unknown")
|
||||
success "RuvBot $INSTALLED_VERSION is ready"
|
||||
else
|
||||
success "RuvBot installed (use 'npx ruvbot' to run)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Install optional dependencies for channels
|
||||
install_channel_deps() {
|
||||
local channel=$1
|
||||
step "Installing $channel dependencies"
|
||||
|
||||
case "$channel" in
|
||||
slack)
|
||||
npm install @slack/bolt @slack/web-api 2>/dev/null
|
||||
success "Slack SDK installed (@slack/bolt, @slack/web-api)"
|
||||
;;
|
||||
discord)
|
||||
npm install discord.js 2>/dev/null
|
||||
success "Discord.js installed"
|
||||
;;
|
||||
telegram)
|
||||
npm install telegraf 2>/dev/null
|
||||
success "Telegraf installed"
|
||||
;;
|
||||
all)
|
||||
npm install @slack/bolt @slack/web-api discord.js telegraf 2>/dev/null
|
||||
success "All channel dependencies installed"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Initialize project
|
||||
init_project() {
|
||||
step "Initializing RuvBot project"
|
||||
|
||||
if [ "$RUVBOT_GLOBAL" = "true" ]; then
|
||||
ruvbot init --yes
|
||||
else
|
||||
npx ruvbot init --yes
|
||||
fi
|
||||
|
||||
success "Project initialized"
|
||||
}
|
||||
|
||||
# Configure channel interactively
|
||||
configure_channel() {
|
||||
local channel=$1
|
||||
|
||||
step "Configuring $channel"
|
||||
|
||||
case "$channel" in
|
||||
slack)
|
||||
echo ""
|
||||
echo " To set up Slack, you'll need credentials from:"
|
||||
echo -e " ${CYAN}https://api.slack.com/apps${NC}"
|
||||
echo ""
|
||||
read -p " SLACK_BOT_TOKEN (xoxb-...): " SLACK_BOT_TOKEN
|
||||
read -p " SLACK_SIGNING_SECRET: " SLACK_SIGNING_SECRET
|
||||
read -p " SLACK_APP_TOKEN (xapp-...): " SLACK_APP_TOKEN
|
||||
|
||||
{
|
||||
echo "SLACK_BOT_TOKEN=$SLACK_BOT_TOKEN"
|
||||
echo "SLACK_SIGNING_SECRET=$SLACK_SIGNING_SECRET"
|
||||
echo "SLACK_APP_TOKEN=$SLACK_APP_TOKEN"
|
||||
} >> .env
|
||||
|
||||
success "Slack configuration saved to .env"
|
||||
;;
|
||||
|
||||
discord)
|
||||
echo ""
|
||||
echo " To set up Discord, you'll need credentials from:"
|
||||
echo -e " ${CYAN}https://discord.com/developers/applications${NC}"
|
||||
echo ""
|
||||
read -p " DISCORD_TOKEN: " DISCORD_TOKEN
|
||||
read -p " DISCORD_CLIENT_ID: " DISCORD_CLIENT_ID
|
||||
read -p " DISCORD_GUILD_ID (optional): " DISCORD_GUILD_ID
|
||||
|
||||
{
|
||||
echo "DISCORD_TOKEN=$DISCORD_TOKEN"
|
||||
echo "DISCORD_CLIENT_ID=$DISCORD_CLIENT_ID"
|
||||
[ -n "$DISCORD_GUILD_ID" ] && echo "DISCORD_GUILD_ID=$DISCORD_GUILD_ID"
|
||||
} >> .env
|
||||
|
||||
success "Discord configuration saved to .env"
|
||||
;;
|
||||
|
||||
telegram)
|
||||
echo ""
|
||||
echo " To set up Telegram, get a token from:"
|
||||
echo -e " ${CYAN}@BotFather${NC} on Telegram"
|
||||
echo ""
|
||||
read -p " TELEGRAM_BOT_TOKEN: " TELEGRAM_BOT_TOKEN
|
||||
|
||||
echo "TELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN" >> .env
|
||||
|
||||
success "Telegram configuration saved to .env"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Deploy to Cloud Run
|
||||
deploy_cloudrun() {
|
||||
step "Deploying to Google Cloud Run"
|
||||
|
||||
if [ "$GCLOUD_AVAILABLE" != "true" ]; then
|
||||
error "gcloud CLI is required. Install from https://cloud.google.com/sdk"
|
||||
fi
|
||||
|
||||
# Check authentication
|
||||
if ! gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null | head -1; then
|
||||
warn "Not authenticated with gcloud"
|
||||
info "Running 'gcloud auth login'..."
|
||||
gcloud auth login
|
||||
fi
|
||||
|
||||
# Get project
|
||||
CURRENT_PROJECT=$(gcloud config get-value project 2>/dev/null || echo "")
|
||||
echo ""
|
||||
read -p " GCP Project ID [$CURRENT_PROJECT]: " PROJECT_ID
|
||||
PROJECT_ID="${PROJECT_ID:-$CURRENT_PROJECT}"
|
||||
|
||||
if [ -z "$PROJECT_ID" ]; then
|
||||
error "Project ID is required"
|
||||
fi
|
||||
|
||||
gcloud config set project "$PROJECT_ID" 2>/dev/null
|
||||
|
||||
# Get region
|
||||
read -p " Region [us-central1]: " REGION
|
||||
REGION="${REGION:-us-central1}"
|
||||
|
||||
# Get service name
|
||||
read -p " Service name [ruvbot]: " SERVICE_NAME
|
||||
SERVICE_NAME="${SERVICE_NAME:-ruvbot}"
|
||||
|
||||
# Get API key
|
||||
echo ""
|
||||
echo " LLM Provider:"
|
||||
echo " 1. OpenRouter (recommended - Gemini, Claude, GPT)"
|
||||
echo " 2. Anthropic (Claude only)"
|
||||
read -p " Choose [1]: " PROVIDER_CHOICE
|
||||
PROVIDER_CHOICE="${PROVIDER_CHOICE:-1}"
|
||||
|
||||
if [ "$PROVIDER_CHOICE" = "1" ]; then
|
||||
read -p " OPENROUTER_API_KEY: " API_KEY
|
||||
ENV_VARS="OPENROUTER_API_KEY=$API_KEY,DEFAULT_MODEL=google/gemini-2.0-flash-001"
|
||||
else
|
||||
read -p " ANTHROPIC_API_KEY: " API_KEY
|
||||
ENV_VARS="ANTHROPIC_API_KEY=$API_KEY"
|
||||
fi
|
||||
|
||||
# Channel configuration
|
||||
echo ""
|
||||
read -p " Configure Slack? [y/N]: " SETUP_SLACK
|
||||
if [[ "$SETUP_SLACK" =~ ^[Yy]$ ]]; then
|
||||
read -p " SLACK_BOT_TOKEN: " SLACK_BOT_TOKEN
|
||||
read -p " SLACK_SIGNING_SECRET: " SLACK_SIGNING_SECRET
|
||||
ENV_VARS="$ENV_VARS,SLACK_BOT_TOKEN=$SLACK_BOT_TOKEN,SLACK_SIGNING_SECRET=$SLACK_SIGNING_SECRET"
|
||||
fi
|
||||
|
||||
read -p " Configure Telegram? [y/N]: " SETUP_TELEGRAM
|
||||
if [[ "$SETUP_TELEGRAM" =~ ^[Yy]$ ]]; then
|
||||
read -p " TELEGRAM_BOT_TOKEN: " TELEGRAM_BOT_TOKEN
|
||||
ENV_VARS="$ENV_VARS,TELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN"
|
||||
fi
|
||||
|
||||
# Enable required APIs
|
||||
info "Enabling required GCP APIs..."
|
||||
gcloud services enable run.googleapis.com containerregistry.googleapis.com cloudbuild.googleapis.com 2>/dev/null
|
||||
|
||||
# Create Dockerfile if it doesn't exist
|
||||
if [ ! -f "Dockerfile" ]; then
|
||||
info "Creating Dockerfile..."
|
||||
cat > Dockerfile << 'DOCKERFILE'
|
||||
FROM node:20-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install curl for health checks
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install ruvbot
|
||||
RUN npm install -g ruvbot
|
||||
|
||||
# Create directories
|
||||
RUN mkdir -p /app/data /app/plugins /app/skills
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:${PORT:-8080}/health || exit 1
|
||||
|
||||
# Start command
|
||||
CMD ["ruvbot", "start", "--port", "8080"]
|
||||
DOCKERFILE
|
||||
success "Dockerfile created"
|
||||
fi
|
||||
|
||||
# Deploy
|
||||
info "Deploying to Cloud Run (this may take a few minutes)..."
|
||||
gcloud run deploy "$SERVICE_NAME" \
|
||||
--source . \
|
||||
--platform managed \
|
||||
--region "$REGION" \
|
||||
--allow-unauthenticated \
|
||||
--port 8080 \
|
||||
--memory 512Mi \
|
||||
--min-instances 0 \
|
||||
--max-instances 10 \
|
||||
--set-env-vars="$ENV_VARS" \
|
||||
--quiet
|
||||
|
||||
# Get URL
|
||||
SERVICE_URL=$(gcloud run services describe "$SERVICE_NAME" --region "$REGION" --format='value(status.url)')
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
||||
echo -e "${BOLD}🚀 RuvBot deployed successfully!${NC}"
|
||||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo -e " URL: ${CYAN}$SERVICE_URL${NC}"
|
||||
echo -e " Health: ${CYAN}$SERVICE_URL/health${NC}"
|
||||
echo -e " API: ${CYAN}$SERVICE_URL/api/status${NC}"
|
||||
echo -e " Models: ${CYAN}$SERVICE_URL/api/models${NC}"
|
||||
echo ""
|
||||
echo " Quick test:"
|
||||
echo -e " ${DIM}curl $SERVICE_URL/health${NC}"
|
||||
echo ""
|
||||
|
||||
# Set Telegram webhook if configured
|
||||
if [ -n "$TELEGRAM_BOT_TOKEN" ]; then
|
||||
WEBHOOK_URL="$SERVICE_URL/telegram/webhook"
|
||||
info "Setting Telegram webhook..."
|
||||
curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/setWebhook?url=$WEBHOOK_URL" > /dev/null
|
||||
success "Telegram webhook: $WEBHOOK_URL"
|
||||
fi
|
||||
}
|
||||
|
||||
# Deploy to Docker
|
||||
deploy_docker() {
|
||||
step "Deploying with Docker"
|
||||
|
||||
if [ "$DOCKER_AVAILABLE" != "true" ]; then
|
||||
error "Docker is required. Install from https://docker.com"
|
||||
fi
|
||||
|
||||
# Get configuration
|
||||
read -p " Container name [ruvbot]: " CONTAINER_NAME
|
||||
CONTAINER_NAME="${CONTAINER_NAME:-ruvbot}"
|
||||
|
||||
read -p " Port [3000]: " PORT
|
||||
PORT="${PORT:-3000}"
|
||||
|
||||
# Create docker-compose.yml
|
||||
info "Creating docker-compose.yml..."
|
||||
cat > docker-compose.yml << COMPOSE
|
||||
version: '3.8'
|
||||
services:
|
||||
ruvbot:
|
||||
image: node:20-slim
|
||||
container_name: $CONTAINER_NAME
|
||||
working_dir: /app
|
||||
command: sh -c "npm install -g ruvbot && ruvbot start --port 3000"
|
||||
ports:
|
||||
- "$PORT:3000"
|
||||
environment:
|
||||
- OPENROUTER_API_KEY=\${OPENROUTER_API_KEY}
|
||||
- ANTHROPIC_API_KEY=\${ANTHROPIC_API_KEY}
|
||||
- SLACK_BOT_TOKEN=\${SLACK_BOT_TOKEN}
|
||||
- SLACK_SIGNING_SECRET=\${SLACK_SIGNING_SECRET}
|
||||
- SLACK_APP_TOKEN=\${SLACK_APP_TOKEN}
|
||||
- DISCORD_TOKEN=\${DISCORD_TOKEN}
|
||||
- DISCORD_CLIENT_ID=\${DISCORD_CLIENT_ID}
|
||||
- TELEGRAM_BOT_TOKEN=\${TELEGRAM_BOT_TOKEN}
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./plugins:/app/plugins
|
||||
- ./skills:/app/skills
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
restart: unless-stopped
|
||||
COMPOSE
|
||||
success "docker-compose.yml created"
|
||||
|
||||
# Start containers
|
||||
read -p " Start containers now? [Y/n]: " START_NOW
|
||||
START_NOW="${START_NOW:-Y}"
|
||||
|
||||
if [[ "$START_NOW" =~ ^[Yy]$ ]]; then
|
||||
info "Starting Docker containers..."
|
||||
docker-compose up -d
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
||||
echo -e "${BOLD}🚀 RuvBot is running!${NC}"
|
||||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo -e " URL: ${CYAN}http://localhost:$PORT${NC}"
|
||||
echo -e " Health: ${CYAN}http://localhost:$PORT/health${NC}"
|
||||
echo -e " Logs: ${DIM}docker-compose logs -f${NC}"
|
||||
echo -e " Stop: ${DIM}docker-compose down${NC}"
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# Deploy to Kubernetes
|
||||
deploy_k8s() {
|
||||
step "Deploying to Kubernetes"
|
||||
|
||||
if [ "$KUBECTL_AVAILABLE" != "true" ]; then
|
||||
error "kubectl is required. Install from https://kubernetes.io/docs/tasks/tools/"
|
||||
fi
|
||||
|
||||
# Get namespace
|
||||
read -p " Namespace [default]: " NAMESPACE
|
||||
NAMESPACE="${NAMESPACE:-default}"
|
||||
|
||||
# Get API key
|
||||
read -p " OPENROUTER_API_KEY: " API_KEY
|
||||
|
||||
info "Creating Kubernetes manifests..."
|
||||
|
||||
mkdir -p k8s
|
||||
|
||||
# Create secret
|
||||
cat > k8s/secret.yaml << SECRET
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: ruvbot-secrets
|
||||
namespace: $NAMESPACE
|
||||
type: Opaque
|
||||
stringData:
|
||||
OPENROUTER_API_KEY: "$API_KEY"
|
||||
DEFAULT_MODEL: "google/gemini-2.0-flash-001"
|
||||
SECRET
|
||||
|
||||
# Create deployment
|
||||
cat > k8s/deployment.yaml << DEPLOYMENT
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ruvbot
|
||||
namespace: $NAMESPACE
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ruvbot
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ruvbot
|
||||
spec:
|
||||
containers:
|
||||
- name: ruvbot
|
||||
image: node:20-slim
|
||||
command: ["sh", "-c", "npm install -g ruvbot && ruvbot start --port 3000"]
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: ruvbot-secrets
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ruvbot
|
||||
namespace: $NAMESPACE
|
||||
spec:
|
||||
selector:
|
||||
app: ruvbot
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 3000
|
||||
type: LoadBalancer
|
||||
DEPLOYMENT
|
||||
|
||||
success "Kubernetes manifests created in k8s/"
|
||||
|
||||
read -p " Apply manifests now? [Y/n]: " APPLY_NOW
|
||||
APPLY_NOW="${APPLY_NOW:-Y}"
|
||||
|
||||
if [[ "$APPLY_NOW" =~ ^[Yy]$ ]]; then
|
||||
kubectl apply -f k8s/
|
||||
|
||||
echo ""
|
||||
success "Kubernetes resources created"
|
||||
echo ""
|
||||
echo " Check status:"
|
||||
echo -e " ${DIM}kubectl get pods -l app=ruvbot${NC}"
|
||||
echo ""
|
||||
echo " Get service URL:"
|
||||
echo -e " ${DIM}kubectl get svc ruvbot${NC}"
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# Deployment wizard
|
||||
deployment_wizard() {
|
||||
step "Deployment Options"
|
||||
echo ""
|
||||
echo " 1. Local (development)"
|
||||
echo " 2. Docker"
|
||||
echo " 3. Google Cloud Run"
|
||||
echo " 4. Kubernetes"
|
||||
echo " 5. Skip deployment"
|
||||
echo ""
|
||||
read -p " Select [5]: " DEPLOY_CHOICE
|
||||
DEPLOY_CHOICE="${DEPLOY_CHOICE:-5}"
|
||||
|
||||
case "$DEPLOY_CHOICE" in
|
||||
1)
|
||||
info "Starting local development server..."
|
||||
if [ "$RUVBOT_GLOBAL" = "true" ]; then
|
||||
ruvbot start --debug
|
||||
else
|
||||
npx ruvbot start --debug
|
||||
fi
|
||||
;;
|
||||
2) deploy_docker ;;
|
||||
3) deploy_cloudrun ;;
|
||||
4) deploy_k8s ;;
|
||||
5) info "Skipping deployment" ;;
|
||||
*) warn "Invalid option, skipping deployment" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Interactive setup wizard
|
||||
run_wizard() {
|
||||
step "RuvBot Setup Wizard"
|
||||
|
||||
# Ensure .env exists
|
||||
touch .env 2>/dev/null || true
|
||||
|
||||
# LLM Provider
|
||||
echo ""
|
||||
echo " ${BOLD}Step 1: LLM Provider${NC}"
|
||||
echo " ───────────────────"
|
||||
echo " 1. OpenRouter (Gemini 2.5, Claude, GPT - recommended)"
|
||||
echo " 2. Anthropic (Claude only)"
|
||||
echo " 3. Skip (configure later)"
|
||||
read -p " Select [1]: " PROVIDER
|
||||
PROVIDER="${PROVIDER:-1}"
|
||||
|
||||
case "$PROVIDER" in
|
||||
1)
|
||||
read -p " OPENROUTER_API_KEY: " OPENROUTER_KEY
|
||||
{
|
||||
echo "OPENROUTER_API_KEY=$OPENROUTER_KEY"
|
||||
echo "DEFAULT_MODEL=google/gemini-2.0-flash-001"
|
||||
} >> .env
|
||||
success "OpenRouter configured"
|
||||
;;
|
||||
2)
|
||||
read -p " ANTHROPIC_API_KEY: " ANTHROPIC_KEY
|
||||
echo "ANTHROPIC_API_KEY=$ANTHROPIC_KEY" >> .env
|
||||
success "Anthropic configured"
|
||||
;;
|
||||
3) info "Skipping LLM configuration" ;;
|
||||
esac
|
||||
|
||||
# Channel Configuration
|
||||
echo ""
|
||||
echo " ${BOLD}Step 2: Channel Integrations${NC}"
|
||||
echo " ────────────────────────────"
|
||||
echo " 1. Slack"
|
||||
echo " 2. Discord"
|
||||
echo " 3. Telegram"
|
||||
echo " 4. All channels"
|
||||
echo " 5. Skip (configure later)"
|
||||
read -p " Select [5]: " CHANNELS
|
||||
CHANNELS="${CHANNELS:-5}"
|
||||
|
||||
case "$CHANNELS" in
|
||||
1)
|
||||
install_channel_deps "slack"
|
||||
configure_channel "slack"
|
||||
;;
|
||||
2)
|
||||
install_channel_deps "discord"
|
||||
configure_channel "discord"
|
||||
;;
|
||||
3)
|
||||
install_channel_deps "telegram"
|
||||
configure_channel "telegram"
|
||||
;;
|
||||
4)
|
||||
install_channel_deps "all"
|
||||
configure_channel "slack"
|
||||
configure_channel "discord"
|
||||
configure_channel "telegram"
|
||||
;;
|
||||
5) info "Skipping channel configuration" ;;
|
||||
esac
|
||||
|
||||
# Deployment
|
||||
echo ""
|
||||
echo " ${BOLD}Step 3: Deployment${NC}"
|
||||
echo " ──────────────────"
|
||||
deployment_wizard
|
||||
}
|
||||
|
||||
# Print next steps
|
||||
print_next_steps() {
|
||||
echo ""
|
||||
echo -e "${BOLD}📚 Quick Start${NC}"
|
||||
echo "═══════════════════════════════════════"
|
||||
echo ""
|
||||
echo " Configure LLM provider:"
|
||||
echo -e " ${CYAN}export OPENROUTER_API_KEY=sk-or-...${NC}"
|
||||
echo ""
|
||||
echo " Run diagnostics:"
|
||||
echo -e " ${CYAN}ruvbot doctor${NC}"
|
||||
echo ""
|
||||
echo " Start the bot:"
|
||||
echo -e " ${CYAN}ruvbot start${NC}"
|
||||
echo ""
|
||||
echo " Channel setup guides:"
|
||||
echo -e " ${CYAN}ruvbot channels setup slack${NC}"
|
||||
echo -e " ${CYAN}ruvbot channels setup discord${NC}"
|
||||
echo -e " ${CYAN}ruvbot channels setup telegram${NC}"
|
||||
echo ""
|
||||
echo " Deploy templates:"
|
||||
echo -e " ${CYAN}ruvbot templates list${NC}"
|
||||
echo -e " ${CYAN}ruvbot deploy code-reviewer${NC}"
|
||||
echo ""
|
||||
echo " Deploy to Cloud Run:"
|
||||
echo -e " ${CYAN}ruvbot deploy cloudrun${NC}"
|
||||
echo ""
|
||||
echo -e "${DIM}Docs: https://github.com/ruvnet/ruvector/tree/main/npm/packages/ruvbot${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main
|
||||
main() {
|
||||
print_banner
|
||||
check_dependencies
|
||||
install_ruvbot
|
||||
|
||||
# Handle channel installation
|
||||
if [ -n "$RUVBOT_CHANNEL" ]; then
|
||||
install_channel_deps "$RUVBOT_CHANNEL"
|
||||
fi
|
||||
|
||||
# Handle initialization
|
||||
if [ "$RUVBOT_INIT" = "true" ]; then
|
||||
init_project
|
||||
fi
|
||||
|
||||
# Handle wizard
|
||||
if [ "$RUVBOT_WIZARD" = "true" ]; then
|
||||
run_wizard
|
||||
elif [ -n "$RUVBOT_DEPLOY" ]; then
|
||||
# Handle deployment without wizard
|
||||
case "$RUVBOT_DEPLOY" in
|
||||
cloudrun|cloud-run|gcp) deploy_cloudrun ;;
|
||||
docker) deploy_docker ;;
|
||||
k8s|kubernetes) deploy_k8s ;;
|
||||
*) warn "Unknown deployment target: $RUVBOT_DEPLOY" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
print_next_steps
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user