openclaw-workspace-sync 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.src.md CHANGED
@@ -1,31 +1,108 @@
1
- # OpenClaw Workspace Cloud Sync Plugin
1
+ # OpenClaw Workspace Sync & Backup Plugin
2
2
 
3
- Sync your OpenClaw agent workspace with cloud storage via [rclone](https://rclone.org/).
3
+ Sync and back up your OpenClaw agent workspace to cloud storage via [rclone](https://rclone.org/).
4
4
 
5
- Supports **Dropbox, Google Drive, OneDrive, S3/R2/Minio**, and [70+ cloud providers](https://rclone.org/overview/).
5
+ **Sync** your workspace to Dropbox, Google Drive, OneDrive, S3, or [70+ providers](https://rclone.org/overview/) with mailbox, mirror, or bisync modes. **Back up** your entire agent system — workspace, config, sessions, memory — as encrypted snapshots to S3, R2, B2, or any rclone backend.
6
6
 
7
- ## How it works
7
+ ## What's included
8
8
 
9
- <p align="center">
10
- <img src="https://raw.githubusercontent.com/ashbrener/openclaw-workspace-sync/main/docs/how-it-works.png" alt="How it works — Local Machine syncs to Cloud Provider syncs to Remote Gateway" width="600" />
11
- </p>
9
+ | Feature | What it does | Cost |
10
+ |---------|-------------|------|
11
+ | [**Sync**](#sync) | Live mirror of your workspace to/from cloud storage. Three modes: mailbox (safest), mirror, bisync. | Zero LLM cost — pure file ops |
12
+ | [**Encrypted Backup**](#encrypted-backups) | Streaming encrypted snapshots of your entire agent system to your own bucket. Automatic retention. | Zero LLM cost, zero extra disk |
13
+
14
+ Both features use rclone under the hood and share provider credentials. You can use sync alone, backup alone, or both together with different providers — e.g. sync to Dropbox for daily access, backup to R2 for disaster recovery.
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ openclaw plugins install openclaw-workspace-sync
20
+ ```
21
+
22
+ Or clone into your extensions directory:
23
+
24
+ ```bash
25
+ cd ~/.openclaw/extensions
26
+ git clone https://github.com/ashbrener/openclaw-workspace-sync workspace-sync
27
+ cd workspace-sync && npm install --omit=dev
28
+ ```
29
+
30
+ ## Quick start
31
+
32
+ ```bash
33
+ # Interactive setup wizard (recommended)
34
+ openclaw workspace-sync setup
35
+ ```
36
+
37
+ The setup wizard guides you through:
38
+ 1. Checking/installing rclone
39
+ 2. Selecting cloud provider
40
+ 3. Choosing sync mode
41
+ 4. Dropbox app folder option (for scoped access)
42
+ 5. Background sync interval
43
+ 6. OAuth authorization
44
+ 7. First sync
45
+
46
+ Or configure manually — see [Configuration](#configuration) below.
47
+
48
+ ## Configuration
49
+
50
+ Add to your `openclaw.json`. The `sync` and `backup` blocks are independent — use one or both:
51
+
52
+ ```json
53
+ {
54
+ "plugins": {
55
+ "entries": {
56
+ "openclaw-workspace-sync": {
57
+ "enabled": true,
58
+ "config": {
59
+ "sync": {
60
+ "provider": "dropbox",
61
+ "mode": "mailbox",
62
+ "remotePath": "",
63
+ "localPath": "/",
64
+ "interval": 180,
65
+ "onSessionStart": true,
66
+ "exclude": [".git/**", "node_modules/**", "*.log"]
67
+ },
68
+ "backup": {
69
+ "enabled": true,
70
+ "provider": "s3",
71
+ "bucket": "my-backups",
72
+ "prefix": "habibi/",
73
+ "interval": 86400,
74
+ "encrypt": true,
75
+ "passphrase": "${BACKUP_PASSPHRASE}",
76
+ "include": ["workspace", "config", "cron", "memory"],
77
+ "retain": 7
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ > **Flat format still works.** Putting `provider`, `mode`, etc. at the config root (without `sync`) is supported for backwards compatibility. The nested `{ sync, backup }` format is recommended for clarity.
12
87
 
13
- The remote gateway workspace is the **source of truth**. Changes made by the agent flow down to your local machine through cloud storage. You can send files to the agent through an optional inbox.
88
+ ---
14
89
 
15
- **Zero LLM cost.** All sync operations are pure rclone file operations — they never wake the bot or trigger LLM calls.
90
+ ## Sync
16
91
 
17
- ## Architecture
92
+ Live workspace mirroring via rclone. The remote gateway workspace is the **source of truth**. Changes made by the agent flow down to your local machine through cloud storage. You can send files to the agent through an optional inbox.
93
+
94
+ <p align="center">
95
+ <img src="https://raw.githubusercontent.com/ashbrener/openclaw-workspace-sync/main/docs/how-it-works.png" alt="How it works — Local Machine syncs to Cloud Provider syncs to Remote Gateway" width="600" />
96
+ </p>
18
97
 
19
98
  <p align="center">
20
99
  <img src="https://raw.githubusercontent.com/ashbrener/openclaw-workspace-sync/main/docs/architecture.png" alt="Plugin architecture — CLI, Hooks, and Sync Manager feed into rclone wrapper" width="600" />
21
100
  </p>
22
101
 
23
- ## Sync modes (breaking change in v2.0)
102
+ ### Sync modes (breaking change in v2.0)
24
103
 
25
104
  **`mode` is now required.** Previous versions used bidirectional bisync implicitly. Starting with v2.0, you must explicitly set `"mode"` in your config. The plugin will refuse to start and log an error until `mode` is set. This prevents accidental data loss from an unexpected sync direction.
26
105
 
27
- The plugin supports three sync modes. Choose the one that fits your workflow:
28
-
29
106
  | Mode | Direction | Description |
30
107
  |------|-----------|-------------|
31
108
  | `mailbox` | Push + inbox/outbox | Workspace pushes to cloud; users drop files in `_outbox` to send them to the agent. **Safest.** |
@@ -34,7 +111,7 @@ The plugin supports three sync modes. Choose the one that fits your workflow:
34
111
 
35
112
  **Upgrading from a previous version?** If you were using bisync before, add `"mode": "bisync"` to your config to preserve the existing behavior. For the safest option, use `"mode": "mailbox"`.
36
113
 
37
- ### `mailbox` mode (recommended)
114
+ #### `mailbox` mode (recommended)
38
115
 
39
116
  The agent workspace is the source of truth. Each sync cycle:
40
117
 
@@ -72,7 +149,7 @@ On startup, the plugin bootstraps both directories:
72
149
 
73
150
  Because the push explicitly excludes `_inbox/**` and `_outbox/**`, there is no risk of sync loops or accidental overwrites. Files only flow in one direction through each channel.
74
151
 
75
- #### Inbox notifications (optional)
152
+ ##### Inbox notifications (optional)
76
153
 
77
154
  By default, mailbox mode is silent — files land in `_inbox` without waking the agent. This keeps costs at zero.
78
155
 
@@ -95,7 +172,7 @@ This wakes the agent on its next heartbeat. The agent sees the message and can p
95
172
  }
96
173
  ```
97
174
 
98
- ### `mirror` mode
175
+ #### `mirror` mode
99
176
 
100
177
  The agent workspace is the source of truth. Every sync cycle copies the latest workspace state down to your local folder. Local files outside the workspace are never sent up.
101
178
 
@@ -117,7 +194,7 @@ flowchart LR
117
194
 
118
195
  This is safe: even if something goes wrong, only your local copy is affected — the workspace stays untouched.
119
196
 
120
- ### `ingest` option (mirror mode only)
197
+ ##### `ingest` option (mirror mode only)
121
198
 
122
199
  Want to send files to the agent while using mirror mode? Enable the `ingest` option. This creates a local `inbox/` folder (sibling to the sync folder) that syncs one-way **up** to the workspace. Drop a file in the inbox — it appears on the remote workspace. The inbox is separate from the mirror, so there is no risk of overwriting workspace files.
123
200
 
@@ -133,7 +210,7 @@ When enabled, a local `inbox/` folder syncs its contents to `<remotePath>/inbox/
133
210
 
134
211
  > For a more robust file-exchange pattern, consider `mailbox` mode instead. Mailbox uses `rclone move` to drain files (deleting from the source after transfer), which prevents duplicates and is easier to reason about.
135
212
 
136
- ### `bisync` mode (advanced)
213
+ #### `bisync` mode (advanced)
137
214
 
138
215
  Full bidirectional sync using rclone bisync. Changes on either side propagate to the other.
139
216
 
@@ -164,11 +241,99 @@ Use this only if you understand the trade-offs:
164
241
 
165
242
  If you are running on a container platform, `mailbox` mode is strongly recommended.
166
243
 
167
- ## Before your first sync
244
+ ### Sync config reference
245
+
246
+ | Key | Type | Default | Description |
247
+ |-----|------|---------|-------------|
248
+ | `provider` | string | `"off"` | `dropbox` \| `gdrive` \| `onedrive` \| `s3` \| `custom` \| `off` |
249
+ | `mode` | string | **required** | `mailbox` \| `mirror` \| `bisync` — see [Sync modes](#sync-modes-breaking-change-in-v20) |
250
+ | `ingest` | boolean | `false` | Enable local inbox for sending files to the agent (mirror mode only) |
251
+ | `ingestPath` | string | `"inbox"` | Local subfolder name for ingestion (relative to `localPath`) |
252
+ | `notifyOnInbox` | boolean | `false` | Wake the agent when files arrive in `_inbox` (mailbox mode). Off by default — enabling this costs LLM credits per notification. |
253
+ | `remotePath` | string | `"openclaw-share"` | Folder name in cloud storage |
254
+ | `localPath` | string | `"shared"` | Subfolder within workspace to sync |
255
+ | `interval` | number | `0` | Background sync interval in seconds (0 = manual only, min 60) |
256
+ | `timeout` | number | `1800` | Max seconds for a single rclone sync operation (min 60) |
257
+ | `onSessionStart` | boolean | `false` | Sync when an agent session begins |
258
+ | `onSessionEnd` | boolean | `false` | Sync when an agent session ends |
259
+ | `remoteName` | string | `"cloud"` | rclone remote name |
260
+ | `configPath` | string | auto | Path to rclone.conf |
261
+ | `conflictResolve` | string | `"newer"` | `newer` \| `local` \| `remote` (bisync only) |
262
+ | `exclude` | string[] | see below | Glob patterns to exclude |
263
+ | `copySymlinks` | boolean | `false` | Follow symlinks during sync |
264
+
265
+ Default excludes: `**/.DS_Store`
266
+
267
+ ### Sync CLI commands
268
+
269
+ ```bash
270
+ # Interactive setup wizard
271
+ openclaw workspace-sync setup
272
+
273
+ # Check sync status
274
+ openclaw workspace-sync status
275
+
276
+ # Sync (behavior depends on mode)
277
+ openclaw workspace-sync sync
278
+
279
+ # Preview changes without syncing
280
+ openclaw workspace-sync sync --dry-run
281
+
282
+ # One-way sync (explicit, overrides mode for this run)
283
+ openclaw workspace-sync sync --direction pull # remote -> local
284
+ openclaw workspace-sync sync --direction push # local -> remote
285
+
286
+ # Force re-establish bisync baseline (bisync mode only)
287
+ openclaw workspace-sync sync --resync
288
+
289
+ # Authorize with cloud provider
290
+ openclaw workspace-sync authorize
291
+ openclaw workspace-sync authorize --provider gdrive
292
+
293
+ # List remote files
294
+ openclaw workspace-sync list
295
+ ```
296
+
297
+ ### Auto-sync
298
+
299
+ #### Session hooks
300
+
301
+ Sync automatically when sessions start or end. These run during existing agent activity and incur zero LLM cost:
302
+
303
+ ```json
304
+ {
305
+ "onSessionStart": true,
306
+ "onSessionEnd": false
307
+ }
308
+ ```
309
+
310
+ #### Periodic background sync
311
+
312
+ Set `interval` to enable automatic background sync (in seconds):
313
+
314
+ ```json
315
+ {
316
+ "interval": 300,
317
+ "timeout": 3600
318
+ }
319
+ ```
320
+
321
+ The gateway runs sync in the background at this interval. Minimum interval is 60 seconds. The `timeout` controls how long each sync operation is allowed to run (default: 1800s / 30 min). Increase this for large workspaces or slow connections.
322
+
323
+ In `mailbox` mode, periodic sync pushes the workspace to the cloud and drains the `_outbox`. In `mirror` mode, periodic sync pulls the latest workspace state down to local. In `bisync` mode, it runs a full bidirectional sync.
324
+
325
+ #### External cron (alternative)
326
+
327
+ ```bash
328
+ # Add to crontab (crontab -e)
329
+ */5 * * * * openclaw workspace-sync sync >> /var/log/openclaw-sync.log 2>&1
330
+ ```
331
+
332
+ ### Before your first sync
168
333
 
169
334
  Getting the initial state right prevents data loss. Each mode has different requirements:
170
335
 
171
- ### `mailbox` mode — starting state
336
+ #### `mailbox` mode — starting state
172
337
 
173
338
  The first sync **pushes** your local workspace to the cloud. This means rclone makes cloud match local exactly — any files on cloud that don't exist locally will be **deleted**.
174
339
 
@@ -185,17 +350,17 @@ rclone sync <remote>:<path> /data/workspace/ --config <config-path> \
185
350
 
186
351
  Then verify local matches remote before enabling the plugin.
187
352
 
188
- ### `mirror` mode — starting state
353
+ #### `mirror` mode — starting state
189
354
 
190
355
  The first sync **pulls** from cloud to local. Local can be empty, stale, or corrupted — the pull simply overwrites it. **No preparation needed.**
191
356
 
192
- ### `bisync` mode — starting state
357
+ #### `bisync` mode — starting state
193
358
 
194
359
  The first sync requires `--resync`, which copies everything from both sides to the other. Any stale or unwanted files on either side will propagate.
195
360
 
196
361
  **Recommended starting state:** Both sides are identical, or one side is empty and the other has the data you want. Verify both before running `--resync`.
197
362
 
198
- ### General first-sync checklist
363
+ #### General first-sync checklist
199
364
 
200
365
  1. Run a `--dry-run` first to see what would happen: `openclaw workspace-sync sync --dry-run`
201
366
  2. Check the output for unexpected deletions
@@ -204,104 +369,254 @@ The first sync requires `--resync`, which copies everything from both sides to t
204
369
 
205
370
  > For maintenance, recovery, and common problems, see [TROUBLESHOOTING.md](./TROUBLESHOOTING.md).
206
371
 
207
- ## Setup sequence
372
+ ### Sync safety
373
+
374
+ Cloud sync involves two copies of your data. When things go wrong, one side can overwrite the other. Here is what to keep in mind:
208
375
 
209
- Getting sync right depends on doing things in the right order. Follow these steps:
376
+ **Mailbox mode is the safest.** The workspace pushes to the cloud; users send files via `_outbox`. The two streams never overlap. Even if your local folder is wiped, the next push re-creates everything. Even if the `_outbox` has stale files, they just land in `_inbox` for the agent to handle.
210
377
 
211
- 1. **Configure the plugin** in `openclaw.json` with your provider credentials and `mode`
212
- 2. **Verify the remote** is accessible: `openclaw workspace-sync status`
213
- 3. **Run a dry-run first** to see what would happen: `openclaw workspace-sync sync --dry-run`
214
- 4. **Run the first sync**: `openclaw workspace-sync sync`
215
- - In `mailbox` mode, this pushes the workspace and drains the `_outbox`
216
- - In `mirror` mode, this pulls the current workspace down
217
- - In `bisync` mode, this requires `--resync` to establish the baseline
218
- 5. **Enable periodic sync** by setting `interval` in your config
378
+ **Mirror mode is safe by design.** The remote workspace is the authority. Local is a read-only copy. Even if your local folder is empty, stale, or corrupted, the next sync just re-downloads the workspace. The agent's work is never affected by local state.
219
379
 
220
- Take care when changing config (switching `remotePath`, `localPath`, or `mode`) — always disable periodic sync first, verify the new paths, then re-enable.
380
+ **Bisync requires both sides to agree.** Bisync tracks what changed since the last sync. If that tracking state is lost (deploy, disk wipe, moving to a new machine), rclone does not know what changed and requires a `--resync`. A resync copies everything from both sides if one side has stale or unwanted files, they propagate to the other.
221
381
 
222
- ## Install
382
+ **Common pitfalls to avoid:**
383
+ - Changing `remotePath` or `localPath` while periodic sync is enabled
384
+ - Running `--resync` without checking both sides first
385
+ - Using `bisync` on container platforms where state is ephemeral
386
+ - Syncing very large directories (use `exclude` patterns liberally)
387
+
388
+ **If in doubt, use `mailbox` mode.** It gives you a live local mirror of the workspace and a clean way to send files to the agent, with no risk of data loss.
389
+
390
+ > For recovery procedures, mode switching, and maintenance tips, see [TROUBLESHOOTING.md](./TROUBLESHOOTING.md).
391
+
392
+ #### Important: `--resync` is destructive (bisync only)
393
+
394
+ **Never use `--resync` unless you know exactly what it does.** The `--resync` flag tells rclone to throw away its knowledge of what has changed and do a full reconciliation — it copies every file that exists on either side to the other side. This means:
395
+
396
+ - Files you deleted remotely will come back from local (and vice versa)
397
+ - It transfers your **entire** sync scope, not just recent changes
398
+ - On a large Dropbox, this can take 30+ minutes and fill your disk
399
+
400
+ Normal bisync (without `--resync`) only transfers files that changed since the last sync. The plugin **never** auto-resyncs. If bisync's internal state gets corrupted, it will log a message telling you to run `--resync` manually — but only do this after confirming both sides are in the state you want.
223
401
 
224
402
  ```bash
225
- openclaw plugins install openclaw-workspace-sync
403
+ # Only when you explicitly need to re-establish the baseline:
404
+ openclaw workspace-sync sync --resync
226
405
  ```
227
406
 
228
- Or clone into your extensions directory:
407
+ ### Sync troubleshooting
408
+
409
+ #### Token expired
229
410
 
230
411
  ```bash
231
- cd ~/.openclaw/extensions
232
- git clone https://github.com/ashbrener/openclaw-workspace-sync workspace-sync
233
- cd workspace-sync && npm install --omit=dev
412
+ openclaw workspace-sync authorize
234
413
  ```
235
414
 
236
- ## Quick start
415
+ #### Conflicts (bisync only)
416
+
417
+ Files modified on both sides get a `.conflict` suffix. The winner is determined by `conflictResolve` (default: `newer`). To find conflict files:
237
418
 
238
419
  ```bash
239
- # Interactive setup wizard (recommended)
240
- openclaw workspace-sync setup
420
+ find <workspace>/shared -name "*.conflict"
241
421
  ```
242
422
 
243
- The setup wizard guides you through:
244
- 1. Checking/installing rclone
245
- 2. Selecting cloud provider
246
- 3. Choosing sync mode
247
- 4. Dropbox app folder option (for scoped access)
248
- 5. Background sync interval
249
- 6. OAuth authorization
250
- 7. First sync
423
+ #### Stale lock files
251
424
 
252
- Or configure manually see [Configuration](#configuration) below.
425
+ The plugin automatically handles stale rclone lock files. If a sync is interrupted (timeout, crash, kill), the next run detects the stale lock, clears it, and retries. Lock files older than 15 minutes are treated as expired by rclone's `--max-lock` flag.
253
426
 
254
- ## Configuration
427
+ If you still see lock errors, you can manually clear them:
428
+
429
+ ```bash
430
+ rclone deletefile ~/.cache/rclone/bisync/<lockfile>.lck
431
+ ```
255
432
 
256
- Add to your `openclaw.json`:
433
+ #### Sync times out
434
+
435
+ Increase the `timeout` config (in seconds). The default is 1800 (30 min). For large workspaces:
257
436
 
258
437
  ```json
259
438
  {
260
- "plugins": {
261
- "entries": {
262
- "openclaw-workspace-sync": {
263
- "enabled": true,
264
- "config": {
265
- "provider": "dropbox",
266
- "mode": "mailbox",
267
- "remotePath": "",
268
- "localPath": "/",
269
- "interval": 60,
270
- "timeout": 1800,
271
- "onSessionStart": true,
272
- "onSessionEnd": false,
273
- "exclude": [".git/**", "node_modules/**", "*.log"]
274
- }
275
- }
276
- }
277
- }
439
+ "timeout": 3600
278
440
  }
279
441
  ```
280
442
 
281
- ### Config reference
443
+ #### Permission errors
444
+
445
+ ```bash
446
+ chmod -R 755 <workspace>/shared
447
+ ```
448
+
449
+ #### Dropbox rate limiting
450
+
451
+ Dropbox enforces API rate limits (`too_many_requests`). If your workspace has many files (10k+), each sync cycle can consume a large number of API calls just for checking. To avoid hitting limits:
452
+
453
+ - **Set `interval` high enough** for the sync to complete between cycles. A workspace with ~40k files takes ~2 minutes to scan. An `interval` of 180 (3 min) is the minimum; 300 (5 min) is safer.
454
+ - **Use `exclude` patterns liberally** — skip `node_modules`, `.git`, `__pycache__`, build output, and anything you don't need synced. Fewer files = fewer API calls.
455
+ - **If you see `too_many_requests` errors** in the logs, increase the interval and add more excludes.
456
+
457
+ ---
458
+
459
+ ## Encrypted backups
460
+
461
+ Back up your entire agent system — workspace, config, cron jobs, memory, sessions — as encrypted snapshots to your own cloud storage. Your bucket, your encryption key, zero monthly fees.
462
+
463
+ ### How it works
464
+
465
+ ```mermaid
466
+ flowchart TD
467
+ subgraph GW["Gateway"]
468
+ WS["/workspace"]
469
+ CFG["config / cron / memory"]
470
+ end
471
+ TAR["tar cz"]
472
+ ENC["openssl enc\n(AES-256)"]
473
+ RCAT["rclone rcat"]
474
+ subgraph REMOTE["Your Bucket (S3 / R2 / B2)"]
475
+ SNAP["backup-2026…Z.tar.gz.enc"]
476
+ OLD["older snapshots"]
477
+ end
478
+ WS --> TAR
479
+ CFG --> TAR
480
+ TAR -- "pipe" --> ENC
481
+ ENC -- "pipe" --> RCAT
482
+ RCAT --> SNAP
483
+ SNAP -. "retention prune" .-> OLD
484
+ ```
485
+
486
+ 1. **Streams directly** — `tar | [openssl enc] | rclone rcat` piped straight to the remote. Zero local temp files, zero extra disk needed. A 10 GB workspace on a 1 GB free volume? No problem.
487
+ 2. Optionally encrypts with AES-256 (client-side, before upload) via `openssl`
488
+ 3. Uploads via rclone to any supported provider (S3, R2, Backblaze B2, Dropbox, etc.)
489
+ 4. Prunes old snapshots based on your retention policy
490
+
491
+ > **Disk-constrained?** Because backups stream directly, you don't need any free disk space for the backup itself. Only the restore downloads to a staging directory.
492
+
493
+ ### Backup config reference
282
494
 
283
495
  | Key | Type | Default | Description |
284
496
  |-----|------|---------|-------------|
285
- | `provider` | string | `"off"` | `dropbox` \| `gdrive` \| `onedrive` \| `s3` \| `custom` \| `off` |
286
- | `mode` | string | **required** | `mailbox` \| `mirror` \| `bisync` — see [Sync modes](#sync-modes-breaking-change-in-v20) |
287
- | `ingest` | boolean | `false` | Enable local inbox for sending files to the agent (mirror mode only) |
288
- | `ingestPath` | string | `"inbox"` | Local subfolder name for ingestion (relative to `localPath`) |
289
- | `notifyOnInbox` | boolean | `false` | Wake the agent when files arrive in `_inbox` (mailbox mode). Off by default enabling this costs LLM credits per notification. |
290
- | `remotePath` | string | `"openclaw-share"` | Folder name in cloud storage |
291
- | `localPath` | string | `"shared"` | Subfolder within workspace to sync |
292
- | `interval` | number | `0` | Background sync interval in seconds (0 = manual only, min 60) |
293
- | `timeout` | number | `1800` | Max seconds for a single rclone sync operation (min 60) |
294
- | `onSessionStart` | boolean | `false` | Sync when an agent session begins |
295
- | `onSessionEnd` | boolean | `false` | Sync when an agent session ends |
296
- | `remoteName` | string | `"cloud"` | rclone remote name |
297
- | `configPath` | string | auto | Path to rclone.conf |
298
- | `conflictResolve` | string | `"newer"` | `newer` \| `local` \| `remote` (bisync only) |
299
- | `exclude` | string[] | see below | Glob patterns to exclude |
300
- | `copySymlinks` | boolean | `false` | Follow symlinks during sync |
497
+ | `enabled` | boolean | `false` | Enable scheduled backups |
498
+ | `provider` | string | parent provider | Cloud provider for backup storage |
499
+ | `bucket` | string | | S3/R2 bucket name |
500
+ | `prefix` | string | `""` | Path prefix within the bucket (e.g., `habibi/`) |
501
+ | `interval` | number | `86400` | Backup interval in seconds (86400 = daily; clamped to min 300) |
502
+ | `encrypt` | boolean | `false` | Encrypt snapshots with AES-256 before upload |
503
+ | `passphrase` | string | | Encryption passphrase (use `${BACKUP_PASSPHRASE}` env var) |
504
+ | `include` | string[] | see below | What to back up |
505
+ | `retain` | number or object | `7` | Retention: `7` = keep 7 latest, or `{ daily: 7, weekly: 4 }` |
506
+ | `exclude` | string[] | parent excludes | Glob patterns to exclude from workspace backup |
507
+
508
+ ### Include options
509
+
510
+ | Item | What gets backed up |
511
+ |------|---------------------|
512
+ | `workspace` | The workspace directory (agent files, projects, etc.) |
513
+ | `config` | `openclaw.json` |
514
+ | `cron` | Cron job schedules and state |
515
+ | `memory` | Memory files (MEMORY.md, etc.) |
516
+ | `sessions` | Session metadata and store |
517
+ | `credentials` | Auth profile credentials |
518
+ | `skills` | Skill files |
519
+ | `hooks` | Webhook configurations and state (Gmail watch, custom hooks) |
520
+ | `extensions` | Installed plugins/extensions (for reproducible restores) |
521
+ | `env` | Environment variables file (`.env`) |
522
+ | `agents` | Multi-agent state (per-agent sessions, subagent registry) |
523
+ | `pages` | Custom pages served by the gateway |
524
+ | `transcripts` | Full conversation logs (JSONL session transcripts) |
525
+
526
+ Default: `["workspace", "config", "cron", "memory"]`
527
+
528
+ ### Backup CLI commands
301
529
 
302
- Default excludes: `**/.DS_Store`
530
+ ```bash
531
+ # Create a backup now
532
+ openclaw workspace-sync backup now
533
+
534
+ # List available snapshots
535
+ openclaw workspace-sync backup list
536
+
537
+ # Restore the latest snapshot
538
+ openclaw workspace-sync backup restore
539
+
540
+ # Restore a specific snapshot
541
+ openclaw workspace-sync backup restore --snapshot backup-20260310T020000Z.tar.gz.enc
542
+
543
+ # Restore to a specific directory (safe — doesn't overwrite live data)
544
+ openclaw workspace-sync backup restore --to /tmp/restore-test
545
+
546
+ # Check backup service status
547
+ openclaw workspace-sync backup status
548
+ ```
549
+
550
+ ### Restore safety
551
+
552
+ By default, `restore` extracts to a staging directory (`~/.openclaw/.backup-restore/`), not directly over your live workspace. This lets you inspect the contents before copying them into place. Use `--to` to control where files land.
553
+
554
+ ### Backup provider examples
555
+
556
+ **Cloudflare R2 (free tier: 10GB):**
557
+
558
+ ```json
559
+ {
560
+ "backup": {
561
+ "enabled": true,
562
+ "provider": "s3",
563
+ "encrypt": true,
564
+ "passphrase": "${BACKUP_PASSPHRASE}",
565
+ "s3": {
566
+ "endpoint": "https://<account-id>.r2.cloudflarestorage.com",
567
+ "bucket": "openclaw-backups",
568
+ "region": "auto",
569
+ "accessKeyId": "${R2_ACCESS_KEY}",
570
+ "secretAccessKey": "${R2_SECRET_KEY}"
571
+ }
572
+ }
573
+ }
574
+ ```
575
+
576
+ **AWS S3:**
577
+
578
+ ```json
579
+ {
580
+ "backup": {
581
+ "enabled": true,
582
+ "provider": "s3",
583
+ "encrypt": true,
584
+ "passphrase": "${BACKUP_PASSPHRASE}",
585
+ "s3": {
586
+ "bucket": "my-openclaw-backups",
587
+ "region": "us-east-1",
588
+ "accessKeyId": "${AWS_ACCESS_KEY_ID}",
589
+ "secretAccessKey": "${AWS_SECRET_ACCESS_KEY}"
590
+ }
591
+ }
592
+ }
593
+ ```
594
+
595
+ **Backblaze B2:**
596
+
597
+ ```json
598
+ {
599
+ "backup": {
600
+ "enabled": true,
601
+ "provider": "s3",
602
+ "encrypt": true,
603
+ "passphrase": "${BACKUP_PASSPHRASE}",
604
+ "s3": {
605
+ "endpoint": "https://s3.us-west-002.backblazeb2.com",
606
+ "bucket": "openclaw-backups",
607
+ "region": "us-west-002",
608
+ "accessKeyId": "${B2_KEY_ID}",
609
+ "secretAccessKey": "${B2_APP_KEY}"
610
+ }
611
+ }
612
+ }
613
+ ```
303
614
 
304
- ### Provider-specific options
615
+ ---
616
+
617
+ ## Provider-specific options
618
+
619
+ These provider blocks work for both sync and backup. Place them inside the `sync` or `backup` config block as needed.
305
620
 
306
621
  **Dropbox with app folder (recommended for security):**
307
622
 
@@ -387,72 +702,7 @@ With `appFolder: true`, set `remotePath` to `""`. The app folder root is your sy
387
702
 
388
703
  The `custom` provider accepts any [rclone backend type](https://rclone.org/overview/) and passes `rcloneOptions` directly to the rclone config. This gives you config-driven access to all 70+ providers without manually editing `rclone.conf`.
389
704
 
390
- ## CLI commands
391
-
392
- ```bash
393
- # Interactive setup wizard
394
- openclaw workspace-sync setup
395
-
396
- # Check sync status
397
- openclaw workspace-sync status
398
-
399
- # Sync (behavior depends on mode)
400
- openclaw workspace-sync sync
401
-
402
- # Preview changes without syncing
403
- openclaw workspace-sync sync --dry-run
404
-
405
- # One-way sync (explicit, overrides mode for this run)
406
- openclaw workspace-sync sync --direction pull # remote -> local
407
- openclaw workspace-sync sync --direction push # local -> remote
408
-
409
- # Force re-establish bisync baseline (bisync mode only)
410
- openclaw workspace-sync sync --resync
411
-
412
- # Authorize with cloud provider
413
- openclaw workspace-sync authorize
414
- openclaw workspace-sync authorize --provider gdrive
415
-
416
- # List remote files
417
- openclaw workspace-sync list
418
- ```
419
-
420
- ## Auto-sync
421
-
422
- ### Session hooks
423
-
424
- Sync automatically when sessions start or end. These run during existing agent activity and incur zero LLM cost:
425
-
426
- ```json
427
- {
428
- "onSessionStart": true,
429
- "onSessionEnd": false
430
- }
431
- ```
432
-
433
- ### Periodic background sync
434
-
435
- Set `interval` to enable automatic background sync (in seconds):
436
-
437
- ```json
438
- {
439
- "interval": 300,
440
- "timeout": 3600
441
- }
442
- ```
443
-
444
- The gateway runs sync in the background at this interval. Minimum interval is 60 seconds. The `timeout` controls how long each sync operation is allowed to run (default: 1800s / 30 min). Increase this for large workspaces or slow connections.
445
-
446
- In `mailbox` mode, periodic sync pushes the workspace to the cloud and drains the `_outbox`. In `mirror` mode, periodic sync pulls the latest workspace state down to local. In `bisync` mode, it runs a full bidirectional sync.
447
-
448
- ### External cron (alternative)
449
-
450
- ```bash
451
- # Add to crontab (crontab -e)
452
- */5 * * * * openclaw workspace-sync sync >> /var/log/openclaw-sync.log 2>&1
453
- ```
454
-
455
- ## Supported providers
705
+ ### Supported providers
456
706
 
457
707
  | Provider | Config value | Auth method | Config-driven |
458
708
  |----------|-------------|-------------|---------------|
@@ -464,24 +714,7 @@ In `mailbox` mode, periodic sync pushes the workspace to the cloud and drains th
464
714
 
465
715
  All providers are fully config-driven — no manual `rclone.conf` editing needed. The `custom` provider gives access to all [70+ rclone backends](https://rclone.org/overview/) (SFTP, B2, Mega, pCloud, Azure Blob, etc.).
466
716
 
467
- ## Manual setup (without wizard)
468
-
469
- If you prefer to skip the interactive wizard, configure the plugin in `openclaw.json` and use the CLI:
470
-
471
- ```bash
472
- # 1. Authorize with your cloud provider
473
- openclaw workspace-sync authorize --provider dropbox
474
-
475
- # 2. Run a dry-run to preview what will sync
476
- openclaw workspace-sync sync --dry-run
477
-
478
- # 3. Run the first sync
479
- openclaw workspace-sync sync
480
- ```
481
-
482
- The plugin handles rclone installation, config generation, and token storage automatically based on your `openclaw.json` settings.
483
-
484
- ## Dropbox app folder access (recommended)
717
+ ### Dropbox app folder access (recommended)
485
718
 
486
719
  For better security, create a scoped Dropbox app that only accesses a single folder:
487
720
 
@@ -502,90 +735,7 @@ Benefits:
502
735
  - If token is compromised, blast radius is limited
503
736
  - Clean separation — sync folder lives under `Apps/<your-app-name>/`
504
737
 
505
- ### Dropbox rate limiting
506
-
507
- Dropbox enforces API rate limits (`too_many_requests`). If your workspace has many files (10k+), each sync cycle can consume a large number of API calls just for checking. To avoid hitting limits:
508
-
509
- - **Set `interval` high enough** for the sync to complete between cycles. A workspace with ~40k files takes ~2 minutes to scan. An `interval` of 180 (3 min) is the minimum; 300 (5 min) is safer.
510
- - **Use `exclude` patterns liberally** — skip `node_modules`, `.git`, `__pycache__`, build output, and anything you don't need synced. Fewer files = fewer API calls.
511
- - **If you see `too_many_requests` errors** in the logs, increase the interval and add more excludes.
512
-
513
- ## Understanding sync safety
514
-
515
- Cloud sync involves two copies of your data. When things go wrong, one side can overwrite the other. Here is what to keep in mind:
516
-
517
- **Mailbox mode is the safest.** The workspace pushes to the cloud; users send files via `_outbox`. The two streams never overlap. Even if your local folder is wiped, the next push re-creates everything. Even if the `_outbox` has stale files, they just land in `_inbox` for the agent to handle.
518
-
519
- **Mirror mode is safe by design.** The remote workspace is the authority. Local is a read-only copy. Even if your local folder is empty, stale, or corrupted, the next sync just re-downloads the workspace. The agent's work is never affected by local state.
520
-
521
- **Bisync requires both sides to agree.** Bisync tracks what changed since the last sync. If that tracking state is lost (deploy, disk wipe, moving to a new machine), rclone does not know what changed and requires a `--resync`. A resync copies everything from both sides — if one side has stale or unwanted files, they propagate to the other.
522
-
523
- **Common pitfalls to avoid:**
524
- - Changing `remotePath` or `localPath` while periodic sync is enabled
525
- - Running `--resync` without checking both sides first
526
- - Using `bisync` on container platforms where state is ephemeral
527
- - Syncing very large directories (use `exclude` patterns liberally)
528
-
529
- **If in doubt, use `mailbox` mode.** It gives you a live local mirror of the workspace and a clean way to send files to the agent, with no risk of data loss.
530
-
531
- > For recovery procedures, mode switching, and maintenance tips, see [TROUBLESHOOTING.md](./TROUBLESHOOTING.md).
532
-
533
- ## Important: `--resync` is destructive (bisync only)
534
-
535
- **Never use `--resync` unless you know exactly what it does.** The `--resync` flag tells rclone to throw away its knowledge of what has changed and do a full reconciliation — it copies every file that exists on either side to the other side. This means:
536
-
537
- - Files you deleted remotely will come back from local (and vice versa)
538
- - It transfers your **entire** sync scope, not just recent changes
539
- - On a large Dropbox, this can take 30+ minutes and fill your disk
540
-
541
- Normal bisync (without `--resync`) only transfers files that changed since the last sync. The plugin **never** auto-resyncs. If bisync's internal state gets corrupted, it will log a message telling you to run `--resync` manually — but only do this after confirming both sides are in the state you want.
542
-
543
- ```bash
544
- # Only when you explicitly need to re-establish the baseline:
545
- openclaw workspace-sync sync --resync
546
- ```
547
-
548
- ## Troubleshooting
549
-
550
- ### Token expired
551
-
552
- ```bash
553
- openclaw workspace-sync authorize
554
- ```
555
-
556
- ### Conflicts (bisync only)
557
-
558
- Files modified on both sides get a `.conflict` suffix. The winner is determined by `conflictResolve` (default: `newer`). To find conflict files:
559
-
560
- ```bash
561
- find <workspace>/shared -name "*.conflict"
562
- ```
563
-
564
- ### Stale lock files
565
-
566
- The plugin automatically handles stale rclone lock files. If a sync is interrupted (timeout, crash, kill), the next run detects the stale lock, clears it, and retries. Lock files older than 15 minutes are treated as expired by rclone's `--max-lock` flag.
567
-
568
- If you still see lock errors, you can manually clear them:
569
-
570
- ```bash
571
- rclone deletefile ~/.cache/rclone/bisync/<lockfile>.lck
572
- ```
573
-
574
- ### Sync times out
575
-
576
- Increase the `timeout` config (in seconds). The default is 1800 (30 min). For large workspaces:
577
-
578
- ```json
579
- {
580
- "timeout": 3600
581
- }
582
- ```
583
-
584
- ### Permission errors
585
-
586
- ```bash
587
- chmod -R 755 <workspace>/shared
588
- ```
738
+ ---
589
739
 
590
740
  ## Deployment recommendations
591
741
 
@@ -594,15 +744,15 @@ If you are running OpenClaw on a cloud container (Fly.io, Railway, Render) or a
594
744
  - **Use a separate persistent volume for the workspace.** Container root filesystems are ephemeral — a redeploy wipes everything. Mount a dedicated volume (e.g., Fly.io volumes, EBS, DigitalOcean block storage) at your workspace path so data survives deploys and restarts.
595
745
  - **Enable daily volume snapshots.** Most cloud providers offer automated snapshots (Fly.io does this by default with 5-day retention). If something goes wrong — a bad sync, accidental deletion, or a failed reorganization — a recent snapshot lets you restore in minutes instead of rebuilding from scratch.
596
746
  - **Test your restore process.** A backup you have never restored is a backup you do not have. Create a volume from a snapshot at least once to confirm the process works and you know the steps.
597
-
598
- These recommendations apply regardless of whether you use this plugin. Cloud sync adds convenience but is not a substitute for proper backups.
747
+ - **Use encrypted backups for off-site disaster recovery.** Volume snapshots protect against accidental deletes, but not against provider outages or account issues. Streaming encrypted backups to a separate provider (e.g., R2, B2) gives you a fully independent recovery path.
599
748
 
600
749
  ## Security notes
601
750
 
602
751
  - **Token storage**: rclone tokens are stored in `rclone.conf` with `0600` permissions
603
752
  - **Sensitive files**: Don't sync secrets, API keys, or credentials
604
- - **Encryption**: Consider [rclone crypt](https://rclone.org/crypt/) for sensitive data
753
+ - **Encryption**: Backups support AES-256 client-side encryption. For sync, consider [rclone crypt](https://rclone.org/crypt/) for sensitive data.
605
754
  - **App folder**: Use Dropbox app folder access for minimal permissions
755
+ - **Passphrase safety**: Use environment variables (`${BACKUP_PASSPHRASE}`) — never hardcode passphrases in config files
606
756
 
607
757
  ## Development
608
758