Skill: aaroncxxx/system-selfcheck (version 2.0.0)

--- name: system-selfcheck version: 2.0.0 description: > 系统自检：一键诊断 OpenClaw 运行环境，输出结构化报告。 检查系统资源、运行时依赖、网络连通性、API 配置、Skills 状态。 预留 MiClaw / Hermes 平台适配。 applyTo: "**" --- # 系统自检 System Self-Check v2.0 一键诊断 Agent 运行环境，输出结构化健康报告。 > **关于作者** — 十五年老米粉了！！冲！！！ > > **功能清单：** > - ✅ 系统/Uptime/Load/Memory/Swap/Disk/CPU 检查 > - ✅ Python/Node/ffmpeg/jq 依赖检测 > - ✅ Docker 状态检测（如已安装） > - ✅ GitHub/MiMo API/ClawHub 网络连通性（带重试） > - ✅ OpenClaw Gateway/Config/Skills/API Keys > - ✅ `--brief` 精简 / `--json` 结构化 / `--fix` 自动修复 > - ✅ 预留 MiClaw/Hermes 平台入口 > - ✅ 健康评分 (Health Score 0-100) > - ✅ 告警阈值（内存 ⚠️<30% 🔴<10%，磁盘同理，网络 ⚠️>3s 🔴超时） ## When to Use | Situation | Use this skill? | |---|---| | 用户说"系统自检" / "健康检查" / "status check" / "diagnostics" | ✅ Yes | | 排查环境问题（依赖缺失、网络不通、配置错误） | ✅ Yes | | 定期巡检（配合 cron 定时执行） | ✅ Yes | | 部署后验证环境是否就绪 | ✅ Yes | ## Usage ```bash bash "{baseDir}/scripts/selfcheck.sh" [options] ``` ### Options | Flag | Description | |------|-------------| | `--brief` | 精简模式，只显示问题项 | | `--json` | JSON 格式输出 | | `--fix` | 自动修复可修复的问题（安装缺失依赖等） | | `--platform <name>` | 强制指定平台：openclaw / miclaw / hermes（默认自动检测） | ### --fix 支持安装的依赖 - jq、curl、git、python3-pip、edge-tts - 自动清理 apt 缓存 ### Examples ```bash # 完整自检 bash "{baseDir}/scripts/selfcheck.sh" # 只看问题 bash "{baseDir}/scripts/selfcheck.sh --brief" # JSON 输出（方便程序消费） bash "{baseDir}/scripts/selfcheck.sh --json" # 自动修复 bash "{baseDir}/scripts/selfcheck.sh --fix" ``` ## 检查项 ### 通用检查（所有平台） | 模块 | 检查内容 | 告警阈值 | |------|---------|---------| | 系统 | OS、内核、CPU 核数/架构、主机名 | — | | Uptime | 运行时间 | ⚠️ >30天建议重启 | | Load | 1/5/15 分钟负载 | ⚠️ >CPU核数 / 🔴 >2倍核数 | | 内存 | 总量/可用/百分比 | ⚠️ <30% 可用 / 🔴 <10% | | Swap | 已用/总量/百分比 | ⚠️ >50% / 🔴 >80% | | 磁盘 | 总量/已用/可用 | ⚠️ <30% 可用 / 🔴 <10% | | 运行时 | Python、Node 版本 | — | | 核心依赖 | ffmpeg、jq、curl、git | 缺失即 🔴 | | Docker | 容器/镜像统计（如已安装） | ⚠️ >10停止容器 | | 网络 | GitHub、MiMo API、ClawHub 连通性（带重试） | ⚠️ >3s / 🔴 超时 | ### OpenClaw 专属检查 | 检查项 | 内容 | |--------|------| | Gateway | 运行状态 | | 配置文件 | `~/.openclaw/openclaw.json` 完整性 | | Skills | 已安装列表 + 缺失依赖 | | API Keys | MIMO_API_KEY / ClawHub Token（仅检查存在，不输出值） | ### 预留平台（TODO） - **MiClaw**：`check_miclaw.sh` — MiMo Agent 平台适配 - **Hermes**：`check_hermes.sh` — Hermes Agent 平台适配 ## 输出格式 ``` ⚡ System Self-Check v2.0 — Openclaw ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ [System] Linux 6.8.0-101-generic | 2 cores | x86_64 | VM-0-4-ubuntu ✅ [Uptime] 4d 2h 35m ✅ [Load] 1m=0.01 5m=0.04 15m=0.07 ✅ [Memory] 1967M total / 856M available (43%) ✅ [Swap] 326M / 10179M (3%) ✅ [Disk] 40G total / 18G available (55% used) ✅ [Runtime] Python 3.12.3 | Node v22.22.2 ✅ [Deps] ffmpeg 6.1.1-3ubuntu5 | jq ✅ | curl ✅ | git ✅ ⚠️ [Network] github.com — 200 (10s) SLOW ✅ [Network] api.xiaomimimo.com — 404 (0s) ✅ [Network] clawhub.ai — 200 (0s) ⚠️ [Platform] OpenClaw OpenClaw 2026.4.21 (latest: 2026.4.27) ✅ [Gateway] Running ✅ [Config] ~/.openclaw/openclaw.json exists ✅ [Skills] 13 installed (/root/.openclaw/workspace/skills) ⚠️ [API Keys] MIMO_API_KEY ❌ | ClawHub ✅ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Summary: 13 passed | 3 warnings | 0 failed Health: ✅ 94/100 (良好) ``` ## 版本历史 ### v2.0.0 (2026-05-01) - 🆕 Uptime 检查：运行时间过长提醒重启 - 🆕 Load Average 检查：1/5/15 分钟负载监控 - 🆕 Swap 检查：交换分区使用率 - 🆕 Docker 检查：容器/镜像统计 - 🆕 健康评分：Health Score 0-100 - 🔧 Skills 路径修复：支持多路径搜索（workspace/skills 优先） - 🔧 网络请求重试：失败自动重试 2 次 - 🔧 `--fix` 扩展：支持 curl/git/pip3 自动安装 - 🔧 依赖检测增强：自动检测 docker ### v1.2 (2026-04-27) - 🍎 macOS 内存检测改用 `vm_stat`，正确计算可用内存（free + speculative pages） - 📂 Skills 路径动态获取：优先 `openclaw config get skills.dir`，不再硬编码 - 🔄 OpenClaw 版本对比：从 npm registry 拉取最新版本，落后时 warn 提示 - ✨ `--brief` 模式无问题时输出 "All clear ✅" ### v1.0.1 (2026-04-24) - 🚀 首发：系统自检 Skill，支持 OpenClaw 平台，预留 MiClaw/Hermes，三种输出模式，告警阈值 ## 定时自检（Cron） 通过 OpenClaw cron 定期执行： ``` schedule: "0 9 * * *" # 每天早上 9 点 payload: "执行系统自检并报告异常" ``` ## 交付格式 - 默认：直接回复结构化文本报告 - `--json`：回复 JSON 格式 - `--brief`：只回复问题项，无问题则回复 "All clear ✅"

path: _meta.json
content: ownerId: kn75hrtysjh0122vxcn1dgr37h85da17
slug: system-selfcheck
version: 1.2.0
publishedAt: 1777258175654

path: scripts/selfcheck.sh
content: #!/usr/bin/env bash
# System Self-Check v2.0 — OpenClaw / MiClaw / Hermes 通用
# Usage: bash selfcheck.sh [--brief] [--json] [--fix] [--platform <name>]

set -euo pipefail

# ============================================================
# 参数解析
# ============================================================
BRIEF=false
JSON=false
FIX=false
PLATFORM=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    --brief)    BRIEF=true; shift ;;
    --json)     JSON=true; shift ;;
    --fix)      FIX=true; shift ;;
    --platform) PLATFORM="$2"; shift 2 ;;
    *)          echo "Unknown option: $1"; exit 1 ;;
  esac
done

# ============================================================
# 计数器
# ============================================================
PASS=0
WARN=0
FAIL=0
TOTAL=0

# ============================================================
# 工具函数
# ============================================================
result() {
  local status="$1" module="$2" detail="$3"
  TOTAL=$((TOTAL + 1))
  case "$status" in
    pass) PASS=$((PASS + 1)) ;;
    warn) WARN=$((WARN + 1)) ;;
    fail) FAIL=$((FAIL + 1)) ;;
  esac
  if $BRIEF && [[ "$status" == "pass" ]]; then return; fi
  local icon
  case "$status" in
    pass) icon="✅" ;;
    warn) icon="⚠️" ;;
    fail) icon="❌" ;;
  esac
  if $JSON; then
    echo "{\"status\":\"$status\",\"module\":\"$module\",\"detail\":\"$detail\"}"
  else
    printf "  %-4s %-10s %s\n" "$icon" "[$module]" "$detail"
  fi
}

# 网络请求（带重试）
curl_retry() {
  local url="$1"
  local timeout="${2:-10}"
  local retries=2
  local code="" latency_s=0 start_s end_s

  for ((i=1; i<=retries; i++)); do
    start_s=$(date +%s%N 2>/dev/null || date +%s)
    code=$(curl -s -o /dev/null -w "%{http_code}" "$url" \
      --connect-timeout 5 --max-time "$timeout" 2>/dev/null || true)
    end_s=$(date +%s%N 2>/dev/null || date +%s)
    code=$(echo "$code" | tr -d '[:space:]')
    code=${code:-000}

    # 计算延迟（毫秒精度）
    if [[ ${#start_s} -gt 10 ]]; then
      latency_s=$(( (end_s - start_s) / 1000000 / 1000 ))
    else
      latency_s=$(( end_s - start_s ))
    fi

    if [[ "$code" != "000" ]]; then
      echo "$code $latency_s"
      return 0
    fi
    sleep 1
  done
  echo "000 $latency_s"
  return 1
}

# ============================================================
# 平台检测
# ============================================================
detect_platform() {
  if [[ -n "$PLATFORM" ]]; then
    echo "$PLATFORM"
    return
  fi
  if command -v openclaw &>/dev/null; then
    echo "openclaw"
  elif command -v miclaw &>/dev/null; then
    echo "miclaw"
  elif command -v hermes &>/dev/null; then
    echo "hermes"
  else
    echo "unknown"
  fi
}

DETECTED_PLATFORM=$(detect_platform)
OS=$(uname -s)

# ============================================================
# 通用检查
# ============================================================

# --- System ---
check_system() {
  local kernel cpus arch hostname_str
  kernel=$(uname -r)
  cpus=$(nproc 2>/dev/null || echo "?")
  arch=$(uname -m)
  hostname_str=$(hostname -s 2>/dev/null || echo "?")
  result pass "System" "$OS $kernel | $cpus cores | $arch | $hostname_str"
}

# --- Uptime ---
check_uptime() {
  local uptime_str
  if [[ -f /proc/uptime ]]; then
    local seconds=$(awk '{print int($1)}' /proc/uptime)
    local days=$((seconds / 86400))
    local hours=$(( (seconds % 86400) / 3600 ))
    local mins=$(( (seconds % 3600) / 60 ))
    if (( days > 30 )); then
      result warn "Uptime" "${days}d ${hours}h ${mins}m — 建议重启"
    elif (( days > 7 )); then
      result pass "Uptime" "${days}d ${hours}h ${mins}m — 较长"
    else
      result pass "Uptime" "${days}d ${hours}h ${mins}m"
    fi
  else
    uptime_str=$(uptime -p 2>/dev/null || uptime | sed 's/.*up //' | sed 's/,.*//')
    result pass "Uptime" "$uptime_str"
  fi
}

# --- Load Average ---
check_load() {
  if [[ -f /proc/loadavg ]]; then
    local load1 load5 load15 cpus
    read -r load1 load5 load15 _ < /proc/loadavg
    cpus=$(nproc 2>/dev/null || echo 1)
    # 去掉小数点做比较
    local l1=${load1%%.*}
    local l5=${load5%%.*}
    local l15=${load15%%.*}
    if (( l1 > cpus * 2 )); then
      result fail "Load" "1m=$load1 5m=$load5 15m=$load15 (cores=$cpus) — OVERLOADED"
    elif (( l1 > cpus )); then
      result warn "Load" "1m=$load1 5m=$load5 15m=$load15 (cores=$cpus) — HIGH"
    else
      result pass "Load" "1m=$load1 5m=$load5 15m=$load15"
    fi
  else
    result pass "Load" "N/A (no /proc/loadavg)"
  fi
}

# --- Memory ---
check_memory() {
  if [[ "$OS" == "Linux" ]]; then
    local total available pct swap_total swap_used
    total=$(free -m | awk '/Mem:/ {print $2}')
    available=$(free -m | awk '/Mem:/ {print $7}')
    pct=$((available * 100 / total))
    swap_total=$(free -m | awk '/Swap:/ {print $2}')
    swap_used=$(free -m | awk '/Swap:/ {print $3}')

    local detail="${total}M total / ${available}M available (${pct}%)"
    if (( pct < 10 )); then
      result fail "Memory" "$detail — CRITICAL"
    elif (( pct < 30 )); then
      result warn "Memory" "$detail — LOW"
    else
      result pass "Memory" "$detail"
    fi

    # Swap 检查
    if (( swap_total > 0 )); then
      local swap_pct=$((swap_used * 100 / swap_total))
      if (( swap_pct > 80 )); then
        result warn "Swap" "${swap_used}M / ${swap_total}M (${swap_pct}%) — HIGH"
      elif (( swap_pct > 50 )); then
        result pass "Swap" "${swap_used}M / ${swap_total}M (${swap_pct}%)"
      else
        result pass "Swap" "${swap_used}M / ${swap_total}M (${swap_pct}%)"
      fi
    else
      result pass "Swap" "No swap configured"
    fi
  else
    # macOS
    local page_size free_pages speculative_pages total_bytes avail_bytes total_mb avail_mb pct
    page_size=$(sysctl -n hw.pagesize 2>/dev/null || echo 4096)
    total_bytes=$(sysctl -n hw.memsize 2>/dev/null || echo 0)
    total_mb=$((total_bytes / 1024 / 1024))
    free_pages=$(vm_stat 2>/dev/null | awk '/Pages free/ {gsub(/\./,"",$3); print $3}')
    speculative_pages=$(vm_stat 2>/dev/null | awk '/Pages speculative/ {gsub(/\./,"",$3); print $3}')
    free_pages=${free_pages:-0}
    speculative_pages=${speculative_pages:-0}
    avail_bytes=$(( (free_pages + speculative_pages) * page_size ))
    avail_mb=$((avail_bytes / 1024 / 1024))
    if (( total_mb > 0 )); then
      pct=$((avail_mb * 100 / total_mb))
    else
      pct=100
    fi
    local detail="${total_mb}M total / ${avail_mb}M available (${pct}%)"
    if (( pct < 10 )); then
      result fail "Memory" "$detail — CRITICAL"
    elif (( pct < 30 )); then
      result warn "Memory" "$detail — LOW"
    else
      result pass "Memory" "$detail"
    fi
  fi
}

# --- Disk ---
check_disk() {
  local total used avail pct
  read -r total used avail pct <<< $(df -h / | awk 'NR==2 {print $2, $3, $4, $5}')
  local pct_num=${pct%\%}
  local avail_pct=$((100 - pct_num))
  local detail="$total total / $avail available (${pct_num}% used)"
  if (( avail_pct < 10 )); then
    result fail "Disk" "$detail — CRITICAL"
  elif (( avail_pct < 30 )); then
    result warn "Disk" "$detail — LOW"
  else
    result pass "Disk" "$detail"
  fi
}

# --- Runtime ---
check_runtime() {
  local py_ver node_ver
  py_ver=$(python3 --version 2>&1 | awk '{print $2}')
  node_ver=$(node --version 2>&1 || echo "not found")
  result pass "Runtime" "Python $py_ver | Node $node_ver"
}

# --- Core Dependencies ---
check_deps() {
  local missing=""
  local found=""

  if command -v ffmpeg &>/dev/null; then
    local ff_ver=$(ffmpeg -version 2>&1 | head -1 | awk '{print $3}')
    found+="ffmpeg $ff_ver | "
  else
    missing+="ffmpeg "
  fi

  if command -v jq &>/dev/null; then
    found+="jq ✅ | "
  else
    missing+="jq "
  fi

  if command -v curl &>/dev/null; then
    found+="curl ✅ | "
  else
    missing+="curl "
  fi

  if command -v git &>/dev/null; then
    found+="git ✅ | "
  else
    missing+="git "
  fi

  if command -v docker &>/dev/null; then
    local docker_ver=$(docker --version 2>&1 | awk '{print $3}' | tr -d ',')
    found+="docker $docker_ver ✅ | "
  fi

  # 去掉末尾的 " | "
  found=${found% | }

  if [[ -n "$missing" ]]; then
    result fail "Deps" "${found} | MISSING: $missing"
  else
    result pass "Deps" "$found"
  fi
}

# --- Docker ---
check_docker() {
  if ! command -v docker &>/dev/null; then
    return  # 没装 docker 就跳过
  fi

  # Docker daemon 状态
  if docker info &>/dev/null; then
    local containers_running=$(docker ps -q 2>/dev/null | wc -l)
    local containers_stopped=$(docker ps -aq --filter "status=exited" 2>/dev/null | wc -l)
    local images=$(docker images -q 2>/dev/null | wc -l)
    local detail="running=$containers_running stopped=$containers_stopped images=$images"
    if (( containers_stopped > 10 )); then
      result warn "Docker" "$detail — 多个停止的容器"
    else
      result pass "Docker" "$detail"
    fi
  else
    result warn "Docker" "installed but daemon not running"
  fi
}

# --- Network ---
check_network() {
  local urls=("github.com" "api.xiaomimimo.com" "clawhub.ai")
  for url in "${urls[@]}"; do
    local code latency_s
    read -r code latency_s <<< $(curl_retry "https://$url" 10)

    if [[ "$code" == "000" ]]; then
      result fail "Network" "$url — TIMEOUT"
    elif (( latency_s > 5 )); then
      result warn "Network" "$url — $code (${latency_s}s) SLOW"
    elif (( latency_s > 3 )); then
      result warn "Network" "$url — $code (${latency_s}s) — 较慢"
    else
      result pass "Network" "$url — $code (${latency_s}s)"
    fi
  done
}


# --- OpenClaw ---
check_openclaw() {
  if command -v openclaw &>/dev/null; then
    local oc_ver=$(openclaw --version 2>&1 | head -1)
    # Check latest version from npm registry
    local latest_ver=""
    if command -v curl &>/dev/null; then
      latest_ver=$(curl -s --connect-timeout 5 --max-time 10 \
        "https://registry.npmjs.org/openclaw/latest" 2>/dev/null \
        | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4 || echo "")
    fi
    if [[ -n "$latest_ver" && "$oc_ver" != *"$latest_ver"* ]]; then
      result warn "Platform" "OpenClaw $oc_ver (latest: $latest_ver)"
    else
      result pass "Platform" "OpenClaw $oc_ver"
    fi

    # Gateway
    local gw_status=$(openclaw gateway status 2>&1 || echo "unknown")
    if echo "$gw_status" | grep -qi "running\|active\|ok"; then
      result pass "Gateway" "Running"
    else
      result warn "Gateway" "Status: $gw_status"
    fi

    # Config
    if [[ -f ~/.openclaw/openclaw.json ]]; then
      result pass "Config" "~/.openclaw/openclaw.json exists"
    else
      result fail "Config" "~/.openclaw/openclaw.json NOT FOUND"
    fi
  else
    result fail "Platform" "openclaw command not found"
  fi
}

# --- Skills ---
check_skills() {
  local skill_dir=""
  # 尝试从 openclaw config 获取
  if command -v openclaw &>/dev/null; then
    skill_dir=$(openclaw config get skills.dir 2>/dev/null || echo "")
  fi
  # 依次尝试多个可能的路径
  local search_dirs=(
    "$skill_dir"
    "${HOME}/.openclaw/workspace/skills"
    "${HOME}/.openclaw/skills"
  )
  local found_dir=""
  for dir in "${search_dirs[@]}"; do
    [[ -z "$dir" ]] && continue
    # 处理相对路径
    [[ "$dir" != /* ]] && dir="${HOME}/.openclaw/$dir"
    if [[ -d "$dir" ]]; then
      found_dir="$dir"
      break
    fi
  done

  if [[ -n "$found_dir" ]]; then
    local count=$(ls -d "$found_dir"/*/ 2>/dev/null | wc -l)
    result pass "Skills" "$count installed ($found_dir)"
  else
    result warn "Skills" "No skills directory found"
  fi
}

# --- API Keys ---
check_api_keys() {
  local key_status=""

  if [[ -n "${MIMO_API_KEY:-}" ]]; then
    key_status+="MIMO_API_KEY ✅ | "
  else
    key_status+="MIMO_API_KEY ❌ | "
  fi

  # Check ClawHub token (in config or env)
  local clawhub_ok=false
  if [[ -n "${CLAWHUB_TOKEN:-}" ]]; then
    clawhub_ok=true
  elif [[ -f ~/.config/clawhub/config.json ]]; then
    clawhub_ok=true
  elif command -v npx &>/dev/null; then
    local whoami=$(timeout 10 npx clawhub@latest whoami 2>/dev/null || echo "")
    if [[ -n "$whoami" && "$whoami" != *"not logged"* ]]; then
      clawhub_ok=true
    fi
  fi

  if $clawhub_ok; then
    key_status+="ClawHub ✅"
  else
    key_status+="ClawHub ❌"
  fi

  # Check for any missing
  if [[ -z "${MIMO_API_KEY:-}" ]] || ! $clawhub_ok; then
    result warn "API Keys" "$key_status"
  else
    result pass "API Keys" "$key_status"
  fi
}

# ============================================================
# Platform-specific checks
# ============================================================
check_platform_specific() {
  case "$DETECTED_PLATFORM" in
    openclaw)
      check_openclaw
      check_skills
      check_api_keys
      ;;
    miclaw)
      result pass "Platform" "MiClaw detected (checks TODO)"
      ;;
    hermes)
      result pass "Platform" "Hermes detected (checks TODO)"
      ;;
    *)
      result warn "Platform" "Unknown — skipping platform checks"
      ;;
  esac
}

# ============================================================
# Auto-fix
# ============================================================
do_fix() {
  echo ""
  echo "🔧 Auto-fix mode"
  echo "━━━━━━━━━━━━━━━━"

  local fixed=0

  # Fix missing jq
  if ! command -v jq &>/dev/null; then
    echo "  Installing jq..."
    if apt-get install -y jq 2>/dev/null; then
      echo "  ✅ jq installed"
      fixed=$((fixed + 1))
    else
      echo "  ❌ jq install failed (apt may be unreachable)"
    fi
  fi

  # Fix missing curl
  if ! command -v curl &>/dev/null; then
    echo "  Installing curl..."
    if apt-get install -y curl 2>/dev/null; then
      echo "  ✅ curl installed"
      fixed=$((fixed + 1))
    else
      echo "  ❌ curl install failed"
    fi
  fi

  # Fix missing git
  if ! command -v git &>/dev/null; then
    echo "  Installing git..."
    if apt-get install -y git 2>/dev/null; then
      echo "  ✅ git installed"
      fixed=$((fixed + 1))
    else
      echo "  ❌ git install failed"
    fi
  fi

  # Fix missing python3-pip
  if ! command -v pip3 &>/dev/null; then
    echo "  Installing python3-pip..."
    if apt-get install -y python3-pip 2>/dev/null; then
      echo "  ✅ python3-pip installed"
      fixed=$((fixed + 1))
    else
      echo "  ❌ python3-pip install failed"
    fi
  fi

  # Fix missing edge-tts
  if ! python3 -c "import edge_tts" 2>/dev/null; then
    echo "  Installing edge-tts..."
    if pip3 install --break-system-packages edge-tts 2>/dev/null; then
      echo "  ✅ edge-tts installed"
      fixed=$((fixed + 1))
    else
      echo "  ❌ edge-tts install failed"
    fi
  fi

  # 清理 apt 缓存
  if command -v apt-get &>/dev/null; then
    echo "  Cleaning apt cache..."
    apt-get autoremove -y 2>/dev/null && echo "  ✅ apt cache cleaned"
  fi

  echo ""
  echo "  🔧 Fixed: $fixed items"
}

# ============================================================
# Health Score
# ============================================================
calc_health_score() {
  if (( TOTAL == 0 )); then
    echo 100
    return
  fi
  # pass=100分, warn=70分, fail=0分
  local score=$(( (PASS * 100 + WARN * 70) / TOTAL ))
  echo "$score"
}

# ============================================================
# Main
# ============================================================

if ! $JSON; then
  echo ""
  echo "⚡ System Self-Check v2.0 — ${DETECTED_PLATFORM^}"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
fi

check_system
check_uptime
check_load
check_memory
check_disk
check_runtime
check_deps
check_docker
check_network
check_platform_specific

if $FIX; then
  do_fix
fi

if ! $JSON; then
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  health_score=$(calc_health_score)
  health_icon="✅"
  health_label="良好"
  if (( health_score < 60 )); then
    health_icon="🔴"
    health_label="较差"
  elif (( health_score < 80 )); then
    health_icon="⚠️"
    health_label="一般"
  fi

  if $BRIEF && (( WARN == 0 )) && (( FAIL == 0 )); then
    echo "  All clear ✅"
  else
    echo "  Summary: $PASS passed | $WARN warnings | $FAIL failed"
    echo "  Health:  $health_icon $health_score/100 ($health_label)"
  fi
  echo ""
fi

# Exit code: 0 = all clear, 1 = has failures, 2 = has warnings
if (( FAIL > 0 )); then exit 1; fi
if (( WARN > 0 )); then exit 2; fi
exit 0


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)