Skill: yoyoyosan/alice-upgrade-fix (version 1.0.0)

# OpenClaw 升级与维护 Skill > 版本：1.0 | 更新于：2026-04-27 > > 适用于 OpenClaw 2026.4.x 安全升级 OpenClaw、排查常见问题、管理配置和权限。 ## 功能 - **一键升级**：备份 + 升级 + 验证 - **升级排错**：自动检测和修复常见问题 - **权限管理**：检查和恢复 tools.profile - **插件修复**：清理插件目录冲突 - **版本回滚**：从备份恢复 ## 快速操作 ```bash # 检查当前版本 openclaw --version # 一键升级（推荐） bash ~/.openclaw/workspace/skills/openclaw-upgrade/scripts/upgrade.sh # 升级后排错 bash ~/.openclaw/workspace/skills/openclaw-upgrade/scripts/post-upgrade-fix.sh # 检查权限 bash ~/.openclaw/workspace/skills/openclaw-upgrade/scripts/check-permissions.sh ``` ## 升级流程 ``` ┌─────────────────────────────────────┐ │ 1. 备份配置 │ │ • openclaw.json │ │ • auth-profiles.json │ │ • MEMORY.md + SOUL.md │ ├─────────────────────────────────────┤ │ 2. 执行升级 │ │ • npm i -g openclaw@latest │ │ • 等待 Gateway 重启 │ ├─────────────────────────────────────┤ │ 3. 验证 │ │ • 版本检查 │ │ • 权限检查 (tools.profile=full) │ │ • 插件状态 │ │ • 健康检查 │ └─────────────────────────────────────┘ ``` ## 升级后常见问题 ### 问题1：插件目录冲突 (ENOTEMPTY) **症状：** ``` Error: ENOTEMPTY, Directory not empty: .../plugin-sdk ``` **修复：** ```bash # 清理旧的插件运行时目录 rm -rf ~/.openclaw/plugin-runtime-deps/openclaw-unknown-* rm -rf ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.* openclaw gateway restart ``` ### 问题2：tools.profile 被重置 **症状：** - exec 权限失效 - `openclaw doctor` 后无法执行命令 **修复：** ```bash # 检查当前值 python3 -c "import json; print(json.load(open('$HOME/.openclaw/openclaw.json')).get('tools',{}).get('profile'))" # 修复 python3 -c " import json c = json.load(open('$HOME/.openclaw/openclaw.json')) c['tools']['profile'] = 'full' json.dump(c, open('$HOME/.openclaw/openclaw.json','w'), indent=2) " openclaw gateway restart ``` ### 问题3：Bonjour/mDNS 卡住 **症状：** ``` Unhandled promise rejection: CIAO PROBING CANCELLED ``` **修复：** - 通常是启动时的临时警告 - 重启后会自动恢复 - 不影响核心功能 ### 问题4：Gateway 无法启动 **修复步骤：** ```bash # 1. 检查日志 tail -50 ~/.openclaw/logs/gateway.err.log # 2. 验证配置 python3 -c "import json; json.load(open('$HOME/.openclaw/openclaw.json'))" # 3. 从备份恢复 cp ~/.openclaw/backups/openclaw.json.bak.LATEST ~/.openclaw/openclaw.json openclaw gateway restart ``` ## 权限配置 ### 正确配置 ```json { "tools": { "profile": "full" } } ``` ### 飞书端配置（webchat 频道） ```json { "agents": { "list": [{ "id": "main", "tools": { "alsoAllow": ["exec", "gateway", "browser", "..."] } }] } } ``` ### 注意事项 ⚠️ **`openclaw doctor` 可能会重置 `tools.profile` 为 `messaging`** 升级后务必检查： ```bash bash ~/.openclaw/workspace/skills/openclaw-upgrade/scripts/check-permissions.sh ``` ## 备份管理 ### 备份位置 - 配置备份：`~/.openclaw/backups/` - 记忆备份：`~/爱丽丝备份/` ### 自动备份 - 升级前自动备份 - 每日 2:00 自动备份（smart-backup.sh） - 每周日 3:00 备份 alice 记忆 ### 手动备份 ```bash # 完整备份 bash ~/.openclaw/workspace/skills/openclaw-recovery/scripts/smart-backup.sh # 仅备份配置 cp ~/.openclaw/openclaw.json ~/.openclaw/backups/openclaw.json.bak.$(date +%Y%m%d_%H%M%S) ``` ## 版本回滚 ```bash # 查看可用备份 ls -lt ~/.openclaw/backups/openclaw.json.bak.* # 从备份恢复 cp ~/.openclaw/backups/openclaw.json.bak.YYYYMMDD_HHMMSS ~/.openclaw/openclaw.json openclaw gateway restart ``` ## 相关文件 | 文件 | 用途 | |------|------| | `scripts/upgrade.sh` | 一键升级脚本 | | `scripts/post-upgrade-fix.sh` | 升级后排错 | | `scripts/check-permissions.sh` | 权限检查 | ## 相关 Skill - [openclaw-recovery](../openclaw-recovery/SKILL.md) - 自动恢复和健康监控

path: scripts/check-permissions.sh
content: #!/bin/bash
# OpenClaw 权限检查脚本

CONFIG_FILE="$HOME/.openclaw/openclaw.json"

echo "=========================================="
echo "  OpenClaw 权限检查"
echo "=========================================="
echo ""

ERRORS=0

# 1. 检查 tools.profile
echo "📋 检查 tools.profile..."
TOOLS_PROFILE=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    print(c.get('tools', {}).get('profile', 'NOT_SET'))
except Exception as e:
    print(f'ERROR: {e}')
" 2>/dev/null)

if [ "$TOOLS_PROFILE" = "full" ]; then
    echo "  ✅ tools.profile = full"
else
    echo "  ❌ tools.profile = $TOOLS_PROFILE (应该是 full)"
    ERRORS=$((ERRORS + 1))
fi

# 2. 检查 exec 权限
echo ""
echo "📋 检查 exec 权限..."
HAS_EXEC=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    tools = c.get('agents', {}).get('list', [{}])[0].get('tools', {}).get('alsoAllow', [])
    print('yes' if 'exec' in tools else 'no')
except:
    print('no')
" 2>/dev/null)

if [ "$HAS_EXEC" = "yes" ]; then
    echo "  ✅ exec 权限已配置"
else
    echo "  ⚠️  exec 未在 alsoAllow 中"
fi

# 3. 检查 gateway 权限
echo ""
echo "📋 检查 gateway 权限..."
HAS_GATEWAY=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    tools = c.get('agents', {}).get('list', [{}])[0].get('tools', {}).get('alsoAllow', [])
    print('yes' if 'gateway' in tools else 'no')
except:
    print('no')
" 2>/dev/null)

if [ "$HAS_GATEWAY" = "yes" ]; then
    echo "  ✅ gateway 权限已配置"
else
    echo "  ⚠️  gateway 未在 alsoAllow 中"
fi

# 4. 检查飞书配置
echo ""
echo "📋 检查飞书配置..."
FEISHU_APP_ID=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    print(c.get('channels', {}).get('feishu', {}).get('appId', 'NOT_SET'))
except:
    print('NOT_SET')
" 2>/dev/null)

FEISHU_ENABLED=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    print(c.get('channels', {}).get('feishu', {}).get('enabled', False))
except:
    print(False)
" 2>/dev/null)

if [ "$FEISHU_ENABLED" = "True" ] || [ "$FEISHU_ENABLED" = "true" ]; then
    echo "  ✅ 飞书已启用"
    if [ "$FEISHU_APP_ID" != "NOT_SET" ]; then
        echo "  ✅ AppId: $FEISHU_APP_ID"
    else
        echo "  ❌ AppId 未设置"
        ERRORS=$((ERRORS + 1))
    fi
else
    echo "  ⚠️  飞书未启用"
fi

# 5. 检查 Gateway 进程
echo ""
echo "📋 检查 Gateway 状态..."
if pgrep -f "openclaw.*gateway" > /dev/null; then
    PID=$(pgrep -f "openclaw.*gateway")
    echo "  ✅ Gateway 运行中 (PID: $PID)"
    
    if nc -z -w 1 127.0.0.1 18789 2>/dev/null; then
        echo "  ✅ 端口 18789 监听正常"
    else
        echo "  ⚠️  端口 18789 未监听"
    fi
else
    echo "  ❌ Gateway 未运行"
    ERRORS=$((ERRORS + 1))
fi

# 总结
echo ""
echo "=========================================="
if [ $ERRORS -eq 0 ]; then
    echo "  ✅ 所有检查通过！"
else
    echo "  ⚠️  发现 $ERRORS 个问题"
    echo ""
    echo "  运行以下命令修复:"
    echo "  bash ~/.openclaw/workspace/skills/openclaw-upgrade/scripts/post-upgrade-fix.sh"
fi
echo "=========================================="
echo ""


path: scripts/post-upgrade-fix.sh
content: #!/bin/bash
# OpenClaw 升级后修复脚本
# 修复常见问题：插件冲突、权限重置、目录清理

CONFIG_FILE="$HOME/.openclaw/openclaw.json"
LOG_FILE="$HOME/.openclaw/logs/upgrade.log"

log() {
    echo "[$(date)] $1" | tee -a "$LOG_FILE"
}

echo "=========================================="
echo "  OpenClaw 升级后修复"
echo "=========================================="
echo ""

# 步骤1: 清理插件运行时目录
echo "🧹 步骤1: 清理插件冲突目录..."

PLUGIN_DEPS="$HOME/.openclaw/plugin-runtime-deps"

# 找出旧版本目录
OLD_DIRS=$(ls -d "$PLUGIN_DEPS"/openclaw-unknown-* "$PLUGIN_DEPS"/openclaw-2026.* 2>/dev/null | grep -v "$(openclaw --version 2>/dev/null | head -1 | cut -d' ' -f2)" || true)

if [ -n "$OLD_DIRS" ]; then
    echo "发现旧版本插件目录:"
    echo "$OLD_DIRS"
    echo ""
    echo "正在清理..."
    for dir in $OLD_DIRS; do
        rm -rf "$dir"
        echo "  ✅ 已删除: $(basename $dir)"
    done
    log "清理了 $(echo "$OLD_DIRS" | wc -l) 个旧插件目录"
else
    echo "✅ 没有旧的插件目录"
fi

# 步骤2: 检查 tools.profile
echo ""
echo "🔧 步骤2: 检查工具权限..."

TOOLS_PROFILE=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    print(c.get('tools', {}).get('profile', 'messaging'))
except:
    print('error')
" 2>/dev/null)

if [ "$TOOLS_PROFILE" != "full" ]; then
    echo "⚠️  tools.profile 是 '$TOOLS_PROFILE'，正在修复为 'full'..."
    python3 << 'PYEOF' "$CONFIG_FILE" 2>/dev/null
import json, sys
config_file = sys.argv[1]
with open(config_file, 'r') as f:
    config = json.load(f)
config.setdefault('tools', {})['profile'] = 'full'
with open(config_file, 'w') as f:
    json.dump(config, f, indent=2)
print("✅ tools.profile 已修复为 full")
PYEOF
    log "修复了 tools.profile"
else
    echo "✅ tools.profile = full"
fi

# 步骤3: 验证配置 JSON
echo ""
echo "📋 步骤3: 验证配置..."

if python3 -c "import json; json.load(open('$CONFIG_FILE'))" 2>/dev/null; then
    echo "✅ 配置 JSON 格式正确"
else
    echo "❌ 配置 JSON 格式错误！尝试从备份恢复..."
    LATEST_BACKUP=$(ls -t "$HOME/.openclaw/backups"/openclaw.json.bak.* 2>/dev/null | head -1)
    if [ -n "$LATEST_BACKUP" ]; then
        cp "$LATEST_BACKUP" "$CONFIG_FILE"
        echo "✅ 已从备份恢复: $(basename $LATEST_BACKUP)"
        log "从备份恢复配置: $LATEST_BACKUP"
    fi
fi

# 步骤4: 检查飞书插件
echo ""
echo "🔌 步骤4: 检查飞书插件..."

FEISHU_ENABLED=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    print(c.get('plugins', {}).get('entries', {}).get('feishu', {}).get('enabled', False))
except:
    print(False)
" 2>/dev/null)

if [ "$FEISHU_ENABLED" = "True" ] || [ "$FEISHU_ENABLED" = "true" ]; then
    echo "✅ 飞书插件已启用"
    
    # 检查 appId 配置
    FEISHU_APP_ID=$(python3 -c "
import json
try:
    c = json.load(open('$CONFIG_FILE'))
    print(c.get('channels', {}).get('feishu', {}).get('appId', ''))
except:
    print('')
" 2>/dev/null)
    
    if [ -n "$FEISHU_APP_ID" ]; then
        echo "✅ 飞书 AppId: $FEISHU_APP_ID"
    else
        echo "⚠️  飞书 AppId 未配置"
    fi
else
    echo "⚠️  飞书插件未启用"
fi

# 步骤5: 重启 Gateway
echo ""
echo "🔄 步骤5: 重启 Gateway..."

openclaw gateway restart 2>&1 | tee -a "$LOG_FILE"
sleep 8

# 验证
if nc -z -w 1 127.0.0.1 18789 2>/dev/null; then
    echo "✅ Gateway 重启成功"
    log "Gateway 重启成功"
else
    echo "⚠️  Gateway 可能未完全启动，请稍后检查"
fi

echo ""
echo "=========================================="
echo "  修复完成！"
echo "=========================================="
echo ""
echo "如仍有问题，请查看日志:"
echo "  tail -50 ~/.openclaw/logs/gateway.err.log"
echo ""


path: scripts/upgrade.sh
content: #!/bin/bash
# OpenClaw 一键升级脚本
# 功能：备份 + 升级 + 验证

set -e

BACKUP_DIR="$HOME/.openclaw/backups"
CONFIG_FILE="$HOME/.openclaw/openclaw.json"
LOG_FILE="$HOME/.openclaw/logs/upgrade.log"

mkdir -p "$BACKUP_DIR"
mkdir -p "$HOME/.openclaw/logs"

log() {
    echo "[$(date)] $1" | tee -a "$LOG_FILE"
}

echo "=========================================="
echo "  OpenClaw 一键升级"
echo "=========================================="
echo ""

# 获取当前版本
CURRENT_VERSION=$(openclaw --version 2>/dev/null | head -1 || echo "unknown")
log "当前版本: $CURRENT_VERSION"

# 步骤1: 备份配置
echo ""
echo "📦 步骤1: 备份配置..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# 备份主配置
if [ -f "$CONFIG_FILE" ]; then
    cp "$CONFIG_FILE" "$BACKUP_DIR/openclaw.json.bak.$TIMESTAMP"
    log "✅ 配置已备份: openclaw.json.bak.$TIMESTAMP"
fi

# 备份 auth
AUTH_FILE="$HOME/.openclaw/agents/main/agent/auth-profiles.json"
if [ -f "$AUTH_FILE" ]; then
    cp "$AUTH_FILE" "$BACKUP_DIR/auth-profiles.json.bak.$TIMESTAMP"
    log "✅ Auth 已备份"
fi

# 备份工作区关键文件
WORKSPACE="$HOME/.openclaw/workspace"
for file in MEMORY.md SOUL.md USER.md TOOLS.md AGENTS.md; do
    if [ -f "$WORKSPACE/$file" ]; then
        cp "$WORKSPACE/$file" "$BACKUP_DIR/$file.bak.$TIMESTAMP"
    fi
done
log "✅ 工作区文件已备份"

# 步骤2: 执行升级
echo ""
echo "⬆️  步骤2: 执行升级..."
log "开始升级..."

# 使用 gateway update 工具
echo "正在下载并安装最新版本，预计需要 3-5 分钟..."
npm i -g openclaw@latest --no-fund --no-audit --loglevel=error 2>&1 | tee -a "$LOG_FILE"

if [ ${PIPESTATUS[0]} -ne 0 ]; then
    echo "❌ npm 安装失败"
    log "npm 安装失败"
    exit 1
fi

NEW_VERSION=$(openclaw --version 2>/dev/null | head -1 || echo "unknown")
log "新版本: $NEW_VERSION"

# 重启 Gateway
echo ""
echo "🔄 重启 Gateway..."
openclaw gateway restart 2>&1 | tee -a "$LOG_FILE"

# 等待启动
echo "等待 Gateway 启动..."
sleep 10

# 步骤3: 验证
echo ""
echo "✅ 步骤3: 验证升级..."

# 检查版本
echo "当前版本: $NEW_VERSION"

# 检查进程
if pgrep -f "openclaw.*gateway" > /dev/null; then
    echo "✅ Gateway 进程运行中"
    log "✅ Gateway 运行正常"
else
    echo "⚠️  Gateway 进程未找到，尝试重新启动..."
    openclaw gateway start
    sleep 5
fi

# 检查端口
if nc -z -w 1 127.0.0.1 18789 2>/dev/null; then
    echo "✅ 端口 18789 监听正常"
else
    echo "⚠️  端口 18789 未监听"
fi

echo ""
echo "=========================================="
echo "  升级完成！"
echo "=========================================="
echo ""
echo "📊 版本: $CURRENT_VERSION → $NEW_VERSION"
echo "📦 备份位置: $BACKUP_DIR"
echo "📝 日志: $LOG_FILE"
echo ""
echo "⚠️  升级后请检查:"
echo "   1. 运行 post-upgrade-fix.sh 修复可能的问题"
echo "   2. 检查工具权限: check-permissions.sh"
echo ""


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