- Hook handler now loads .env.daemon for proper config (plugin URL/secret, bot user ID) - Hook logs to /tmp/status-watcher.log instead of /dev/null - Added .env.daemon config file (.gitignored - contains tokens) - Added start-daemon.sh convenience script - Plugin mode: mobile fallback updates post message field with formatted markdown - Fixed unbounded lines array in status-watcher (capped at 50) - Added session marker to formatter output for restart recovery - Go plugin: added updatePostMessageForMobile() for dual-render strategy (webapp gets custom React component, mobile gets markdown in message field) Fixes: daemon silently dying, no plugin connection, mobile showing blank posts
79 lines
2.4 KiB
Bash
Executable File
79 lines
2.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# start-daemon.sh — Start the live-status watcher daemon with proper config.
|
|
# This script is the canonical way to start the daemon. It loads env vars,
|
|
# ensures only one instance runs, and redirects logs properly.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
LOG_FILE="${LIVESTATUS_LOG_FILE:-/tmp/status-watcher.log}"
|
|
PID_FILE="${PID_FILE:-/tmp/status-watcher.pid}"
|
|
ENV_FILE="${SCRIPT_DIR}/.env.daemon"
|
|
|
|
# Load .env.daemon if it exists
|
|
if [ -f "$ENV_FILE" ]; then
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "$ENV_FILE"
|
|
set +a
|
|
fi
|
|
|
|
# Required env vars with defaults
|
|
export MM_BOT_TOKEN="${MM_BOT_TOKEN:?MM_BOT_TOKEN is required}"
|
|
export MM_BASE_URL="${MM_BASE_URL:-https://slack.solio.tech}"
|
|
export MM_BOT_USER_ID="${MM_BOT_USER_ID:-eqtkymoej7rw7dp8xbh7hywzrr}"
|
|
export TRANSCRIPT_DIR="${TRANSCRIPT_DIR:-/home/node/.openclaw/agents}"
|
|
export LOG_LEVEL="${LOG_LEVEL:-info}"
|
|
export IDLE_TIMEOUT_S="${IDLE_TIMEOUT_S:-60}"
|
|
export SESSION_POLL_MS="${SESSION_POLL_MS:-2000}"
|
|
export MAX_ACTIVE_SESSIONS="${MAX_ACTIVE_SESSIONS:-20}"
|
|
export MAX_STATUS_LINES="${MAX_STATUS_LINES:-20}"
|
|
export HEALTH_PORT="${HEALTH_PORT:-9090}"
|
|
export PID_FILE
|
|
export OFFSET_FILE="${OFFSET_FILE:-/tmp/status-watcher-offsets.json}"
|
|
|
|
# Plugin config (optional but recommended)
|
|
export PLUGIN_ENABLED="${PLUGIN_ENABLED:-true}"
|
|
export PLUGIN_URL="${PLUGIN_URL:-https://slack.solio.tech/plugins/com.openclaw.livestatus}"
|
|
export PLUGIN_SECRET="${PLUGIN_SECRET:-}"
|
|
|
|
# Kill existing daemon if running
|
|
if [ -f "$PID_FILE" ]; then
|
|
OLD_PID=$(cat "$PID_FILE" 2>/dev/null || true)
|
|
if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then
|
|
echo "Stopping existing daemon (PID $OLD_PID)..."
|
|
kill "$OLD_PID" 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
rm -f "$PID_FILE"
|
|
fi
|
|
|
|
# Start daemon with proper logging
|
|
echo "Starting status watcher daemon..."
|
|
echo " Log file: $LOG_FILE"
|
|
echo " PID file: $PID_FILE"
|
|
echo " Plugin: ${PLUGIN_ENABLED} (${PLUGIN_URL:-not configured})"
|
|
|
|
cd "$SCRIPT_DIR"
|
|
node src/watcher-manager.js start >> "$LOG_FILE" 2>&1 &
|
|
DAEMON_PID=$!
|
|
|
|
# Wait for PID file
|
|
for i in $(seq 1 10); do
|
|
if [ -f "$PID_FILE" ]; then
|
|
echo "Daemon started (PID $(cat "$PID_FILE"))"
|
|
exit 0
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
|
|
# Check if process is still running
|
|
if kill -0 "$DAEMON_PID" 2>/dev/null; then
|
|
echo "Daemon started (PID $DAEMON_PID) but PID file not created yet"
|
|
exit 0
|
|
else
|
|
echo "ERROR: Daemon failed to start. Check $LOG_FILE"
|
|
tail -20 "$LOG_FILE" 2>/dev/null
|
|
exit 1
|
|
fi
|