Skip to content

feat: add git-based workspace backup#131

Open
dev01lay2 wants to merge 19 commits intodevelopfrom
feat/git-workspace-backup
Open

feat: add git-based workspace backup#131
dev01lay2 wants to merge 19 commits intodevelopfrom
feat/git-workspace-backup

Conversation

@dev01lay2
Copy link
Collaborator

@dev01lay2 dev01lay2 commented Mar 17, 2026

Summary

Based on OpenClaw docs: Git backup (recommended, private), optimizes ClawPal's backup of managed OpenClaw instances in two ways:

  1. Fix: existing copy-based backup now includes workspace (was missing entirely on remote, partially on local)
  2. Feature: adds git-based workspace backup as the docs-recommended approach

Context

ClawPal manages OpenClaw instances (local or remote via SSH). The backup feature protects instance data before upgrades. The workspace (~/.openclaw/workspace) contains the agent's memory and personality files (AGENTS.md, SOUL.md, USER.md, memory/, skills/) — the most important data to back up.

Before this PR:

  • Remote backup: only copied openclaw.json + agents/ + memory/ (wrong path) — workspace not backed up
  • Local backup: copied ~/.openclaw/ recursively — workspace included only if at default path
  • No git integration

Changes

1. Fix copy-based backup to include workspace

remote_backup_before_upgrade: reads workspace path from remote openclaw.json (agents.defaults.workspace), copies it to backup/workspace/

remote_restore_from_backup: restores workspace from backup, resolving target path from config

backup_before_upgrade (local): also copies workspace when configured outside ~/.openclaw/ (custom path), skips .git dir

restore_from_backup (local): restores workspace to custom path if backed up separately

2. Git-based workspace backup (new feature)

Core layer (clawpal-core/src/backup.rs):

  • WorkspaceGitStatus struct — repo state tracking (branch, remote URL, uncommitted count, ahead/behind, last commit)
  • Shell command builders for git probe, commit+push, init+.gitignore
  • WORKSPACE_GITIGNORE matching docs recommendation
  • 7 new unit tests

Tauri commands (src-tauri/src/commands/backup.rs):

  • workspace_git_status / remote_workspace_git_status — probe git state on managed instance
  • workspace_git_backup / remote_workspace_git_backup — commit + push
  • workspace_git_init / remote_workspace_git_init — init repo + .gitignore

Both local and remote paths follow the same dispatch pattern as existing backup commands.

Frontend (WorkspaceGitBackup.tsx):

  • Status card: branch, remote URL, uncommitted changes (amber ⚠) / clean (green ✓)
  • "Sync Now" button — git add + commit + push
  • "Initialize Git" for non-git workspaces
  • Integrated into BackupsPanel above copy-based backups
  • i18n (en + zh)

Testing

  • cargo test -p clawpal-core --lib backup — 18/18 pass (7 new + 11 existing)
  • npx tsc --noEmit — zero TypeScript errors

@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

📊 Test Coverage Report

Metric Base (develop) PR (feat/git-workspace-backup) Delta
Lines 74.34% (6134/8251) 74.70% (6255/8373) 🟢 +0.36%
Functions 68.88% (704/1022) 69.22% (715/1033) 🟢 +0.34%
Regions 75.86% (10156/13388) 76.13% (10318/13554) 🟢 +0.27%

Coverage measured by cargo llvm-cov (clawpal-core + clawpal-cli).

@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

📦 PR Build Artifacts

Platform Download Size
Windows-x64 📥 clawpal-Windows-x64 24.8 MB
Linux-x64 📥 clawpal-Linux-x64 102.9 MB
macOS-x64 📥 clawpal-macOS-x64 13.0 MB
macOS-ARM64 📥 clawpal-macOS-ARM64 12.3 MB

🔨 Built from c6ef47f · View workflow run
⚠️ Unsigned development builds — for testing only

cjs and others added 16 commits March 18, 2026 09:40
- Use gh CLI to get release body (avoids shell escaping issues)
- Use jq for proper JSON construction
- Skip .sig and latest.json files
- Use HTTP/1.1 for large file upload stability
- Detect user timezone to determine if likely in China
- CN users fetch release assets from GitLab (lay2dev/clawpal)
- Other users fetch from GitHub as before
- Falls back to secondary source if primary fails
- Add canonical, Open Graph, Twitter Card meta tags
- Add SoftwareApplication JSON-LD schema
- Add robots.txt with AI crawler permissions
- Add llms.txt for AI search engines
- Add sitemap.xml
- Improve meta description for better CTR
- Redirect clawpal.zhixian.io to clawpal.xyz (301)
- Redirect clawpal.pages.dev to clawpal.xyz (301)
- Fixes GSC 'Google 选择的规范网页与用户指定的不同' issue
- 1200x630 hero section screenshot
- Fixes broken social preview cards
Based on https://docs.openclaw.ai/concepts/agent-workspace#git-backup-recommended-private

Core layer (clawpal-core/src/backup.rs):
- WorkspaceGitStatus struct with repo/remote/branch/uncommitted/ahead/behind tracking
- Shell command builders: git status probe, git add+commit+push, git init+.gitignore
- WORKSPACE_GITIGNORE constant matching docs recommendation
- 7 new tests (parse_workspace_git_status, build_* commands)

Tauri commands (src-tauri/src/commands/backup.rs):
- workspace_git_status / remote_workspace_git_status
- workspace_git_backup / remote_workspace_git_backup (add+commit+push)
- workspace_git_init / remote_workspace_git_init (init+.gitignore)
- Workspace path resolution from config (agents.defaults.workspace)

Frontend:
- WorkspaceGitBackup component: status card with branch/remote/uncommitted
  indicators, sync button, and git init flow for uninitialized workspaces
- Integrated into BackupsPanel above existing copy-based backups
- API bindings + dispatch wrappers with cache invalidation
- i18n (en + zh) for all git backup strings
read_openclaw_config signature changed to accept &OpenClawPaths instead of
&PathBuf after the harness Phase 3 refactor. Update the backup module call
site to match.
The existing remote backup (remote_backup_before_upgrade) only copied
config + agents/, missing the workspace entirely. The local backup
covered workspace only when it was at the default path inside ~/.openclaw/.

Changes:
- remote_backup_before_upgrade: resolve workspace path from remote
  config (agents.defaults.workspace), copy it to backup/workspace/
- remote_restore_from_backup: restore workspace from backup if present,
  resolving the target path from config
- backup_before_upgrade (local): also copy workspace when it lives
  outside ~/.openclaw/ (custom workspace path), skip .git dir
- restore_from_backup (local): restore workspace to custom path if
  backed up separately
read_openclaw_config signature changed to accept &OpenClawPaths instead
of &PathBuf. Update both call sites (lines 266 and 358) to pass &paths
directly, matching the existing call at line 423.
@dev01lay2 dev01lay2 force-pushed the feat/git-workspace-backup branch from e5d12bf to de632dd Compare March 18, 2026 09:43
@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2026

📏 Metrics Gate Report

Status: ✅ All gates passed

Commit Size ❌

Metric Value Limit Status
Commits checked 19
All within limit 18/19 ≤ 500 lines
Largest commit 862 lines ≤ 500

Bundle Size ✅

Metric Value Limit Status
JS bundle (raw) 921 KB
JS bundle (gzip) 289 KB ≤ 512 KB
JS initial load (gzip) 165 KB ℹ️

Perf Metrics E2E ✅

Metric Value Limit Status
Tests 10 passed, 0 failed 0 failures
RSS (test process) 3.3 MB ≤ 80 MB
VMS (test process) 269.9 MB ℹ️
Command P50 latency 0 ms ℹ️
Command P95 latency 0 ms ≤ 100 ms
Command max latency 0 ms ℹ️

Command Perf (local) ✅

Metric Value Status
Tests 4 passed, 0 failed
Commands measured 5 ℹ️
RSS (test process) 4.5 MB ℹ️
Local command timings
Command P50 P95 Max
local_openclaw_config_exists 0 0 0
list_ssh_hosts 0 0 0
get_app_preferences 0 0 0
read_app_log 0 0 0
read_error_log 0 0 0

Command Perf (remote SSH) ✅

Metric Value Status
SSH transport OK
Command failures 12/15 runs ⚠️ expected in Docker
Remote command timings (via Docker SSH)
Command Median Max
openclaw_status 1856 ms 2527 ms
cat__root_.openclaw_openclaw.json 237 ms 238 ms
openclaw_gateway 1987 ms 2048 ms
openclaw_cron 1883 ms 1896 ms
openclaw_agent 1984 ms 2084 ms

Home Page Render Probes ✅

Probe Value Limit Status
status 8 ms ℹ️
version 9 ms ℹ️
agents 9 ms ℹ️
models 68 ms ℹ️
settled 9 ms < 5000 ms

Code Readability (informational)

File Lines Target Status
commands/mod.rs 230 ≤ 2000
App.tsx 1737 ≤ 500 ⚠️
Files > 500 lines 29 trend ↓ ℹ️

📊 Metrics defined in docs/architecture/metrics.md

The function body after format!() was incorrectly indented inside a
non-existent closure, with an extra }) closing delimiter at line 163.
Fix indentation and remove the unmatched bracket.
… backup.rs

- Remove duplicate list_backups and restore_from_backup definitions that were
  accidentally nested inside backup_before_upgrade
- Add missing closing brace for if let Some(ws_str) block
- Add missing }) for timed_sync! macro in restore_from_backup
- Fix read_openclaw_config call to pass &paths instead of &paths.config_path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant