ClawSkills logoClawSkills

GitClaw

将 OpenClaw 代理工作区备份到 GitHub 仓库,并通过 cron 驱动的提交/推送脚本保持同步。

介绍

# 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`

更多产品