#!/usr/bin/env bash # launch.sh — maestrod 服务管理 # # ./launch.sh start 启动(若未安装 launchd 则先 build+install) # ./launch.sh stop 停止 # ./launch.sh restart 停止 → build → 启动(发版用) set -euo pipefail LABEL="com.maestro.maestrod" PLIST="${HOME}/Library/LaunchAgents/${LABEL}.plist" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" _is_loaded() { launchctl list 2>/dev/null | grep -qF "${LABEL}" } cmd_stop() { if _is_loaded; then echo "==> 停止 ${LABEL}…" launchctl stop "${LABEL}" 2>/dev/null || true sleep 1 echo " 已停止" else echo "==> 服务未运行,跳过 stop" fi } cmd_start() { if [[ ! -f "${PLIST}" ]]; then echo "==> plist 不存在,先执行 install-daemon.sh…" bash "${SCRIPT_DIR}/scripts/install-daemon.sh" return fi if _is_loaded; then echo "==> 服务已在运行,跳过 start(用 restart 来重启)" return fi echo "==> 启动 ${LABEL}…" launchctl start "${LABEL}" echo " 已启动 · API: http://127.0.0.1:4517" } cmd_restart() { cmd_stop echo "==> 重新构建…" cd "${SCRIPT_DIR}" npm run build echo "==> 启动 ${LABEL}…" if [[ ! -f "${PLIST}" ]]; then bash "${SCRIPT_DIR}/scripts/install-daemon.sh" return fi launchctl start "${LABEL}" echo " 已重启 · API: http://127.0.0.1:4517" } case "${1:-}" in start) cmd_start ;; stop) cmd_stop ;; restart) cmd_restart ;; *) echo "用法: $0 {start|stop|restart}" exit 1 ;; esac