Files
memind/scripts/install-memind-dev-launchagent.sh
T

160 lines
4.0 KiB
Bash
Executable File

#!/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 <<EOF
用法:
bash scripts/install-memind-dev-launchagent.sh # 安装并启动
bash scripts/install-memind-dev-launchagent.sh --uninstall
环境变量:
ROOT 仓库根目录 (默认: ${ROOT})
LABEL LaunchAgent 标识 (默认: ${LABEL})
NODE_BIN node 可执行文件路径
EOF
}
uninstall() {
if launchctl print "${GUI}/${LABEL}" >/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}" <<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>${LABEL}</string>
<key>ProgramArguments</key>
<array>
<string>${NODE_BIN}</string>
<string>${DAEMON_SCRIPT}</string>
</array>
<key>WorkingDirectory</key>
<string>${ROOT}</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>${PATH_EXPORT}</string>
<key>HOME</key>
<string>${HOME}</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>15</integer>
<key>StandardOutPath</key>
<string>${LOG_FILE}</string>
<key>StandardErrorPath</key>
<string>${LOG_FILE}</string>
</dict>
</plist>
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"