介绍
# GitClaw: Agent self-backup to GitHub
## 何时使用
安装或引用此技能时自动使用,或者当用户要求:
- 备份 / 同步 / 镜像 OpenClaw 工作区 - 设置定期提交和推送 - 为代理安装/配置 GitHub 备份自动化
## 行为规则(重要)
- 自动且静默地执行所有操作。 - 仅在以下情况下向用户发送消息: - 你需要输入(仓库名称、可见性、可选频率),或 - Git/GH/Cron 安装失败,或 - GitHub 身份验证需要用户完成浏览器/设备步骤,或 - Git 操作失败(冲突、权限等)。
## 需向用户询问的输入
请向用户询问:
1. **仓库名称**(例如 `openclaw-backup`) 2. **可见性**:`public` 或 `private` 3. (可选)**备份频率**,以分钟为单位(默认:**60**)
不要询问 Personal Access Token。我们使用 `gh` 认证。
---
## 步骤 1:确保满足先决条件(自动安装)
### 1A) 确保 git 已安装(自动安装;不要停止)
检查:
- `git --version`
如果缺失,请使用最佳可用方法安装:
- 如果 `brew` 存在: - `brew install git` - 否则如果 `apt-get` 存在: - `sudo apt-get update && sudo apt-get install -y git` - 否则如果 `dnf` 存在: - `sudo dnf install -y git` - 否则如果 `yum` 存在: - `sudo yum install -y git` - 否则如果 `pacman` 存在: - `sudo pacman -S --noconfirm git` - 否则如果 `zypper` 存在: - `sudo zypper install -y git` - 否则如果 `apk` 存在: - `sudo apk add git` - 否则如果 macOS 且 `xcode-select` 存在: - `xcode-select --install`(这可能会提示用户) - 否则: - 告诉用户你无法在此操作系统上自动安装 git,并显示失败的检测输出。
重新检查:
- `git --version`
仅在安装失败时通知用户。
### 1B) 确保 cron/crontab 可用(尽力自动安装)
检查:
- `command -v crontab`
如果缺失,尝试安装:
- 如果 `apt-get` 存在: - `sudo apt-get update && sudo apt-get install -y cron` - `sudo systemctl enable --now cron || sudo service cron start || true` - 否则如果 `dnf` 存在: - `sudo dnf install -y cronie` - `sudo systemctl enable --now crond || true` - 否则如果 `yum` 存在: - `sudo yum install -y cronie` - `sudo systemctl enable --now crond || true` - 否则如果 `pacman` 存在: - `sudo pacman -S --noconfirm cronie` - `sudo systemctl enable --now cronie || true` - 否则如果 `apk` 存在: - `sudo apk add dcron` - `sudo rc-update add dcron default || true` - `sudo rc-service dcron start || true` - 否则: - 如果你无法安装,请告诉用户调度需要 cron。
重新检查:
- `command -v crontab`
---
## 步骤 2:确保 GitHub CLI (`gh`) 已安装(自动安装)
检查:
- `gh --version`
如果缺失,安装:
- 如果 `brew` 存在: - `brew install gh`
- 否则如果 `apt-get` 存在(官方 GitHub CLI 包;首选): - 使用官方 apt 仓库步骤安装: - `(type -p wget >/dev/null || (sudo apt-get update && sudo apt-get install -y wget))` - `sudo mkdir -p -m 755 /etc/apt/keyrings` - `out=$(mktemp) && wget -nv -O"$out" https://cli.github.com/packages/githubcli-archive-keyring.gpg` - `cat "$out" | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null` - `sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg` - `sudo mkdir -p -m 755 /etc/apt/sources.list.d` - `echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null` - `sudo apt-get update && sudo apt-get install -y gh`
- 否则如果 `dnf` 存在: - `sudo dnf install -y 'dnf-command(config-manager)' || sudo dnf install -y dnf5-plugins || true` - `sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo || sudo dnf config-manager addrepo --from-repofile=https://cli.github.com/packages/rpm/gh-cli.repo || true` - `sudo dnf install -y gh --repo gh-cli || sudo dnf install -y gh || true`
- 否则如果 `yum` 存在: - `type -p yum-config-manager >/dev/null || sudo yum install -y yum-utils` - `sudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo` - `sudo yum install -y gh`
- 否则如果 `zypper` 存在: - `sudo zypper addrepo https://cli.github.com/packages/rpm/gh-cli.repo || true` - `sudo zypper ref` - `sudo zypper install -y gh`
- 否则如果 `pacman` 存在: - `sudo pacman -S --noconfirm github-cli`
- 否则如果 `apk` 存在: - `sudo apk add github-cli`
- 否则: - 告诉用户你无法在此操作系统上自动安装 `gh`。
重新检查:
- `gh --version`
仅在安装失败时通知用户。
---
## 步骤 3:确保用户已在 `gh` 中通过身份验证(代理运行流程)
检查:
- `gh auth status --hostname github.com`
如果未通过身份验证:
1. 运行: - `gh auth login --hostname github.com --git-protocol https`
2. 终端流程将显示一次性代码并要求用户授权。 - 告诉用户在浏览器中打开 **https://github.com/login/device** 并输入终端中显示的代码,然后授权。
3. 登录后: - `gh auth setup-git`
4. 再次验证: - `gh auth status --hostname github.com`
如果身份验证失败,停止并报告确切的终端输出。
---
## 步骤 4:在 OpenClaw 工作区中初始化 git 并连接/创建仓库
工作区目录(你存储 SOUL.md、AGENTS.md 等的地方):
- 示例(路径在你的环境中可能不同):`WORKSPACE_DIR="$HOME/.openclaw/workspace"`
1. 确保工作区存在: - `mkdir -p "$WORKSPACE_DIR"` - `cd "$WORKSPACE_DIR"`
2. 如有必要,初始化仓库: - 如果 `.git` 不存在:`git init` - `git branch -M main`
3. 配置确定性提交身份(仅本地): - `git config user.name "gitclaw.ai"` - `git config user.email "[email protected]"`
4. 确定已通过身份验证的 GitHub 用户名(所有者): - `OWNER="$(gh api user --jq .login)"` - (除非需要调试,否则不要打印)
5. 仓库名称和可见性: - `REPO="<来自用户的仓库名称>"` - 可见性: - `public` => `--public` - `private` => `--private`
6. 确保至少存在一个提交(首次推送/cron 所需): - 如有必要创建一个微小的标记文件: - `test -f .gitclaw.keep || printf "gitclaw initialized: %s\n" "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" > .gitclaw.keep` - `git add -A` - `git commit -m "gitclaw: initial backup" || true`
7. 创建或重用目标仓库: - 如果它存在: - `gh repo view "$OWNER/$REPO" >/dev/null 2>&1` - 设置远程: - `REMOTE_URL="https://github.com/$OWNER/$REPO.git"` - 如果 origin 存在:`git remote set-url origin "$REMOTE_URL"` - 否则:`git remote add origin "$REMOTE_URL"` - 尝试快进同步(避免覆盖远程历史记录): - `git fetch origin main || true` - `git merge --ff-only origin/main || true` - 如果它不存在: - 以非交互方式创建它并进行连接: - 公开: - `gh repo create "$REPO" --public --confirm` - 私有: - `gh repo create "$REPO" --private --confirm` - 设置远程: - `REMOTE_URL="https://github.com/$OWNER/$REPO.git"` - `git remote add origin "$REMOTE_URL" || git remote set-url origin "$REMOTE_URL"`
8. 初始推送: - `git push -u origin main`
如果由于冲突或非快进而导致推送失败:
- 不要自动强制推送。 - 报告确切错误并停止(需要用户决定)。
---
## 步骤 5:安装确定性备份脚本(无 AI / 无心跳)
在工作区外创建一个文件夹:
- `mkdir -p "$HOME/.openclaw/gitclaw"`
精确创建此脚本:
路径:
- `$HOME/.openclaw/gitclaw/auto_backup.sh`
内容:
```bash #!/usr/bin/env bash set -euo pipefail
# GitClaw deterministic backup (no AI) export PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:$PATH"
WORKSPACE_DIR="${HOME}/.openclaw/workspace" STATE_DIR="${HOME}/.openclaw/gitclaw" LOG_FILE="${STATE_DIR}/backup.log" LOCK_DIR="${STATE_DIR}/lock"
mkdir -p "${STATE_DIR}"
timestamp() { date -u '+%Y-%m-%dT%H:%M:%SZ'; }
# Simple lock to prevent overlapping runs if ! mkdir "${LOCK_DIR}" 2>/dev/null; then echo "$(timestamp) Skip: already running." >> "${LOG_FILE}" exit 0 fi trap 'rmdir "${LOCK_DIR}" >/dev/null 2>&1 || true' EXIT
if ! command -v git >/dev/null 2>&1; then echo "$(timestamp) ERROR: git not found on PATH. Install git first." >> "${LOG_FILE}" exit 2 fi
if [ ! -d "${WORKSPACE_DIR}/.git" ]; then echo "$(timestamp) ERROR: ${WORKSPACE_DIR} is not a git repo. Run GitClaw setup first." >> "${LOG_FILE}" exit 3 fi
cd "${WORKSPACE_DIR}"
# Stage everything git add -A
# If nothing staged, exit quietly if git diff --cached --quiet; then echo "$(timestamp) No changes." >> "${LOG_FILE}" exit 0 fi
# Commit + push git commit -m "gitclaw backup: $(timestamp)" >> "${LOG_FILE}" 2>&1 git push origin main >> "${LOG_FILE}" 2>&1
echo "$(timestamp) Backup OK." >> "${LOG_FILE}" ```
将脚本写入:
- `$HOME/.openclaw/gitclaw/auto_backup.sh`
然后:
- `chmod +x "$HOME/.openclaw/gitclaw/auto_backup.sh"`
---
## 步骤 6:配置 crontab(幂等)
默认计划:每小时(`0 * * * *`)。如果用户提供了不同的频率,请将其转换为 cron 表达式。
1. 定义:
- `CRON_CMD="$HOME/.openclaw/gitclaw/auto_backup.sh"` - `CRON_LINE="0 * * * * $CRON_CMD"`
2. 无重复安装:
- `crontab -l 2>/dev/null | grep -F "$CRON_CMD" >/dev/null` - 如果未找到,追加: - `(crontab -l 2>/dev/null; echo "$CRON_LINE") | crontab -`
3. 确认:
- `crontab -l | grep -F "$CRON_CMD"`
---
## 步骤 7:最终验证
1. 运行一次:
- `$HOME/.openclaw/gitclaw/auto_backup.sh`
2. 显示日志:
- `tail -n 50 "$HOME/.openclaw/gitclaw/backup.log" || true`
3. 告诉用户:
- 仓库:`https://github.com/$OWNER/$REPO` - 计划:每小时(或选择的频率) - 脚本路径:`~/.openclaw/gitclaw/auto_backup.sh`