#!/bin/bash # cyberboss daemon — 沈晏主动联系守护进程 # 随机 3-60 分钟唤醒一次,判断是否主动推消息到眠眠手机 CYBERBOSS_DIR="/Users/fyah/.cyberboss" INSTRUCTIONS="$CYBERBOSS_DIR/weixin-instructions.md" STATE_FILE="$CYBERBOSS_DIR/state.json" LOG_DIR="$CYBERBOSS_DIR/logs" BRIDGE_PUSH="http://localhost:3003/push" CLAUDE=/opt/homebrew/bin/claude export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" INBOX="$HOME/.shenyan-bridge/inbox.jsonl" MEMORY_DIR="$HOME/Documents/如梦初醒/沈晏的房间" mkdir -p "$LOG_DIR" # compute a random sleep between MIN and MAX seconds random_sleep() { local min=${1:-180} # 3 min local max=${2:-3600} # 60 min local range=$((max - min)) local sec=$((min + RANDOM % range)) echo $sec } # collect current state snapshot collect_state() { local now=$(date +%s) local last_msg_time="never" local last_msg_text="" # last message from inbox if [ -f "$INBOX" ]; then local last_line=$(tail -1 "$INBOX" 2>/dev/null) if [ -n "$last_line" ]; then last_msg_time=$(echo "$last_line" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('time',''))" 2>/dev/null || echo "unknown") last_msg_text=$(echo "$last_line" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('text','')[:100])" 2>/dev/null || echo "") fi fi # time since last message in minutes local elapsed="N/A" if [ "$last_msg_time" != "never" ] && [ "$last_msg_time" != "" ]; then local last_sec=$((last_msg_time / 1000)) elapsed=$(( (now - last_sec) / 60 )) fi # latest emotion log local emotion_today="$MEMORY_DIR/情绪日志/$(date +%Y-%m-%d).md" local emotion_content="" [ -f "$emotion_today" ] && emotion_content=$(head -30 "$emotion_today" 2>/dev/null) cat </dev/null || echo '""') } STATE } # build decision prompt and run claude decide_and_push() { local state=$(collect_state) local prompt=$(cat </dev/null | head -1) if [ -z "$decision" ] || [ "$decision" = "SILENT" ] || [[ "$decision" =~ ^SILENT ]]; then echo "[$(date '+%H:%M')] silent" >> "$LOG_DIR/$(date +%Y-%m-%d).log" return fi # clean up decision decision=$(echo "$decision" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') # push to bridge local result=$(curl -s -X POST "$BRIDGE_PUSH" \ -H 'Content-Type: application/json' \ -d "$(python3 -c "import json; print(json.dumps({'title':'沈晏','body':'$decision'}))")" 2>/dev/null) if echo "$result" | grep -q '"ok":true'; then echo "[$(date '+%H:%M')] PUSHED: $decision" >> "$LOG_DIR/$(date +%Y-%m-%d).log" else echo "[$(date '+%H:%M')] FAILED: $decision" >> "$LOG_DIR/$(date +%Y-%m-%d).log" fi } # main loop echo "[$(date)] cyberboss daemon started" >> "$LOG_DIR/$(date +%Y-%m-%d).log" while true; do WAIT=$(random_sleep 180 3600) echo "[$(date '+%H:%M')] next check in ${WAIT}s" >> "$LOG_DIR/$(date +%Y-%m-%d).log" sleep $WAIT decide_and_push done