From be014bcb3c578275c05ad407b7899620be2f59d3 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Fri, 22 May 2026 18:26:46 +0800 Subject: [PATCH] auto-sync: 2026-05-22 18:26:46 --- scripts/backup.sh | 0 scripts/build-frontend.sh | 0 scripts/deploy.sh | 0 scripts/reset-data.sh | 0 scripts/status.sh | 140 ++++++++++++++++++++++++++++++++++++++ scripts/uninstall.sh | 0 6 files changed, 140 insertions(+) mode change 100644 => 100755 scripts/backup.sh mode change 100644 => 100755 scripts/build-frontend.sh mode change 100644 => 100755 scripts/deploy.sh mode change 100644 => 100755 scripts/reset-data.sh create mode 100755 scripts/status.sh mode change 100644 => 100755 scripts/uninstall.sh diff --git a/scripts/backup.sh b/scripts/backup.sh old mode 100644 new mode 100755 diff --git a/scripts/build-frontend.sh b/scripts/build-frontend.sh old mode 100644 new mode 100755 diff --git a/scripts/deploy.sh b/scripts/deploy.sh old mode 100644 new mode 100755 diff --git a/scripts/reset-data.sh b/scripts/reset-data.sh old mode 100644 new mode 100755 diff --git a/scripts/status.sh b/scripts/status.sh new file mode 100755 index 0000000..69fc516 --- /dev/null +++ b/scripts/status.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +# status.sh — 查看 moziplus v2 运行状态 +set -euo pipefail + +TARGET_DIR="$HOME/.sanguo_projects/sanguo_moziplus_v2" +PM2_NAME="sanguo-moziplus-v2" +HEALTH_URL="http://localhost:8083/api/health" +DETAILED=false + +usage() { + echo "Usage: $0 [options]" + echo "" + echo "Options:" + echo " --target=DIR 安装目录" + echo " -v, --verbose 显示详细信息(项目列表、磁盘占用等)" + echo " -h, --help 显示帮助" + exit 0 +} + +for arg in "$@"; do + case "$arg" in + --target=*) TARGET_DIR="${arg#*=}" ;; + -v|--verbose) DETAILED=true ;; + -h|--help) usage ;; + esac +done + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo " moziplus v2 — Status" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + +# ── 版本 ── +VERSION=$(cd "$TARGET_DIR" 2>/dev/null && python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])' 2>/dev/null || echo 'unknown') +echo " Version: v$VERSION" + +# ── 安装目录 ── +if [ -d "$TARGET_DIR" ]; then + echo " Install: $TARGET_DIR ✅" +else + echo " Install: $TARGET_DIR ❌ (not found)" + exit 1 +fi + +# ── PM2 状态 ── +echo "" +PM2_STATUS=$(pm2 jlist 2>/dev/null | python3 -c " +import sys, json +procs = json.load(sys.stdin) +for p in procs: + if p['name'] == '$PM2_NAME': + s = p['pm2_env']['status'] + pid = p['pid'] or '-' + uptime = p['pm2_env'].get('pm_uptime', 0) + restarts = p['pm2_env'].get('restart_time', 0) + mem = p['monit'].get('memory', 0) + mem_mb = round(mem / 1024 / 1024, 1) + cpu = p['monit'].get('cpu', 0) + print(f'{s}|{pid}|{uptime}|{restarts}|{mem_mb}|{cpu}') + break +else: + print('not_found|||||') +" 2>/dev/null || echo 'error|||||') + +IFS='|' read -r STATUS PID UPTIME RESTARTS MEM CPU <<< "$PM2_STATUS" +if [ "$STATUS" = "online" ]; then + # 计算 uptime + if [ -n "$UPTIME" ] && [ "$UPTIME" != "0" ]; then + UPTIME_FMT=$(python3 -c " +from datetime import datetime, timezone +delta = datetime.now(timezone.utc) - datetime.fromtimestamp($UPTIME/1000, tz=timezone.utc) +days = delta.days +hours, rem = divmod(delta.seconds, 3600) +mins, _ = divmod(rem, 60) +parts = [] +if days: parts.append(f'{days}d') +if hours: parts.append(f'{hours}h') +parts.append(f'{mins}m') +print(' '.join(parts)) +" 2>/dev/null || echo '?') + else + UPTIME_FMT="just started" + fi + echo " PM2: online ✅" + echo " PID: $PID" + echo " Uptime: $UPTIME_FMT" + echo " Restarts: $RESTARTS" + echo " Memory: ${MEM}MB" + echo " CPU: ${CPU}%" +else + echo " PM2: $STATUS ❌" +fi + +# ── 健康检查 ── +echo "" +HEALTH=$(curl -sf "$HEALTH_URL" 2>/dev/null || echo '{"status":"unreachable"}') +HEALTH_STATUS=$(echo "$HEALTH" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status','unknown'))" 2>/dev/null || echo 'unknown') +if [ "$HEALTH_STATUS" = "ok" ]; then + echo " Health: ok ✅" +else + echo " Health: $HEALTH_STATUS ❌" +fi + +# ── 数据统计 ── +echo "" +DATA_DIR="$TARGET_DIR/data" +if [ -d "$DATA_DIR" ]; then + # 项目数 + PROJ_COUNT=$(find "$DATA_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ') + DATA_SIZE=$(du -sh "$DATA_DIR" 2>/dev/null | cut -f1) + echo " Projects: $PROJ_COUNT" + echo " Data size: $DATA_SIZE" + + if [ "$DETAILED" = true ]; then + echo "" + echo " Project details:" + for proj_dir in "$DATA_DIR"/*/; do + proj_name=$(basename "$proj_dir") + db_file="$proj_dir/blackboard.db" + if [ -f "$db_file" ]; then + TASK_COUNT=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM tasks" 2>/dev/null || echo '?') + ACTIVE_COUNT=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM tasks WHERE status NOT IN ('done','cancelled','archived')" 2>/dev/null || echo '?') + PROJ_SIZE=$(du -sh "$proj_dir" 2>/dev/null | cut -f1) + printf " %-25s %s tasks (%s active) %s\n" "$proj_name" "$TASK_COUNT" "$ACTIVE_COUNT" "$PROJ_SIZE" + else + printf " %-25s (no db)\n" "$proj_name" + fi + done + fi +fi + +# ── 配置 ── +if [ "$DETAILED" = true ]; then + echo "" + echo " Config:" + echo " Port: $(grep -o 'port:.*' "$TARGET_DIR/config/default.yaml" 2>/dev/null | head -1 || echo '8083 (default)')" + echo " Interval: $(grep -o 'interval:.*' "$TARGET_DIR/config/default.yaml" 2>/dev/null | head -1 || echo '?')" + echo " Agents: $(grep 'agents:' -A 20 "$TARGET_DIR/config/default.yaml" 2>/dev/null | grep ' - ' | wc -l | tr -d ' ') configured" +fi + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh old mode 100644 new mode 100755