#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" ENV_FILE="${ENV_FILE:-${ROOT}/.env}" LABEL="${LABEL:-cn.tkmind.memind-dev}" PLIST="${HOME}/Library/LaunchAgents/${LABEL}.plist" LOG_DIR="${HOME}/Library/Logs" LOG_FILE="${LOG_DIR}/memind-dev.log" DAEMON_SCRIPT="${ROOT}/scripts/dev-core-daemon.mjs" UID_NUM="$(id -u)" GUI="gui/${UID_NUM}" PATH_EXPORT="/opt/homebrew/bin:/opt/homebrew/opt/node@24/bin:/usr/local/bin:/usr/bin:/bin" usage() { cat </dev/null 2>&1; then launchctl bootout "${GUI}/${LABEL}" 2>/dev/null || true sleep 1 fi rm -f "${PLIST}" echo "已卸载 LaunchAgent: ${LABEL}" } if [[ "${1:-}" == "--uninstall" ]]; then uninstall exit 0 fi if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then usage exit 0 fi if [[ ! -f "${ENV_FILE}" ]]; then echo "未找到环境文件: ${ENV_FILE}" >&2 echo "请先 cp .env.example .env 并配置数据库等变量" >&2 exit 1 fi if [[ ! -f "${DAEMON_SCRIPT}" ]]; then echo "未找到 daemon 脚本: ${DAEMON_SCRIPT}" >&2 exit 1 fi set -a # shellcheck disable=SC1090 source "${ENV_FILE}" set +a NODE_BIN="${NODE_BIN:-/opt/homebrew/opt/node@24/bin/node}" if [[ ! -x "${NODE_BIN}" ]]; then NODE_BIN="$(command -v node || true)" fi if [[ ! -x "${NODE_BIN}" ]]; then echo "未找到 node,请安装 Node.js 或设置 NODE_BIN" >&2 exit 1 fi if [[ ! -d "${ROOT}/node_modules" ]]; then echo "未找到 node_modules,请先在 ${ROOT} 执行 pnpm install" >&2 exit 1 fi if [[ ! -d "${ROOT}/ops/node_modules" ]]; then echo "未找到 ops/node_modules,请先在 ${ROOT}/ops 执行 npm install" >&2 exit 1 fi mkdir -p "${HOME}/Library/LaunchAgents" "${LOG_DIR}" cat >"${PLIST}" < Label ${LABEL} ProgramArguments ${NODE_BIN} ${DAEMON_SCRIPT} WorkingDirectory ${ROOT} EnvironmentVariables PATH ${PATH_EXPORT} HOME ${HOME} RunAtLoad KeepAlive ThrottleInterval 15 StandardOutPath ${LOG_FILE} StandardErrorPath ${LOG_FILE} EOF plutil -lint "${PLIST}" if launchctl print "${GUI}/${LABEL}" >/dev/null 2>&1; then launchctl bootout "${GUI}/${LABEL}" 2>/dev/null || true sleep 1 fi launchctl bootstrap "${GUI}" "${PLIST}" launchctl enable "${GUI}/${LABEL}" launchctl kickstart -k "${GUI}/${LABEL}" echo "等待 H5 开发栈就绪..." portal_port="${H5_PORT:-8081}" vite_port="${VITE_PORT:-5173}" ready=0 for _ in $(seq 1 90); do if curl -sf "http://127.0.0.1:${portal_port}/auth/status" >/dev/null 2>&1 \ && curl -sf "http://127.0.0.1:${vite_port}/" >/dev/null 2>&1; then ready=1 break fi sleep 1 done echo "" echo "=== Memind 本地开发栈 (LaunchAgent) ===" launchctl list | grep "${LABEL}" || true if [[ "${ready}" -eq 1 ]]; then echo "Portal: http://127.0.0.1:${portal_port}" echo "H5 UI: http://127.0.0.1:${vite_port}/?preview=mindspace" else echo "服务尚未就绪,请查看日志: tail -f ${LOG_FILE}" fi echo "" echo "LaunchAgent: ${PLIST}" echo "Log file: ${LOG_FILE}" echo "" echo "常用命令:" echo " launchctl kickstart -k ${GUI}/${LABEL} # 重启" echo " tail -f ${LOG_FILE} # 看日志" echo " bash scripts/install-memind-dev-launchagent.sh --uninstall"