313 lines
8.7 KiB
Bash
313 lines
8.7 KiB
Bash
#!/usr/bin/env bash
|
|
# QwenClaw Full Installation Script
|
|
# Works on Linux, macOS, and Windows (Git Bash/WSL)
|
|
#
|
|
# Usage: ./install.sh
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Script directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
echo ""
|
|
echo -e "${CYAN} ____ _ __ _ _ ${NC}"
|
|
echo -e "${CYAN} / ___|_ __ __ _ ___| | __ / _(_) | ___ ${NC}"
|
|
echo -e "${CYAN}| | | '__/ _\` |/ __| |/ /| |_| | |/ _ \ ${NC}"
|
|
echo -e "${CYAN}| |___| | | (_| | (__| < | _| | | __/ ${NC}"
|
|
echo -e "${CYAN} \____|_| \__,_|\___|_|\_\|_| |_|_|\___| ${NC}"
|
|
echo ""
|
|
echo -e "${CYAN}Full Installation Script${NC}"
|
|
echo "========================"
|
|
echo ""
|
|
|
|
# Detect OS
|
|
OS="$(uname -s)"
|
|
case "$OS" in
|
|
Linux*) OS_NAME="Linux";;
|
|
Darwin*) OS_NAME="macOS";;
|
|
MINGW*|MSYS*|CYGWIN*) OS_NAME="Windows";;
|
|
*) OS_NAME="Unknown";;
|
|
esac
|
|
|
|
echo -e "${YELLOW}Detected OS:${NC} $OS_NAME"
|
|
echo ""
|
|
|
|
# Function to check if command exists
|
|
command_exists() {
|
|
command -v "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
# Step 1: Check prerequisites
|
|
echo -e "${YELLOW}[1/6] Checking prerequisites...${NC}"
|
|
|
|
# Check Git
|
|
if ! command_exists git; then
|
|
echo -e "${RED}[ERROR] Git is not installed. Please install Git first.${NC}"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN}[OK]${NC} Git is installed"
|
|
|
|
# Check Bun (install if missing)
|
|
if ! command_exists bun; then
|
|
echo -e "${YELLOW}[INFO]${NC} Bun is not installed. Installing..."
|
|
if [ "$OS_NAME" = "Windows" ]; then
|
|
echo -e "${YELLOW}[INFO]${NC} Please install Bun manually from: https://bun.sh/install"
|
|
echo -e "${YELLOW}[INFO]${NC} Run: powershell -c \"irm bun.sh/install.ps1 | iex\""
|
|
else
|
|
curl -fsSL https://bun.sh/install | bash
|
|
fi
|
|
|
|
# Source bun if installed
|
|
if [ -f "$HOME/.bun/_bun" ]; then
|
|
source "$HOME/.bun/_bun"
|
|
elif [ -f "$HOME/.bun/bin/bun" ]; then
|
|
export PATH="$HOME/.bun/bin:$PATH"
|
|
fi
|
|
|
|
if command_exists bun; then
|
|
echo -e "${GREEN}[OK]${NC} Bun installed successfully"
|
|
else
|
|
echo -e "${RED}[ERROR]${NC} Failed to install Bun. Please install manually.${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo -e "${GREEN}[OK]${NC} Bun is installed (v$(bun --version))"
|
|
fi
|
|
|
|
# Step 2: Install dependencies
|
|
echo ""
|
|
echo -e "${YELLOW}[2/6] Installing dependencies...${NC}"
|
|
bun install
|
|
echo -e "${GREEN}[OK]${NC} Dependencies installed"
|
|
|
|
# Step 3: Create directories
|
|
echo ""
|
|
echo -e "${YELLOW}[3/6] Creating directories...${NC}"
|
|
|
|
if [ "$OS_NAME" = "Windows" ]; then
|
|
HOME_DIR="$USERPROFILE"
|
|
else
|
|
HOME_DIR="$HOME"
|
|
fi
|
|
|
|
QWEN_DIR="$HOME_DIR/.qwen"
|
|
QWENCLAW_DATA_DIR="$QWEN_DIR/qwenclaw"
|
|
|
|
mkdir -p "$QWENCLAW_DATA_DIR/jobs"
|
|
mkdir -p "$QWENCLAW_DATA_DIR/logs"
|
|
mkdir -p "$QWENCLAW_DATA_DIR/inbox/telegram"
|
|
echo -e "${GREEN}[OK]${NC} Directories created"
|
|
|
|
# Step 4: Create default settings
|
|
echo ""
|
|
echo -e "${YELLOW}[4/6] Creating default configuration...${NC}"
|
|
|
|
SETTINGS_FILE="$QWENCLAW_DATA_DIR/settings.json"
|
|
if [ ! -f "$SETTINGS_FILE" ]; then
|
|
cat > "$SETTINGS_FILE" << 'EOF'
|
|
{
|
|
"model": "",
|
|
"api": "",
|
|
"autoStart": true,
|
|
"fallback": {
|
|
"model": "",
|
|
"api": ""
|
|
},
|
|
"timezone": "UTC",
|
|
"timezoneOffsetMinutes": 0,
|
|
"heartbeat": {
|
|
"enabled": false,
|
|
"interval": 15,
|
|
"prompt": "",
|
|
"excludeWindows": []
|
|
},
|
|
"telegram": {
|
|
"token": "",
|
|
"allowedUserIds": []
|
|
},
|
|
"security": {
|
|
"level": "moderate",
|
|
"allowedTools": [],
|
|
"disallowedTools": []
|
|
},
|
|
"web": {
|
|
"enabled": true,
|
|
"host": "127.0.0.1",
|
|
"port": 4632
|
|
}
|
|
}
|
|
EOF
|
|
echo -e "${GREEN}[OK]${NC} Default settings created: $SETTINGS_FILE"
|
|
else
|
|
echo -e "${YELLOW}[INFO]${NC} Settings already exist, skipping"
|
|
fi
|
|
|
|
# Step 5: Set up auto-start
|
|
echo ""
|
|
echo -e "${YELLOW}[5/6] Configuring auto-start...${NC}"
|
|
|
|
if [ "$OS_NAME" = "Windows" ]; then
|
|
# Windows: Create startup shortcut
|
|
STARTUP_FOLDER="$APPDATA\\Microsoft\\Windows\\Start Menu\\Programs\\Startup"
|
|
if [ -d "$STARTUP_FOLDER" ]; then
|
|
# Create a batch file for startup
|
|
STARTUP_BAT="$STARTUP_FOLDER\\QwenClaw Daemon.bat"
|
|
cat > "$STARTUP_BAT" << EOF
|
|
@echo off
|
|
cd /d "$SCRIPT_DIR"
|
|
start /B bun run start --web
|
|
EOF
|
|
echo -e "${GREEN}[OK]${NC} Windows auto-start configured"
|
|
else
|
|
echo -e "${YELLOW}[INFO]${NC} Startup folder not found, skipping auto-start"
|
|
fi
|
|
elif [ "$OS_NAME" = "Linux" ]; then
|
|
# Linux: Create systemd service or desktop autostart
|
|
if command_exists systemctl; then
|
|
# Systemd service
|
|
SERVICE_FILE="/etc/systemd/system/qwenclaw.service"
|
|
if [ -w "/etc/systemd/system" ]; then
|
|
cat > "$SERVICE_FILE" << EOF
|
|
[Unit]
|
|
Description=QwenClaw Daemon
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=$USER
|
|
WorkingDirectory=$SCRIPT_DIR
|
|
ExecStart=$(which bun) run start --web
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
systemctl daemon-reload
|
|
systemctl enable qwenclaw.service
|
|
echo -e "${GREEN}[OK]${NC} Systemd service created and enabled"
|
|
else
|
|
echo -e "${YELLOW}[INFO]${NC} Cannot create systemd service (need sudo)"
|
|
fi
|
|
fi
|
|
|
|
# Desktop autostart (for GUI sessions)
|
|
AUTOSTART_DIR="$HOME/.config/autostart"
|
|
mkdir -p "$AUTOSTART_DIR"
|
|
cat > "$AUTOSTART_DIR/qwenclaw.desktop" << EOF
|
|
[Desktop Entry]
|
|
Type=Application
|
|
Name=QwenClaw Daemon
|
|
Exec=bash -c "cd $SCRIPT_DIR && bun run start --web"
|
|
Hidden=false
|
|
NoDisplay=false
|
|
X-GNOME-Autostart-enabled=true
|
|
EOF
|
|
echo -e "${GREEN}[OK]${NC} Desktop auto-start configured"
|
|
elif [ "$OS_NAME" = "macOS" ]; then
|
|
# macOS: Create LaunchAgent
|
|
LAUNCHAGENT_DIR="$HOME/Library/LaunchAgents"
|
|
mkdir -p "$LAUNCHAGENT_DIR"
|
|
cat > "$LAUNCHAGENT_DIR/com.qwenclaw.daemon.plist" << EOF
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>Label</key>
|
|
<string>com.qwenclaw.daemon</string>
|
|
<key>ProgramArguments</key>
|
|
<array>
|
|
<string>$(which bun)</string>
|
|
<string>run</string>
|
|
<string>start</string>
|
|
<string>--web</string>
|
|
</array>
|
|
<key>WorkingDirectory</key>
|
|
<string>$SCRIPT_DIR</string>
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
<key>KeepAlive</key>
|
|
<true/>
|
|
<key>StandardOutPath</key>
|
|
<string>$QWENCLAW_DATA_DIR/qwenclaw.log</string>
|
|
<key>StandardErrorPath</key>
|
|
<string>$QWENCLAW_DATA_DIR/qwenclaw.err</string>
|
|
</dict>
|
|
</plist>
|
|
EOF
|
|
launchctl load "$LAUNCHAGENT_DIR/com.qwenclaw.daemon.plist" 2>/dev/null || true
|
|
echo -e "${GREEN}[OK]${NC} macOS LaunchAgent configured"
|
|
fi
|
|
|
|
# Step 6: Initialize git (optional, for repo management)
|
|
echo ""
|
|
echo -e "${YELLOW}[6/6] Finalizing installation...${NC}"
|
|
|
|
if [ ! -d ".git" ]; then
|
|
git init
|
|
git checkout -b main 2>/dev/null || true
|
|
echo -e "${GREEN}[OK]${NC} Git repository initialized"
|
|
else
|
|
echo -e "${YELLOW}[INFO]${NC} Git repository already exists"
|
|
fi
|
|
|
|
# Create example job
|
|
EXAMPLE_JOB="$QWENCLAW_DATA_DIR/jobs/example-daily-check.md"
|
|
if [ ! -f "$EXAMPLE_JOB" ]; then
|
|
cat > "$EXAMPLE_JOB" << 'EOF'
|
|
---
|
|
schedule: 0 9 * * *
|
|
recurring: true
|
|
notify: true
|
|
---
|
|
|
|
Good morning! Here's your daily check-in:
|
|
1. What are today's priorities?
|
|
2. Any pending tasks from yesterday?
|
|
3. Weather and calendar summary.
|
|
EOF
|
|
echo -e "${GREEN}[OK]${NC} Example job created"
|
|
fi
|
|
|
|
# Summary
|
|
echo ""
|
|
echo "========================================"
|
|
echo -e "${GREEN} Installation Complete!${NC}"
|
|
echo "========================================"
|
|
echo ""
|
|
echo -e "${CYAN}What's configured:${NC}"
|
|
echo -e " ${GREEN}[OK]${NC} Dependencies installed"
|
|
echo -e " ${GREEN}[OK]${NC} Directories created"
|
|
echo -e " ${GREEN}[OK]${NC} Default settings created"
|
|
echo -e " ${GREEN}[OK]${NC} Auto-start configured"
|
|
echo -e " ${GREEN}[OK]${NC} Example job created"
|
|
echo ""
|
|
echo -e "${CYAN}Quick Start:${NC}"
|
|
echo -e " ${YELLOW}bun run start --web${NC} - Start daemon"
|
|
echo -e " ${YELLOW}bun run status${NC} - Check status"
|
|
echo -e " ${YELLOW}bun run stop${NC} - Stop daemon"
|
|
echo -e " ${YELLOW}bun run send \"hello\"${NC} - Send prompt"
|
|
echo ""
|
|
echo -e "${CYAN}Web Dashboard:${NC}"
|
|
echo -e " ${YELLOW}http://127.0.0.1:4632${NC}"
|
|
echo ""
|
|
echo -e "${CYAN}Configuration:${NC}"
|
|
echo -e " Edit: ${YELLOW}$SETTINGS_FILE${NC}"
|
|
echo -e " Jobs: ${YELLOW}$QWENCLAW_DATA_DIR/jobs/${NC}"
|
|
echo -e " Logs: ${YELLOW}$QWENCLAW_DATA_DIR/logs/${NC}"
|
|
echo ""
|
|
echo -e "${CYAN}Documentation:${NC}"
|
|
echo -e " ${YELLOW}README.md${NC} - Full documentation"
|
|
echo -e " ${YELLOW}QUICKSTART.md${NC} - Quick reference"
|
|
echo ""
|
|
echo -e "The daemon will ${YELLOW}start automatically${NC} when you log in."
|
|
echo ""
|