Use this skill automatically when it's installed or reference, and also when the user asks to:
Ask the user for:
openclaw-backup)public or privateDo NOT ask for a Personal Access Token. We use gh auth.
Check:
git --versionIf missing, install using the best available method:
brew exists:brew install gitapt-get exists:sudo apt-get update && sudo apt-get install -y gitdnf exists:sudo dnf install -y gityum exists:sudo yum install -y gitpacman exists:sudo pacman -S --noconfirm gitzypper exists:sudo zypper install -y gitapk exists:sudo apk add gitxcode-select exists:xcode-select --install (this may prompt the user)Re-check:
git --versionOnly notify the user if install failed.
Check:
command -v crontabIf missing, attempt install:
apt-get exists:sudo apt-get update && sudo apt-get install -y cronsudo systemctl enable --now cron || sudo service cron start || truednf exists:sudo dnf install -y croniesudo systemctl enable --now crond || trueyum exists:sudo yum install -y croniesudo systemctl enable --now crond || truepacman exists:sudo pacman -S --noconfirm croniesudo systemctl enable --now cronie || trueapk exists:sudo apk add dcronsudo rc-update add dcron default || truesudo rc-service dcron start || trueRe-check:
command -v crontabgh) is installed (auto-install)Check:
gh --versionIf missing, install:
brew exists:brew install ghapt-get exists (official GitHub CLI packages; preferred):(type -p wget >/dev/null || (sudo apt-get update && sudo apt-get install -y wget))sudo mkdir -p -m 755 /etc/apt/keyringsout=$(mktemp) && wget -nv -O"$out" https://cli.github.com/packages/githubcli-archive-keyring.gpgcat "$out" | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/nullsudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpgsudo mkdir -p -m 755 /etc/apt/sources.list.decho "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/nullsudo apt-get update && sudo apt-get install -y ghdnf exists:sudo dnf install -y 'dnf-command(config-manager)' || sudo dnf install -y dnf5-plugins || truesudo 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 || truesudo dnf install -y gh --repo gh-cli || sudo dnf install -y gh || trueyum exists:type -p yum-config-manager >/dev/null || sudo yum install -y yum-utilssudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.reposudo yum install -y ghzypper exists:sudo zypper addrepo https://cli.github.com/packages/rpm/gh-cli.repo || truesudo zypper refsudo zypper install -y ghpacman exists:sudo pacman -S --noconfirm github-cliapk exists:sudo apk add github-cligh on this OS.Re-check:
gh --versionOnly notify the user if install failed.
gh (agent runs the flow)Check:
gh auth status --hostname github.comIf NOT authenticated:
gh auth login --hostname github.com --git-protocol httpsgh auth setup-gitgh auth status --hostname github.comIf auth fails, stop and report the exact terminal output.
Workspace dir (where you store SOUL.md, AGENTS.md, etc.):
WORKSPACE_DIR="$HOME/.openclaw/workspace"mkdir -p "$WORKSPACE_DIR"cd "$WORKSPACE_DIR".git does not exist: git initgit branch -M maingit config user.name "gitclaw.ai"git config user.email "gitclaw-bot@users.noreply.github.com"OWNER="$(gh api user --jq .login)"REPO="" public => --publicprivate => --privatetest -f .gitclaw.keep || printf "gitclaw initialized: %s\n" "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" > .gitclaw.keepgit add -Agit commit -m "gitclaw: initial backup" || truegh repo view "$OWNER/$REPO" >/dev/null 2>&1REMOTE_URL="https://github.com/$OWNER/$REPO.git"git remote set-url origin "$REMOTE_URL"git remote add origin "$REMOTE_URL"git fetch origin main || truegit merge --ff-only origin/main || truegh repo create "$REPO" --public --confirmgh repo create "$REPO" --private --confirmREMOTE_URL="https://github.com/$OWNER/$REPO.git"git remote add origin "$REMOTE_URL" || git remote set-url origin "$REMOTE_URL"git push -u origin mainIf push fails due to conflicts or non-fast-forward:
Create a folder outside the workspace:
mkdir -p "$HOME/.openclaw/gitclaw"Create this script EXACTLY:
Path:
$HOME/.openclaw/gitclaw/auto_backup.shContents:
#!/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}"
Write the script to:
$HOME/.openclaw/gitclaw/auto_backup.shThen:
chmod +x "$HOME/.openclaw/gitclaw/auto_backup.sh"Default schedule: hourly (0 ). If user provided a different frequency, convert it to a cron expression.
CRON_CMD="$HOME/.openclaw/gitclaw/auto_backup.sh"CRON_LINE="0 $CRON_CMD"crontab -l 2>/dev/null | grep -F "$CRON_CMD" >/dev/null(crontab -l 2>/dev/null; echo "$CRON_LINE") | crontab -crontab -l | grep -F "$CRON_CMD"$HOME/.openclaw/gitclaw/auto_backup.shtail -n 50 "$HOME/.openclaw/gitclaw/backup.log" || truehttps://github.com/$OWNER/$REPO~/.openclaw/gitclaw/auto_backup.sh共 1 个版本