예제 소스
오목 Next.js 웹과 VLM 착수 API 연결하기 · 파일 59개
install_omook_launchd.sh
#!/usr/bin/env bash
# Omook 서비스 스택을 launchd에 등록 — Next:3002 + VLM:9299 감시
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
UID_NUM="$(id -u)"
GUI="gui/$UID_NUM"
LA_DIR="$HOME/Library/LaunchAgents"
SUPPORT="${OMOOK_LAUNCHD_SUPPORT:-$HOME/Library/Application Support/Omook}"
LOGS="${OMOOK_LAUNCHD_LOGS:-$HOME/Library/Logs/Omook}"
PY="$ROOT/.venv/bin/python"
if [[ ! -x "$PY" ]]; then
echo "venv python not found: $PY" >&2
exit 1
fi
mkdir -p "$LA_DIR" "$SUPPORT" "$LOGS" "$ROOT/logs/omook_stack_watch"
write_wrapper() {
local name="$1"
shift
local script="$SUPPORT/$name.sh"
local log="$LOGS/${name}.log"
cat >"$script" <<EOF
#!/bin/zsh
set -euo pipefail
ROOT="$ROOT"
PY="$PY"
LOG="$log"
PATH_EXTRA="$HOME/.nvm/versions/node/v24.14.1/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
until [[ -d "\$ROOT" ]]; do
echo "\$(date '+%Y-%m-%d %H:%M:%S') waiting for \$ROOT" >>"\$LOG"
sleep 30
done
mkdir -p "\$(dirname "\$LOG")"
cd "\$ROOT"
export PYTHONUNBUFFERED=1
export TOKENIZERS_PARALLELISM=false
export PORT=3002
export OMOOK_VLM_DEVICE="\${OMOOK_VLM_DEVICE:-mps}"
export PATH="\$PATH_EXTRA"
exec "\$PY" $* >>"\$LOG" 2>&1
EOF
chmod +x "$script"
echo "wrote $script"
}
write_plist() {
local label="$1"
local script="$2"
local out="$LA_DIR/$label.plist"
cat >"$out" <<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>/bin/zsh</string>
<string>${script}</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>15</integer>
<key>StandardOutPath</key>
<string>${LOGS}/${label#com.omook.}.stdout.log</string>
<key>StandardErrorPath</key>
<string>${LOGS}/${label#com.omook.}.stderr.log</string>
</dict>
</plist>
EOF
echo "wrote $out"
}
stop_label() {
local label="$1"
launchctl bootout "$GUI" "$LA_DIR/$label.plist" 2>/dev/null || true
}
start_label() {
local label="$1"
launchctl bootstrap "$GUI" "$LA_DIR/$label.plist"
launchctl enable "$GUI/$label" 2>/dev/null || true
}
echo "== Omook launchd install =="
echo "ROOT=$ROOT"
echo "PY=$PY"
pkill -f 'daemon_omook_stack_watchdog.py' 2>/dev/null || true
sleep 1
write_wrapper run-stack-watchdog scripts/daemon_omook_stack_watchdog.py
write_plist com.omook.stack-watchdog "$SUPPORT/run-stack-watchdog.sh"
stop_label com.omook.stack-watchdog
start_label com.omook.stack-watchdog
sleep 3
echo ""
echo "== launchd status =="
launchctl print "$GUI/com.omook.stack-watchdog" 2>/dev/null | grep -E 'state =|pid =|last exit code' \
|| echo "com.omook.stack-watchdog: not loaded"
echo ""
lsof -nP -iTCP:3002,9299 -sTCP:LISTEN 2>/dev/null || true
echo ""
echo "상태: $ROOT/logs/omook_stack_watch/HEARTBEAT.md"
echo "로그: $ROOT/logs/omook_stack_watch/watchdog.log"
echo " ~/Library/Logs/Omook/"