commit 13e6b18536bf75ec66bee2574a4c7100eb834343 Author: Azat Date: Mon Feb 2 22:25:32 2026 +0100 Initial supervisor skill with auto-discovery diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..edb628a --- /dev/null +++ b/SKILL.md @@ -0,0 +1,65 @@ +--- +name: supervisor +description: Process manager for running multiple skills concurrently +metadata: + version: "1.0.0" + vibestack: + main: true +--- + +# Supervisor Skill + +Runs multiple skills as managed processes using [supervisord](http://supervisord.org/). + +## Features + +- Auto-discovers skills with `run.sh` scripts +- Manages process lifecycle (start, stop, restart) +- Log aggregation +- Process health monitoring +- Web UI for process management (optional) + +## Auto-Discovery + +On startup, supervisor scans `/skills/*/scripts/run.sh` and creates a program entry for each skill that has a `run.sh` script. + +Skills can opt-out by setting `SUPERVISOR_SKIP=true` in their environment or by not having a `run.sh` script. + +## Configuration + +### Environment Variables + +| Variable | Description | Default | +|----------|-------------|---------| +| `SUPERVISOR_HTTP_PORT` | Web UI port (0 = disabled) | `9001` | +| `SUPERVISOR_USER` | Web UI username | `admin` | +| `SUPERVISOR_PASSWORD` | Web UI password | `admin` | +| `SUPERVISOR_LOG_DIR` | Log directory | `/var/log/supervisor` | + +### Per-Skill Configuration + +Skills can provide a `.supervisor.conf` file in their directory to customize their process: + +```ini +[program:my-skill] +priority=100 +autostart=true +autorestart=true +startsecs=5 +``` + +## Usage + +Supervisor is typically the `main: true` skill that orchestrates other skills: + +```bash +SKILL_URLS="https://git.../supervisor https://git.../caddy https://git.../ttyd" +MAIN_SKILL="supervisor" +``` + +## Web UI + +Access at `http://localhost:9001` to: +- View process status +- Start/stop/restart processes +- View logs diff --git a/scripts/autorun.sh b/scripts/autorun.sh new file mode 100644 index 0000000..4bc12ed --- /dev/null +++ b/scripts/autorun.sh @@ -0,0 +1,131 @@ +#!/bin/bash +set -e + +SKILLS_DIR="${SKILLS_DIR:-/skills}" +SUPERVISOR_LOG_DIR="${SUPERVISOR_LOG_DIR:-/var/log/supervisor}" +SUPERVISOR_HTTP_PORT="${SUPERVISOR_HTTP_PORT:-9001}" +SUPERVISOR_USER="${SUPERVISOR_USER:-admin}" +SUPERVISOR_PASSWORD="${SUPERVISOR_PASSWORD:-admin}" + +# Idempotent supervisord installation +install_supervisor() { + if command -v supervisord &>/dev/null; then + echo "supervisord already installed: $(supervisord --version)" + return 0 + fi + + echo "Installing supervisord..." + apt-get update + apt-get install -y supervisor + + echo "supervisord installed: $(supervisord --version)" +} + +# Setup directories +setup_dirs() { + mkdir -p "$SUPERVISOR_LOG_DIR" + mkdir -p /etc/supervisor/conf.d + echo "Log directory: $SUPERVISOR_LOG_DIR" +} + +# Generate base supervisord.conf +generate_base_config() { + cat > /etc/supervisor/supervisord.conf << EOF +[supervisord] +nodaemon=true +logfile=$SUPERVISOR_LOG_DIR/supervisord.log +pidfile=/var/run/supervisord.pid +childlogdir=$SUPERVISOR_LOG_DIR +user=root + +[unix_http_server] +file=/var/run/supervisor.sock +chmod=0700 + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock + +EOF + + # Add HTTP server if port > 0 + if [ "$SUPERVISOR_HTTP_PORT" -gt 0 ]; then + cat >> /etc/supervisor/supervisord.conf << EOF +[inet_http_server] +port=*:$SUPERVISOR_HTTP_PORT +username=$SUPERVISOR_USER +password=$SUPERVISOR_PASSWORD + +EOF + echo "Web UI enabled on port $SUPERVISOR_HTTP_PORT" + fi + + # Include conf.d + cat >> /etc/supervisor/supervisord.conf << EOF +[include] +files=/etc/supervisor/conf.d/*.conf +EOF + + echo "Base config written to /etc/supervisor/supervisord.conf" +} + +# Auto-discover skills with run.sh and generate program configs +discover_skills() { + echo "Discovering skills..." + + local priority=100 + + for skill_dir in "$SKILLS_DIR"/*/; do + local skill_name=$(basename "$skill_dir") + local run_script="$skill_dir/scripts/run.sh" + local custom_conf="$skill_dir/.supervisor.conf" + + # Skip self + if [ "$skill_name" = "supervisor" ]; then + continue + fi + + # Skip if no run.sh + if [ ! -x "$run_script" ]; then + echo " $skill_name: no run.sh, skipping" + continue + fi + + echo " $skill_name: found run.sh" + + # Use custom config if provided + if [ -f "$custom_conf" ]; then + cp "$custom_conf" "/etc/supervisor/conf.d/${skill_name}.conf" + echo " Using custom config" + else + # Generate default config + cat > "/etc/supervisor/conf.d/${skill_name}.conf" << EOF +[program:$skill_name] +command=$run_script +directory=$skill_dir +priority=$priority +autostart=true +autorestart=true +startsecs=3 +startretries=3 +stopwaitsecs=10 +stdout_logfile=$SUPERVISOR_LOG_DIR/${skill_name}.log +stdout_logfile_maxbytes=10MB +stderr_logfile=$SUPERVISOR_LOG_DIR/${skill_name}.err +stderr_logfile_maxbytes=10MB +EOF + echo " Generated default config (priority=$priority)" + fi + + priority=$((priority + 10)) + done +} + +install_supervisor +setup_dirs +generate_base_config +discover_skills + +echo "Supervisor setup complete" diff --git a/scripts/run.sh b/scripts/run.sh new file mode 100644 index 0000000..39dad0d --- /dev/null +++ b/scripts/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -e + +echo "Starting supervisord..." +exec supervisord -c /etc/supervisor/supervisord.conf