Combines homeai-character (service status, character profiles, editor) and homeai-desktop (chat with voice I/O) into homeai-dashboard on port 5173. - 4-page sidebar layout: Dashboard, Chat, Characters, Editor - Merged Vite middleware: health checks, service restart, bridge proxy - Bridge upgraded to ThreadingHTTPServer (fixes LAN request queuing) - TTS strips emojis before synthesis - Updated start.sh with new launchd service names - Added preload-models to startup sequence Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
222 lines
6.1 KiB
Bash
Executable File
222 lines
6.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# start.sh — Start all HomeAI services on LINDBLUM
|
|
#
|
|
# Usage:
|
|
# ./start.sh # start everything
|
|
# ./start.sh status # show what's running
|
|
# ./start.sh stop # stop everything
|
|
# ./start.sh restart # stop then start everything
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "${REPO_DIR}/scripts/common.sh"
|
|
|
|
DOCKER_DIR="${HOME}/server/docker"
|
|
|
|
# ─── Service definitions ──────────────────────────────────────────────────────
|
|
|
|
LAUNCHD_SERVICES=(
|
|
com.homeai.ollama
|
|
com.homeai.wyoming-stt
|
|
com.homeai.wyoming-tts
|
|
com.homeai.wyoming-satellite
|
|
com.homeai.openclaw
|
|
com.homeai.openclaw-bridge
|
|
com.homeai.preload-models
|
|
com.homeai.dashboard
|
|
)
|
|
|
|
DOCKER_COMPOSE_DIRS=(
|
|
"${DOCKER_DIR}/open-webui"
|
|
"${DOCKER_DIR}/uptime-kuma"
|
|
"${DOCKER_DIR}/n8n"
|
|
"${DOCKER_DIR}/code-server"
|
|
)
|
|
|
|
# ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
|
|
launchd_running() {
|
|
local label="$1"
|
|
local pid
|
|
pid=$(launchctl list "$label" 2>/dev/null | grep '"PID"' | sed 's/[^0-9]//g' || true)
|
|
[[ -n "$pid" && "$pid" -gt 0 ]] 2>/dev/null
|
|
}
|
|
|
|
start_launchd() {
|
|
local label="$1"
|
|
local plist="${HOME}/Library/LaunchAgents/${label}.plist"
|
|
|
|
if [[ ! -f "$plist" ]]; then
|
|
log_warn "Plist not found: $plist — skipping"
|
|
return
|
|
fi
|
|
|
|
if launchd_running "$label"; then
|
|
log_info "Already running: $label"
|
|
return
|
|
fi
|
|
|
|
log_step "Starting $label"
|
|
# bootstrap loads + starts the agent
|
|
launchctl bootstrap "gui/$(id -u)" "$plist" 2>/dev/null \
|
|
|| launchctl kickstart -k "gui/$(id -u)/$label" 2>/dev/null \
|
|
|| true
|
|
sleep 0.5
|
|
|
|
if launchd_running "$label"; then
|
|
log_success "$label started"
|
|
else
|
|
log_warn "$label may not have started — check logs"
|
|
fi
|
|
}
|
|
|
|
stop_launchd() {
|
|
local label="$1"
|
|
local plist="${HOME}/Library/LaunchAgents/${label}.plist"
|
|
|
|
if [[ ! -f "$plist" ]]; then
|
|
return
|
|
fi
|
|
|
|
if ! launchd_running "$label"; then
|
|
log_info "Already stopped: $label"
|
|
return
|
|
fi
|
|
|
|
log_step "Stopping $label"
|
|
launchctl bootout "gui/$(id -u)/$label" 2>/dev/null || true
|
|
log_success "$label stopped"
|
|
}
|
|
|
|
start_docker_services() {
|
|
ensure_docker_running
|
|
|
|
for dir in "${DOCKER_COMPOSE_DIRS[@]}"; do
|
|
if [[ ! -d "$dir" ]]; then
|
|
log_warn "Docker compose dir not found: $dir — skipping"
|
|
continue
|
|
fi
|
|
|
|
local name
|
|
name=$(basename "$dir")
|
|
log_step "Starting Docker stack: $name"
|
|
docker_compose -f "${dir}/docker-compose.yml" up -d 2>/dev/null \
|
|
|| docker_compose -f "${dir}/compose.yml" up -d 2>/dev/null \
|
|
|| log_warn "No compose file found in $dir"
|
|
done
|
|
}
|
|
|
|
stop_docker_services() {
|
|
for dir in "${DOCKER_COMPOSE_DIRS[@]}"; do
|
|
if [[ ! -d "$dir" ]]; then
|
|
continue
|
|
fi
|
|
|
|
local name
|
|
name=$(basename "$dir")
|
|
log_step "Stopping Docker stack: $name"
|
|
docker_compose -f "${dir}/docker-compose.yml" down 2>/dev/null \
|
|
|| docker_compose -f "${dir}/compose.yml" down 2>/dev/null \
|
|
|| true
|
|
done
|
|
}
|
|
|
|
# ─── Commands ─────────────────────────────────────────────────────────────────
|
|
|
|
do_start() {
|
|
log_section "Starting HomeAI Services"
|
|
|
|
echo ""
|
|
log_info "── LaunchD services ──"
|
|
for svc in "${LAUNCHD_SERVICES[@]}"; do
|
|
start_launchd "$svc"
|
|
done
|
|
|
|
echo ""
|
|
log_info "── Docker services ──"
|
|
start_docker_services
|
|
|
|
echo ""
|
|
log_success "All services started."
|
|
echo ""
|
|
do_status
|
|
}
|
|
|
|
do_stop() {
|
|
log_section "Stopping HomeAI Services"
|
|
|
|
echo ""
|
|
log_info "── LaunchD services ──"
|
|
for svc in "${LAUNCHD_SERVICES[@]}"; do
|
|
stop_launchd "$svc"
|
|
done
|
|
|
|
echo ""
|
|
log_info "── Docker services ──"
|
|
stop_docker_services
|
|
|
|
echo ""
|
|
log_success "All services stopped."
|
|
}
|
|
|
|
do_status() {
|
|
log_section "HomeAI Service Status"
|
|
|
|
# LaunchD services
|
|
printf "\n ${BOLD}%-34s %-10s %s${RESET}\n" "SERVICE" "STATUS" "PID"
|
|
printf " %-34s %-10s %s\n" "─────────────────────────────────" "────────" "─────"
|
|
|
|
for svc in "${LAUNCHD_SERVICES[@]}"; do
|
|
local pid
|
|
pid=$(launchctl list "$svc" 2>/dev/null | grep '"PID"' | sed 's/[^0-9]//g' || true)
|
|
if [[ -n "$pid" && "$pid" -gt 0 ]] 2>/dev/null; then
|
|
printf " ${GREEN}●${RESET} %-32s ${GREEN}%-10s${RESET} %s\n" "$svc" "running" "$pid"
|
|
else
|
|
printf " ${RED}○${RESET} %-32s ${RED}%-10s${RESET} %s\n" "$svc" "stopped" "-"
|
|
fi
|
|
done
|
|
|
|
# Docker services
|
|
echo ""
|
|
local containers=("homeai-open-webui" "homeai-uptime-kuma" "homeai-n8n" "homeai-code-server")
|
|
for c in "${containers[@]}"; do
|
|
local state
|
|
state=$(docker inspect -f '{{.State.Status}}' "$c" 2>/dev/null || echo "not found")
|
|
if [[ "$state" == "running" ]]; then
|
|
printf " ${GREEN}●${RESET} %-32s ${GREEN}%-10s${RESET}\n" "$c" "$state"
|
|
else
|
|
printf " ${RED}○${RESET} %-32s ${RED}%-10s${RESET}\n" "$c" "$state"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
}
|
|
|
|
# ─── Main ─────────────────────────────────────────────────────────────────────
|
|
|
|
main() {
|
|
local cmd="${1:-start}"
|
|
|
|
case "$cmd" in
|
|
start) do_start ;;
|
|
stop) do_stop ;;
|
|
restart) do_stop; echo ""; do_start ;;
|
|
status) do_status ;;
|
|
-h|--help|help)
|
|
echo ""
|
|
echo " Usage: $0 [start|stop|restart|status]"
|
|
echo ""
|
|
echo " Commands:"
|
|
echo " start Start all HomeAI services (default)"
|
|
echo " stop Stop all HomeAI services"
|
|
echo " restart Stop then start all services"
|
|
echo " status Show current service status"
|
|
echo ""
|
|
;;
|
|
*) die "Unknown command: $cmd. Run '$0 help' for usage." ;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|