Skill: haha8d/agent-migrate (version 1.0.0)

--- name: agent-migrate description: "Cross-platform agent migration and deployment. Use when: (1) migrating OpenClaw agent to new servers, (2) backing up and restoring agent state, (3) deploying agent configurations across environments, (4) syncing workspace between development and production. NOT for: general file backup, non-agent data migration." --- # Agent Migration Migrate OpenClaw agents across servers and platforms while preserving identity, memory, and configuration. ## When to Use ✅ **USE this skill when:** - Moving agent from local machine to remote server - Cloning agent configuration to multiple environments - Backing up complete agent state for disaster recovery - Syncing workspace changes between dev/prod - Upgrading OpenClaw with full rollback capability ❌ **DON'T use when:** - Simple file copy operations → use `cp`/`rsync` directly - Database migrations → use database-specific tools - Non-OpenClaw application deployment ## Core Concepts ### Agent State Components ``` Agent State = Identity + Memory + Config + Skills + Extensions ├── workspace/ # Core identity files │ ├── IDENTITY.md # Who the agent is │ ├── USER.md # Who they serve │ ├── SOUL.md # Personality │ ├── MEMORY.md # Long-term memory │ ├── AGENTS.md # Operational rules │ ├── TOOLS.md # Environment notes │ └── memory/ # Daily logs ├── .openclaw/ │ ├── openclaw.json # Gateway config │ ├── agents/ # Session data │ └── extensions/ # Custom plugins └── skills/ # Custom skills (if any) ``` ### Migration Workflows #### 1. Export (Source Machine) ```bash # Full agent export ./scripts/export-agent.sh [export-name] # Creates: # /tmp/agent-export-[name]/ # ├── manifest.json # Export metadata # ├── workspace.tar.gz # Core files # ├── config.tar.gz # OpenClaw config # └── restore.sh # Self-contained restore ``` #### 2. Transfer ```bash # Via SSH scp -r /tmp/agent-export-[name] user@new-server:/tmp/ # Via GitHub (recommended for versioned deployments) # Push to repo, clone on target ``` #### 3. Import (Target Machine) ```bash # Run self-contained restore cd /tmp/agent-export-[name] && ./restore.sh # Or manual: ./scripts/import-agent.sh /tmp/agent-export-[name] ``` ## Scripts ### Export Agent ```bash scripts/export-agent.sh [name] [--full] ``` Options: - `name` - Export identifier (default: timestamp) - `--full` - Include session history and logs ### Import Agent ```bash scripts/import-agent.sh <export-path> [--merge|--replace] ``` Options: - `--merge` - Merge with existing agent (default) - `--replace` - Wipe existing, clean install ### Sync to GitHub ```bash scripts/sync-github.sh <repo-url> [--push|--pull] ``` Syncs agent state to GitHub for versioned deployment. ## Platform-Specific Notes ### Linux → Linux Direct transfer, no conversion needed. ### macOS → Linux - Check for macOS-specific paths in scripts - Update file watchers if used ### Windows WSL → Native Linux - Line endings auto-handled - Verify executable permissions ### Docker Deployment See `references/docker-deploy.md` for containerized deployment. ## Security Checklist - [ ] Sanitize `openclaw.json` (remove sensitive tokens before export) - [ ] Verify target machine permissions - [ ] Rotate any exposed credentials post-migration - [ ] Test agent functionality before production cutover ## Rollback Exports are immutable snapshots. To rollback: ```bash # Re-import previous export ./scripts/import-agent.sh /path/to/previous-export --replace ```

path: references/docker-deploy.md
content: # Docker 部署指南

在容器中运行 OpenClaw Agent。

## 快速开始

```dockerfile
FROM node:22-slim

# 安装 OpenClaw
RUN npm install -g openclaw

# 创建工作目录
WORKDIR /app

# 复制导出的 agent
COPY agent-export/ /app/agent/

# 恢复 agent
RUN cd /app/agent && ./restore.sh /root/.openclaw

# 暴露 Gateway 端口
EXPOSE 18789

# 启动
CMD ["openclaw", "gateway", "start"]
```

## 构建和运行

```bash
# 构建
docker build -t my-agent .

# 运行
docker run -d \
  -p 18789:18789 \
  -v agent-data:/root/.openclaw \
  --name my-agent \
  my-agent
```

## Docker Compose

```yaml
version: '3.8'
services:
  agent:
    build: .
    ports:
      - "18789:18789"
    volumes:
      - agent-data:/root/.openclaw
      - ./workspace:/root/.openclaw/workspace:rw
    environment:
      - OPENCLAW_GATEWAY_TOKEN=${GATEWAY_TOKEN}
    restart: unless-stopped

volumes:
  agent-data:
```

## 环境变量

| 变量 | 说明 |
|------|------|
| `OPENCLAW_GATEWAY_TOKEN` | Gateway 认证令牌 |
| `OPENCLAW_MODEL_API_KEY` | AI 模型 API 密钥 |
| `OPENCLAW_LOG_LEVEL` | 日志级别 (debug/info/warn) |

## 数据持久化

必须持久化的目录：
- `/root/.openclaw/workspace` - Agent 核心文件
- `/root/.openclaw/openclaw.json` - 配置文件

可选持久化：
- `/root/.openclaw/agents` - Session 历史
- `/root/.openclaw/backups` - 备份文件


path: scripts/export-agent.sh
content: #!/bin/bash
# export-agent.sh - 导出完整 Agent 状态
set -e

EXPORT_NAME="${1:-export_$(date +%Y%m%d_%H%M%S)}"
EXPORT_DIR="/tmp/agent-export-$EXPORT_NAME"
FULL_MODE=false

if [ "$2" == "--full" ]; then
    FULL_MODE=true
fi

echo "[EXPORT] 开始导出: $EXPORT_NAME"
mkdir -p "$EXPORT_DIR"

# 1. 导出 workspace
echo "  → 导出 workspace..."
tar czf "$EXPORT_DIR/workspace.tar.gz" -C /home/node/.openclaw workspace \
    --exclude='*.log' --exclude='node_modules' --exclude='.git' 2>/dev/null || true

# 2. 导出配置
echo "  → 导出配置..."
mkdir -p "$EXPORT_DIR/config"
cp /home/node/.openclaw/openclaw.json "$EXPORT_DIR/config/" 2>/dev/null || true

# 3. 导出自定义 skills（如果有）
if [ -d "/home/node/.openclaw/skills" ]; then
    echo "  → 导出自定义 skills..."
    tar czf "$EXPORT_DIR/skills.tar.gz" -C /home/node/.openclaw skills 2>/dev/null || true
fi

# 4. 导出 extensions（如果有）
if [ -d "/home/node/.openclaw/extensions" ]; then
    echo "  → 导出 extensions..."
    tar czf "$EXPORT_DIR/extensions.tar.gz" -C /home/node/.openclaw \
        --exclude='node_modules' --exclude='*.log' --exclude='dist' \
        extensions 2>/dev/null || true
fi

# 5. Full mode: 包含 session 数据
if [ "$FULL_MODE" = true ]; then
    echo "  → 导出 sessions (full mode)..."
    tar czf "$EXPORT_DIR/sessions.tar.gz" -C /home/node/.openclaw agents 2>/dev/null || true
fi

# 6. 创建清单
cat > "$EXPORT_DIR/manifest.json" << EOF
{
  "export_name": "$EXPORT_NAME",
  "export_time": "$(date -Iseconds)",
  "source_host": "$(hostname)",
  "openclaw_version": "$(openclaw status 2>>1 | head -5 | grep -i version || echo 'unknown')",
  "full_mode": $FULL_MODE,
  "components": {
    "workspace": true,
    "config": true,
    "skills": $(test -f "$EXPORT_DIR/skills.tar.gz" && echo true || echo false),
    "extensions": $(test -f "$EXPORT_DIR/extensions.tar.gz" && echo true || echo false),
    "sessions": $FULL_MODE
  }
}
EOF

# 7. 创建自恢复脚本
cat > "$EXPORT_DIR/restore.sh" << 'RESTORE_SCRIPT'
#!/bin/bash
# Self-contained restore script
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TARGET_DIR="${1:-$HOME/.openclaw}"

echo "[RESTORE] 恢复 Agent 到: $TARGET_DIR"
mkdir -p "$TARGET_DIR"

# 恢复 workspace
if [ -f "$SCRIPT_DIR/workspace.tar.gz" ]; then
    echo "  → 恢复 workspace..."
    tar xzf "$SCRIPT_DIR/workspace.tar.gz" -C "$TARGET_DIR"
fi

# 恢复配置
if [ -f "$SCRIPT_DIR/config/openclaw.json" ]; then
    echo "  → 恢复配置..."
    cp "$SCRIPT_DIR/config/openclaw.json" "$TARGET_DIR/"
fi

# 恢复 skills
if [ -f "$SCRIPT_DIR/skills.tar.gz" ]; then
    echo "  → 恢复 skills..."
    tar xzf "$SCRIPT_DIR/skills.tar.gz" -C "$TARGET_DIR"
fi

# 恢复 extensions
if [ -f "$SCRIPT_DIR/extensions.tar.gz" ]; then
    echo "  → 恢复 extensions..."
    tar xzf "$SCRIPT_DIR/extensions.tar.gz" -C "$TARGET_DIR"
fi

echo "[RESTORE] 完成. 请检查配置并运行: openclaw status"
RESTORE_SCRIPT

chmod +x "$EXPORT_DIR/restore.sh"

# 8. 打包最终导出
cd /tmp
FINAL_ARCHIVE="agent-export-$EXPORT_NAME.tar.gz"
tar czf "$FINAL_ARCHIVE" "agent-export-$EXPORT_NAME"

echo ""
echo "[EXPORT] 完成!"
echo "  导出目录: $EXPORT_DIR"
echo "  压缩包: /tmp/$FINAL_ARCHIVE"
echo ""
echo "传输到目标服务器:"
echo "  scp /tmp/$FINAL_ARCHIVE user@server:/tmp/"
echo ""
echo "在目标服务器恢复:"
echo "  tar xzf /tmp/$FINAL_ARCHIVE -C /tmp/"
echo "  cd /tmp/agent-export-$EXPORT_NAME && ./restore.sh"


path: scripts/sync-github.sh
content: #!/bin/bash
# sync-github.sh - 同步 Agent 最小化数据到 GitHub 私有仓库
set -e

REPO_URL="$1"
MODE="${2:-push}"
TEMP_DIR="/tmp/agent-sync-$(date +%s)"

if [ -z "$REPO_URL" ]; then
    echo "用法: $0 <repo-url> [--push|--pull]"
    echo "  示例: $0 [REDACTED_SECRET]:xiage/my-agent.git --push"
    exit 1
fi

echo "[SYNC] GitHub 同步: $MODE"
echo "  仓库: $REPO_URL"

# 清理
trap "rm -rf $TEMP_DIR" EXIT
mkdir -p "$TEMP_DIR"

if [ "$MODE" == "push" ]; then
    echo "  → 推送到 GitHub..."
    
    # 克隆仓库
    git clone "$REPO_URL" "$TEMP_DIR/repo" 2>/dev/null || {
        echo "  仓库不存在，初始化新仓库..."
        mkdir -p "$TEMP_DIR/repo"
        cd "$TEMP_DIR/repo"
        git init
        git remote add origin "$REPO_URL"
        # 创建 README
        echo "# Agent Backup" > README.md
        git add README.md
        git commit -m "init"
        git push -u origin HEAD:main 2>/dev/null || git push -u origin HEAD:master 2>/dev/null || true
    }
    
    cd "$TEMP_DIR/repo"
    
    # 创建最小化备份结构
    echo "  → 收集 Agent 数据..."
    mkdir -p agent-backup
    
    # 1. 核心身份文件
    echo "    - 核心配置文件"
    for file in IDENTITY.md USER.md SOUL.md AGENTS.md TOOLS.md MEMORY.md BOOTSTRAP.md HEARTBEAT.md; do
        if [ -f "/home/node/.openclaw/workspace/$file" ]; then
            cp "/home/node/.openclaw/workspace/$file" agent-backup/ 2>/dev/null || true
        fi
    done
    
    # 2. memory 目录
    if [ -d "/home/node/.openclaw/workspace/memory" ]; then
        echo "    - 记忆文件"
        cp -r "/home/node/.openclaw/workspace/memory" agent-backup/ 2>/dev/null || true
    fi
    
    # 3. 已安装 skills 清单（只存名字，不存内容）
    echo "    - skills 清单"
    ls /usr/local/lib/node_modules/openclaw/skills/ > agent-backup/installed-skills.txt 2>/dev/null || true
    
    # 4. 自定义 skills（如果有）
    if [ -d "/home/node/.openclaw/skills" ]; then
        echo "    - 自定义 skills"
        mkdir -p agent-backup/custom-skills
        cp /home/node/.openclaw/skills/*.skill agent-backup/custom-skills/ 2>/dev/null || true
    fi
    
    # 5. 配置模板（脱敏）
    echo "    - 配置模板（脱敏）"
    if [ -f "/home/node/.openclaw/openclaw.json" ]; then
        jq 'walk(if type == "object" then 
            with_entries(if .value | type == "string" and (contains("key") or contains("token") or contains("secret")) 
            then .value = "***REMOVED***" else . end) 
        else . end)' "/home/node/.openclaw/openclaw.json" > agent-backup/openclaw.json.template 2>/dev/null || \
            echo "{}" > agent-backup/openclaw.json.template
    fi
    
    # 6. 创建恢复脚本
    cat > agent-backup/restore.sh << 'EOF'
#!/bin/bash
# 恢复 Agent 最小化备份
set -e

TARGET="${1:-$HOME/.openclaw}"
echo "[RESTORE] 恢复 Agent 到: $TARGET"

mkdir -p "$TARGET/workspace"

# 恢复核心文件
echo "  → 恢复配置文件..."
for file in IDENTITY.md USER.md SOUL.md AGENTS.md TOOLS.md MEMORY.md BOOTSTRAP.md HEARTBEAT.md; do
    if [ -f "$file" ]; then
        cp "$file" "$TARGET/workspace/"
        echo "    ✓ $file"
    fi
done

# 恢复 memory
if [ -d "memory" ]; then
    echo "  → 恢复记忆..."
    cp -r memory "$TARGET/workspace/"
fi

# 恢复自定义 skills
if [ -d "custom-skills" ]; then
    echo "  → 恢复自定义 skills..."
    mkdir -p "$TARGET/skills"
    cp custom-skills/* "$TARGET/skills/" 2>/dev/null || true
fi

# 提示
if [ -f "installed-skills.txt" ]; then
    echo ""
    echo "  📋 已安装 skills 清单（需手动安装）:"
    cat installed-skills.txt | while read skill; do
        echo "     - $skill"
    done
fi

if [ -f "openclaw.json.template" ]; then
    echo ""
    echo "  ⚠️  请手动配置 openclaw.json（模板已保存）"
    cp openclaw.json.template "$TARGET/openclaw.json"
fi

echo ""
echo "[RESTORE] ✅ 完成"
echo "  下一步: 1) 配置 API keys  2) 安装 skills  3) openclaw status"
EOF
    chmod +x agent-backup/restore.sh
    
    # 7. 创建清单
    cat > agent-backup/MANIFEST.json << EOF
{
  "sync_time": "$(date -Iseconds)",
  "source": "$(whoami)@$(hostname)",
  "version": "$(openclaw status 2>>1 | grep -i 'openclaw' | head -1 | awk '{print $2}' || echo 'unknown')",
  "files": $(ls -1 agent-backup/*.md 2>/dev/null | xargs -n1 basename | jq -R . | jq -s .),
  "memory_files": $(ls -1 agent-backup/memory/*.md 2>/dev/null | wc -l),
  "custom_skills": $(ls -1 agent-backup/custom-skills/*.skill 2>/dev/null | wc -l)
}
EOF
    
    # 提交推送
    git add -A
    git commit -m "Agent backup: $(date '+%Y-%m-%d %H:%M:%S')" || true
    
    echo "  → 推送到远程..."
    git push origin HEAD:main 2>/dev/null || git push origin HEAD:master 2>/dev/null || {
        echo "  尝试强制推送..."
        git push --force origin HEAD:main 2>/dev/null || git push --force origin HEAD:master 2>/dev/null
    }
    
    echo "[SYNC] ✅ 推送完成"
    echo "  备份位置: $REPO_URL"
    
elif [ "$MODE" == "pull" ]; then
    echo "  → 从 GitHub 拉取..."
    
    git clone "$REPO_URL" "$TEMP_DIR/repo"
    cd "$TEMP_DIR/repo/agent-backup"
    
    ./restore.sh
    
    echo "[SYNC] ✅ 拉取完成"
fi


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