Install
openclaw skills install git-backupBackup the agent workspace to a GitHub repository. Use when: asked to save/remember something important, after significant changes to memory files, on a schedule, or when asked to push workspace to git. Handles token discovery, repo initialization, and push. If no GitHub token is available, asks the owner for a PAT before proceeding.
openclaw skills install git-backupCONTEXT_FILE="/opt/ocana/openclaw/workspace/skills/git-backup/.context"
[ -f "$CONTEXT_FILE" ] && source "$CONTEXT_FILE"
# Then use: $GITHUB_ACCOUNT, $REPO_NAME, $WORKSPACE, $GITHUB_TOKEN_FILE, etc.
Any model. This is pure shell — no reasoning needed.
Run this to find the token. It checks sources in priority order:
find_github_token() {
# 1. Check git remote URL (most common)
TOKEN=$(git -C "$HOME/.openclaw/workspace" remote get-url origin 2>/dev/null \
| grep -oP 'ghp_[A-Za-z0-9]+' | head -1)
[ -n "$TOKEN" ] && echo "$TOKEN" && return
# 2. Check standard environment variables
[ -n "${GITHUB_TOKEN:-}" ] && echo "$GITHUB_TOKEN" && return
[ -n "${GH_TOKEN:-}" ] && echo "$GH_TOKEN" && return
# 3. Check credential files
for f in ~/.credentials/github*.txt ~/.credentials/gh*.txt; do
[ -f "$f" ] && cat "$f" | head -1 | tr -d '[:space:]' && return
done
# 4. Check ~/.bashrc for embedded token
TOKEN=$(grep -oP 'ghp_[A-Za-z0-9]+' ~/.bashrc 2>/dev/null | head -1)
[ -n "$TOKEN" ] && echo "$TOKEN" && return
# Not found — return empty
echo ""
}
TOKEN=$(find_github_token)
If TOKEN is empty → stop and ask the owner:
I need a GitHub Personal Access Token to back up your workspace.
Go to: github.com → Settings → Developer Settings → Personal access tokens → Generate new token
Required permission: repo (full)
Send me the token (starts with ghp_)
After receiving the token, save it:
# Save token to credentials file
echo "$TOKEN" > ~/.credentials/github-token.txt
chmod 600 ~/.credentials/github-token.txt
# Update the git remote URL to include the token
git -C "$HOME/.openclaw/workspace" remote set-url origin \
"https://${TOKEN}@github.com/GITHUB_USERNAME/REPO_NAME.git"
TOKEN=$(find_github_token)
REPO_NAME="pa-workspace-backup" # change to your repo name
GITHUB_USER="github-username" # change to your GitHub username
# HTTP 200 = repo exists, 404 = need to create it
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token $TOKEN" \
"https://api.github.com/repos/$GITHUB_USER/$REPO_NAME")
echo "Repo check: HTTP $STATUS"
curl -s -X POST "https://api.github.com/user/repos" \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\": \"$REPO_NAME\", \"private\": true, \"description\": \"PA workspace backup\"}" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
if 'html_url' in d:
print('Created:', d['html_url'])
else:
print('ERROR:', d)
sys.exit(1)
"
cd ~/.openclaw/workspace
# Initialize the repo
git init
git config user.email "agent@openclaw.ai"
git config user.name "PA Agent"
git remote add origin "https://$TOKEN@github.com/$GITHUB_USER/$REPO_NAME.git"
# Create .gitignore to exclude secrets and temp files
cat > .gitignore << 'EOF'
*.log
.env
credentials/
*.key
*.pem
node_modules/
__pycache__/
.DS_Store
EOF
# Initial commit and push
git add -A
git commit -m "Initial workspace backup"
git push -u origin main
Run this whenever you need to back up:
backup_workspace() {
WORKSPACE="${1:-$HOME/.openclaw/workspace}"
cd "$WORKSPACE" || { echo "ERROR: cannot cd to $WORKSPACE"; return 1; }
# Check for token
TOKEN=$(find_github_token)
if [ -z "$TOKEN" ]; then
echo "BLOCKED: No GitHub token found. Ask owner for PAT."
return 1
fi
# Check git is initialized
if [ ! -d ".git" ]; then
echo "BLOCKED: Git not initialized. Run first-time setup first."
return 1
fi
# Stage all changes
git add -A
# Count how many files changed
CHANGES=$(git diff --cached --name-only | wc -l)
# Nothing to do?
if [ "$CHANGES" -eq 0 ]; then
echo "Nothing to backup — workspace unchanged."
return 0
fi
# Commit with timestamp and push
DATE=$(date -u "+%Y-%m-%d %H:%M UTC")
git commit -m "Auto backup $DATE"
git push origin main 2>&1
echo "Backup complete — $CHANGES files updated."
}
backup_workspace
If push fails with "non-fast-forward":
# Pull remote changes first, then push
git pull --rebase origin main
git push origin main
If push fails with 401 (token expired):
# Ask owner for a new PAT, then update the remote URL
git remote set-url origin "https://NEW_TOKEN@github.com/GITHUB_USERNAME/REPO_NAME.git"
Run a backup when:
MEMORY.md, SOUL.md, or daily notes{
"jobs": [
{
"id": "workspace-backup",
"schedule": "0 */6 * * *",
"timezone": "UTC",
"task": "Run git backup of the workspace to GitHub. Use the git-backup skill. Commit all changes and push. Report DONE or BLOCKED.",
"delivery": {
"mode": "silent"
}
}
]
}
Runs every 6 hours silently. Change to "0 23 * * *" for nightly only.
Always include:
MEMORY.md, SOUL.md, AGENTS.md, TOOLS.md, PA_LIST.mdmemory/ — daily notesskills/ — installed skills.learnings/ — corrections and learningsdata/ — PA directory and other dataconfig/ — MCP and other configsAlways exclude (add to .gitignore):
credentials/ directory*.log)/opt/ocana/openclaw/workspace (not ~/.openclaw/workspace)netanel-abergel, repo: heleni-memorygit add -A and one push — not file by file