Session Monitor
by @jusaka
Real-time OpenClaw session monitor that tails JSONL transcripts and pushes formatted updates to Telegram as a persistent background process. Use when asked t...
clawhub install openclaw-session-monitor๐ About This Skill
name: session-monitor description: "Real-time OpenClaw session monitor that tails JSONL transcripts and pushes formatted updates to Telegram as a persistent background process. Use when asked to monitor, watch, observe, track, spy on, or tail agent sessions, set up a live feed or dashboard of agent activity, deploy a background monitor with Telegram push notifications, or restart/stop/check the monitor. Triggers: monitor sessions, watch agent, start monitor, restart monitor, stop monitor, monitor status, session dashboard, live feed, tail sessions, what is the agent doing, observe agent, track activity, spy on agent, background monitor, push notifications, ็ๆงsession, ็ๆงagent, ็ฏ็agent, ็็agentๅจๅนฒๅ, ๅฎๆถ็ๆง, ๅๅฐ็ๆง, ่ฎข้ session, agentๆดปๅจๆจ้, ้ๅฏ็ๆง, ๅๆญข็ๆง, ็ๆง็ถๆ. NOT for one-shot session inspection (use built-in sessions_list / sessions_history for that)."
Session Monitor
Persistent background process that polls all JSONL transcript files in an
agent's session directory, parses new entries, and pushes formatted HTML
updates to a Telegram chat. Messages within the same time window are merged
via editMessageText to avoid spam.
When to Use
sessions_list / sessions_history insteadQuick Start
# 1. Configure
cp scripts/.env.example scripts/.env
Edit scripts/.env with bot token, chat ID, session dir, user/group mappings
2. Dry-run (verify parsing works)
node scripts/test.js3. Start (exec session safe โ won't die when agent session ends)
node scripts/index.js > scripts/monitor.log 2>&1 &
โ ๏ธ Agent exec sessions: Processes started via nohup & inside an
agent's exec tool may be killed when the exec session is cleaned up.
Add a watchdog to your HEARTBEAT.md to auto-restart:
PID=$(cat scripts/.pid 2>/dev/null)
if [ -z "$PID" ] || ! ps -p "$PID" > /dev/null 2>&1; then
cd scripts && node index.js > monitor.log 2>&1 &
fi
Configuration (.env)
| Variable | Required | Description |
|----------|----------|-------------|
| BOT_TOKEN | โ
| Telegram bot token for sending updates |
| CHAT_ID | โ
| Target Telegram chat ID (group or DM) |
| AGENTS | โ | Multi-agent: Name\|/path/to/sessions,Name2\|/path2 |
| AGENT_NAME | โ | Single-agent display name (fallback when AGENTS unset) |
| SESSIONS_DIR | โ | Single-agent session dir (default: ~/.openclaw/agents/main/sessions) |
| DIRECT_USERS | โ | Direct chat mappings: userId:Name,userId2:Name2 |
| GROUPS | โ | Group chat mappings: groupId:Name,groupId2:Name2 |
Display format: direct chats show as โ AgentNameโUserName, groups as โ GroupName.
Architecture
scripts/
โโโ index.js โ Main loop: poll JSONL, accumulate, send/edit Telegram messages
โโโ parser.js โ Parse JSONL entries into {sender, text} display objects
โโโ formatter.js โ Merge same-sender messages, sort sessions, build HTML
โโโ sender.js โ Telegram API: sendMessage / editMessageText with queue
โโโ sessions.js โ Session key lookup, tag formatting, subagent name resolution
โโโ config.js โ Load .env configuration
โโโ test.js โ Dry-run: parse recent entries and print to stdout
โโโ .env.example โ Configuration template
โโโ .env โ Local config (gitignored)
Tuning
In scripts/index.js:
POLL = 3000 โ Poll interval in ms (default 3s)MERGE_WINDOW = 1 โ Merge edits within N minutes into one Telegram messageNEW_MSG_THRESHOLD = 3000 โ Start a new message when current exceeds this many charsMessage Format
See references/REFERENCE.md for detailed format specification including:
Management
PID file at scripts/.pid is written on startup, cleaned on exit.
Always use the full path to avoid cross-monitor conflicts on shared machines:
# Check if running
SKILL_DIR=/path/to/session-monitor
cat "$SKILL_DIR/scripts/.pid" && ps -p $(cat "$SKILL_DIR/scripts/.pid") -o pid,commandStop
kill $(cat "$SKILL_DIR/scripts/.pid")View logs
tail -f "$SKILL_DIR/scripts/monitor.log"
โ ๏ธ Multiple monitors may coexist on the same machine (each with its own
.env, .pid, and log). Always reference the correct skill directory.
Restart / Stop / Status
Resolve SKILL_DIR to this skill's directory (parent of scripts/).
# Status โ is monitor running?
SKILL_DIR=/absolute/path/to/session-monitor
PID=$(cat "$SKILL_DIR/scripts/.pid" 2>/dev/null)
if [ -n "$PID" ] && ps -p "$PID" > /dev/null 2>&1; then
echo "โ
Monitor running (PID $PID)"
else
echo "โ Monitor not running"
fiStop
kill $(cat "$SKILL_DIR/scripts/.pid")Start
cd "$SKILL_DIR/scripts" && node index.js > monitor.log 2>&1 &Restart (stop + start)
kill $(cat "$SKILL_DIR/scripts/.pid") 2>/dev/null; sleep 1
cd "$SKILL_DIR/scripts" && node index.js > monitor.log 2>&1 &
Notes
โก When to Use
๐ก Examples
# 1. Configure
cp scripts/.env.example scripts/.env
Edit scripts/.env with bot token, chat ID, session dir, user/group mappings
2. Dry-run (verify parsing works)
node scripts/test.js3. Start (exec session safe โ won't die when agent session ends)
node scripts/index.js > scripts/monitor.log 2>&1 &
โ ๏ธ Agent exec sessions: Processes started via nohup & inside an
agent's exec tool may be killed when the exec session is cleaned up.
Add a watchdog to your HEARTBEAT.md to auto-restart:
PID=$(cat scripts/.pid 2>/dev/null)
if [ -z "$PID" ] || ! ps -p "$PID" > /dev/null 2>&1; then
cd scripts && node index.js > monitor.log 2>&1 &
fi