openclaw-workspace-sync 2.3.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.md +282 -329
- package/README.src.md +282 -329
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +88 -25
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,31 +1,108 @@
|
|
|
1
|
-
# OpenClaw Workspace
|
|
1
|
+
# OpenClaw Workspace Sync & Backup Plugin
|
|
2
2
|
|
|
3
|
-
Sync your OpenClaw agent workspace
|
|
3
|
+
Sync and back up your OpenClaw agent workspace to cloud storage via [rclone](https://rclone.org/).
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
##
|
|
7
|
+
## What's included
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
+
```
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
Or clone into your extensions directory:
|
|
14
23
|
|
|
15
|
-
|
|
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
|
+
```
|
|
16
29
|
|
|
17
|
-
##
|
|
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.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Sync
|
|
91
|
+
|
|
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
|
-
|
|
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
|
-
|
|
114
|
+
#### `mailbox` mode (recommended)
|
|
38
115
|
|
|
39
116
|
The agent workspace is the source of truth. Each sync cycle:
|
|
40
117
|
|
|
@@ -56,7 +133,7 @@ On startup, the plugin bootstraps both directories:
|
|
|
56
133
|
|
|
57
134
|
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.
|
|
58
135
|
|
|
59
|
-
|
|
136
|
+
##### Inbox notifications (optional)
|
|
60
137
|
|
|
61
138
|
By default, mailbox mode is silent — files land in `_inbox` without waking the agent. This keeps costs at zero.
|
|
62
139
|
|
|
@@ -79,7 +156,7 @@ This wakes the agent on its next heartbeat. The agent sees the message and can p
|
|
|
79
156
|
}
|
|
80
157
|
```
|
|
81
158
|
|
|
82
|
-
|
|
159
|
+
#### `mirror` mode
|
|
83
160
|
|
|
84
161
|
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.
|
|
85
162
|
|
|
@@ -89,7 +166,7 @@ The agent workspace is the source of truth. Every sync cycle copies the latest w
|
|
|
89
166
|
|
|
90
167
|
This is safe: even if something goes wrong, only your local copy is affected — the workspace stays untouched.
|
|
91
168
|
|
|
92
|
-
|
|
169
|
+
##### `ingest` option (mirror mode only)
|
|
93
170
|
|
|
94
171
|
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.
|
|
95
172
|
|
|
@@ -105,7 +182,7 @@ When enabled, a local `inbox/` folder syncs its contents to `<remotePath>/inbox/
|
|
|
105
182
|
|
|
106
183
|
> 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.
|
|
107
184
|
|
|
108
|
-
|
|
185
|
+
#### `bisync` mode (advanced)
|
|
109
186
|
|
|
110
187
|
Full bidirectional sync using rclone bisync. Changes on either side propagate to the other.
|
|
111
188
|
|
|
@@ -123,136 +200,7 @@ Use this only if you understand the trade-offs:
|
|
|
123
200
|
|
|
124
201
|
If you are running on a container platform, `mailbox` mode is strongly recommended.
|
|
125
202
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
Getting the initial state right prevents data loss. Each mode has different requirements:
|
|
129
|
-
|
|
130
|
-
### `mailbox` mode — starting state
|
|
131
|
-
|
|
132
|
-
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**.
|
|
133
|
-
|
|
134
|
-
**Recommended starting state:** Local workspace is the source of truth (the agent has been writing here), or local and remote are already identical.
|
|
135
|
-
|
|
136
|
-
**If remote is the source of truth** (e.g. you've been syncing manually or switching from another mode), pull first:
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
rclone sync <remote>:<path> /data/workspace/ --config <config-path> \
|
|
140
|
-
--exclude '**/.DS_Store' --exclude '**/.git/**' \
|
|
141
|
-
--exclude '**/__pycache__/**' --exclude '**/node_modules/**' \
|
|
142
|
-
--verbose
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Then verify local matches remote before enabling the plugin.
|
|
146
|
-
|
|
147
|
-
### `mirror` mode — starting state
|
|
148
|
-
|
|
149
|
-
The first sync **pulls** from cloud to local. Local can be empty, stale, or corrupted — the pull simply overwrites it. **No preparation needed.**
|
|
150
|
-
|
|
151
|
-
### `bisync` mode — starting state
|
|
152
|
-
|
|
153
|
-
The first sync requires `--resync`, which copies everything from both sides to the other. Any stale or unwanted files on either side will propagate.
|
|
154
|
-
|
|
155
|
-
**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`.
|
|
156
|
-
|
|
157
|
-
### General first-sync checklist
|
|
158
|
-
|
|
159
|
-
1. Run a `--dry-run` first to see what would happen: `openclaw workspace-sync sync --dry-run`
|
|
160
|
-
2. Check the output for unexpected deletions
|
|
161
|
-
3. If everything looks right, run the actual sync
|
|
162
|
-
4. Only then enable periodic sync (`interval` in config)
|
|
163
|
-
|
|
164
|
-
> For maintenance, recovery, and common problems, see [TROUBLESHOOTING.md](./TROUBLESHOOTING.md).
|
|
165
|
-
|
|
166
|
-
## Setup sequence
|
|
167
|
-
|
|
168
|
-
Getting sync right depends on doing things in the right order. Follow these steps:
|
|
169
|
-
|
|
170
|
-
1. **Configure the plugin** in `openclaw.json` with your provider credentials and `mode`
|
|
171
|
-
2. **Verify the remote** is accessible: `openclaw workspace-sync status`
|
|
172
|
-
3. **Run a dry-run first** to see what would happen: `openclaw workspace-sync sync --dry-run`
|
|
173
|
-
4. **Run the first sync**: `openclaw workspace-sync sync`
|
|
174
|
-
- In `mailbox` mode, this pushes the workspace and drains the `_outbox`
|
|
175
|
-
- In `mirror` mode, this pulls the current workspace down
|
|
176
|
-
- In `bisync` mode, this requires `--resync` to establish the baseline
|
|
177
|
-
5. **Enable periodic sync** by setting `interval` in your config
|
|
178
|
-
|
|
179
|
-
Take care when changing config (switching `remotePath`, `localPath`, or `mode`) — always disable periodic sync first, verify the new paths, then re-enable.
|
|
180
|
-
|
|
181
|
-
## Install
|
|
182
|
-
|
|
183
|
-
```bash
|
|
184
|
-
openclaw plugins install openclaw-workspace-sync
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Or clone into your extensions directory:
|
|
188
|
-
|
|
189
|
-
```bash
|
|
190
|
-
cd ~/.openclaw/extensions
|
|
191
|
-
git clone https://github.com/ashbrener/openclaw-workspace-sync workspace-sync
|
|
192
|
-
cd workspace-sync && npm install --omit=dev
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
## Quick start
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
# Interactive setup wizard (recommended)
|
|
199
|
-
openclaw workspace-sync setup
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
The setup wizard guides you through:
|
|
203
|
-
1. Checking/installing rclone
|
|
204
|
-
2. Selecting cloud provider
|
|
205
|
-
3. Choosing sync mode
|
|
206
|
-
4. Dropbox app folder option (for scoped access)
|
|
207
|
-
5. Background sync interval
|
|
208
|
-
6. OAuth authorization
|
|
209
|
-
7. First sync
|
|
210
|
-
|
|
211
|
-
Or configure manually — see [Configuration](#configuration) below.
|
|
212
|
-
|
|
213
|
-
## Configuration
|
|
214
|
-
|
|
215
|
-
Add to your `openclaw.json`:
|
|
216
|
-
|
|
217
|
-
```json
|
|
218
|
-
{
|
|
219
|
-
"plugins": {
|
|
220
|
-
"entries": {
|
|
221
|
-
"openclaw-workspace-sync": {
|
|
222
|
-
"enabled": true,
|
|
223
|
-
"config": {
|
|
224
|
-
"sync": {
|
|
225
|
-
"provider": "dropbox",
|
|
226
|
-
"mode": "mailbox",
|
|
227
|
-
"remotePath": "",
|
|
228
|
-
"localPath": "/",
|
|
229
|
-
"interval": 60,
|
|
230
|
-
"timeout": 1800,
|
|
231
|
-
"onSessionStart": true,
|
|
232
|
-
"onSessionEnd": false,
|
|
233
|
-
"exclude": [".git/**", "node_modules/**", "*.log"]
|
|
234
|
-
},
|
|
235
|
-
"backup": {
|
|
236
|
-
"enabled": true,
|
|
237
|
-
"provider": "s3",
|
|
238
|
-
"bucket": "my-backups",
|
|
239
|
-
"prefix": "habibi/",
|
|
240
|
-
"interval": 86400,
|
|
241
|
-
"encrypt": true,
|
|
242
|
-
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
243
|
-
"include": ["workspace", "config", "cron", "memory"],
|
|
244
|
-
"retain": 7
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
> **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.
|
|
254
|
-
|
|
255
|
-
### Config reference
|
|
203
|
+
### Sync config reference
|
|
256
204
|
|
|
257
205
|
| Key | Type | Default | Description |
|
|
258
206
|
|-----|------|---------|-------------|
|
|
@@ -275,93 +223,7 @@ Add to your `openclaw.json`:
|
|
|
275
223
|
|
|
276
224
|
Default excludes: `**/.DS_Store`
|
|
277
225
|
|
|
278
|
-
###
|
|
279
|
-
|
|
280
|
-
**Dropbox with app folder (recommended for security):**
|
|
281
|
-
|
|
282
|
-
```json
|
|
283
|
-
{
|
|
284
|
-
"provider": "dropbox",
|
|
285
|
-
"remotePath": "",
|
|
286
|
-
"dropbox": {
|
|
287
|
-
"appFolder": true,
|
|
288
|
-
"appKey": "your-app-key",
|
|
289
|
-
"appSecret": "your-app-secret",
|
|
290
|
-
"token": "{\"access_token\":\"...\"}"
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
With `appFolder: true`, set `remotePath` to `""`. The app folder root is your sync root — do not repeat the app folder name in `remotePath` or rclone will fail with "directory not found."
|
|
296
|
-
|
|
297
|
-
**Google Drive:**
|
|
298
|
-
|
|
299
|
-
```json
|
|
300
|
-
{
|
|
301
|
-
"provider": "gdrive",
|
|
302
|
-
"remotePath": "openclaw-sync",
|
|
303
|
-
"gdrive": {
|
|
304
|
-
"token": "{\"access_token\":\"...\"}",
|
|
305
|
-
"teamDrive": "0ABcDeFgHiJ",
|
|
306
|
-
"rootFolderId": "folder-id"
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
`teamDrive` and `rootFolderId` are optional — omit them for personal Google Drive.
|
|
312
|
-
|
|
313
|
-
**OneDrive:**
|
|
314
|
-
|
|
315
|
-
```json
|
|
316
|
-
{
|
|
317
|
-
"provider": "onedrive",
|
|
318
|
-
"remotePath": "openclaw-sync",
|
|
319
|
-
"onedrive": {
|
|
320
|
-
"token": "{\"access_token\":\"...\"}",
|
|
321
|
-
"driveId": "drive-id",
|
|
322
|
-
"driveType": "business"
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
`driveType` can be `personal`, `business`, or `sharepoint`. Both fields are optional.
|
|
328
|
-
|
|
329
|
-
**S3 / Cloudflare R2 / Minio:**
|
|
330
|
-
|
|
331
|
-
```json
|
|
332
|
-
{
|
|
333
|
-
"provider": "s3",
|
|
334
|
-
"remotePath": "openclaw-sync",
|
|
335
|
-
"s3": {
|
|
336
|
-
"endpoint": "https://s3.us-east-1.amazonaws.com",
|
|
337
|
-
"bucket": "your-bucket",
|
|
338
|
-
"region": "us-east-1",
|
|
339
|
-
"accessKeyId": "AKID...",
|
|
340
|
-
"secretAccessKey": "SECRET..."
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
**Any rclone backend (SFTP, B2, Mega, pCloud, etc.):**
|
|
346
|
-
|
|
347
|
-
```json
|
|
348
|
-
{
|
|
349
|
-
"provider": "custom",
|
|
350
|
-
"remotePath": "openclaw-sync",
|
|
351
|
-
"custom": {
|
|
352
|
-
"rcloneType": "sftp",
|
|
353
|
-
"rcloneOptions": {
|
|
354
|
-
"host": "example.com",
|
|
355
|
-
"user": "deploy",
|
|
356
|
-
"key_file": "/path/to/key"
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
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`.
|
|
363
|
-
|
|
364
|
-
## CLI commands
|
|
226
|
+
### Sync CLI commands
|
|
365
227
|
|
|
366
228
|
```bash
|
|
367
229
|
# Interactive setup wizard
|
|
@@ -391,9 +253,9 @@ openclaw workspace-sync authorize --provider gdrive
|
|
|
391
253
|
openclaw workspace-sync list
|
|
392
254
|
```
|
|
393
255
|
|
|
394
|
-
|
|
256
|
+
### Auto-sync
|
|
395
257
|
|
|
396
|
-
|
|
258
|
+
#### Session hooks
|
|
397
259
|
|
|
398
260
|
Sync automatically when sessions start or end. These run during existing agent activity and incur zero LLM cost:
|
|
399
261
|
|
|
@@ -404,7 +266,7 @@ Sync automatically when sessions start or end. These run during existing agent a
|
|
|
404
266
|
}
|
|
405
267
|
```
|
|
406
268
|
|
|
407
|
-
|
|
269
|
+
#### Periodic background sync
|
|
408
270
|
|
|
409
271
|
Set `interval` to enable automatic background sync (in seconds):
|
|
410
272
|
|
|
@@ -419,72 +281,54 @@ The gateway runs sync in the background at this interval. Minimum interval is 60
|
|
|
419
281
|
|
|
420
282
|
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.
|
|
421
283
|
|
|
422
|
-
|
|
284
|
+
#### External cron (alternative)
|
|
423
285
|
|
|
424
286
|
```bash
|
|
425
287
|
# Add to crontab (crontab -e)
|
|
426
288
|
*/5 * * * * openclaw workspace-sync sync >> /var/log/openclaw-sync.log 2>&1
|
|
427
289
|
```
|
|
428
290
|
|
|
429
|
-
|
|
291
|
+
### Before your first sync
|
|
430
292
|
|
|
431
|
-
|
|
432
|
-
|----------|-------------|-------------|---------------|
|
|
433
|
-
| Dropbox | `dropbox` | OAuth token | Full (token, appKey, appSecret, appFolder) |
|
|
434
|
-
| Google Drive | `gdrive` | OAuth token | Full (token, teamDrive, rootFolderId) |
|
|
435
|
-
| OneDrive | `onedrive` | OAuth token | Full (token, driveId, driveType) |
|
|
436
|
-
| S3/R2/Minio | `s3` | Access keys | Full (endpoint, bucket, region, credentials) |
|
|
437
|
-
| Any rclone backend | `custom` | Varies | Full (rcloneType + rcloneOptions) |
|
|
438
|
-
|
|
439
|
-
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.).
|
|
293
|
+
Getting the initial state right prevents data loss. Each mode has different requirements:
|
|
440
294
|
|
|
441
|
-
|
|
295
|
+
#### `mailbox` mode — starting state
|
|
442
296
|
|
|
443
|
-
|
|
297
|
+
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**.
|
|
444
298
|
|
|
445
|
-
|
|
446
|
-
# 1. Authorize with your cloud provider
|
|
447
|
-
openclaw workspace-sync authorize --provider dropbox
|
|
299
|
+
**Recommended starting state:** Local workspace is the source of truth (the agent has been writing here), or local and remote are already identical.
|
|
448
300
|
|
|
449
|
-
|
|
450
|
-
openclaw workspace-sync sync --dry-run
|
|
301
|
+
**If remote is the source of truth** (e.g. you've been syncing manually or switching from another mode), pull first:
|
|
451
302
|
|
|
452
|
-
|
|
453
|
-
|
|
303
|
+
```bash
|
|
304
|
+
rclone sync <remote>:<path> /data/workspace/ --config <config-path> \
|
|
305
|
+
--exclude '**/.DS_Store' --exclude '**/.git/**' \
|
|
306
|
+
--exclude '**/__pycache__/**' --exclude '**/node_modules/**' \
|
|
307
|
+
--verbose
|
|
454
308
|
```
|
|
455
309
|
|
|
456
|
-
|
|
310
|
+
Then verify local matches remote before enabling the plugin.
|
|
457
311
|
|
|
458
|
-
|
|
312
|
+
#### `mirror` mode — starting state
|
|
459
313
|
|
|
460
|
-
|
|
314
|
+
The first sync **pulls** from cloud to local. Local can be empty, stale, or corrupted — the pull simply overwrites it. **No preparation needed.**
|
|
461
315
|
|
|
462
|
-
|
|
463
|
-
2. Click **Create app** > **Scoped access** > **App folder**
|
|
464
|
-
3. Name it (e.g., `openclaw-sync`)
|
|
465
|
-
4. In **Settings** tab, add a **Redirect URI**: `http://localhost:53682/`
|
|
466
|
-
- This is required for rclone's OAuth flow to work. Without it, Dropbox returns "Invalid redirect_uri" during authorization.
|
|
467
|
-
5. In **Permissions** tab, enable:
|
|
468
|
-
- `files.metadata.read` / `files.metadata.write`
|
|
469
|
-
- `files.content.read` / `files.content.write`
|
|
470
|
-
6. Copy **App key** and **App secret** from Settings
|
|
316
|
+
#### `bisync` mode — starting state
|
|
471
317
|
|
|
472
|
-
|
|
318
|
+
The first sync requires `--resync`, which copies everything from both sides to the other. Any stale or unwanted files on either side will propagate.
|
|
473
319
|
|
|
474
|
-
|
|
475
|
-
- Token only accesses one folder, not your entire Dropbox
|
|
476
|
-
- If token is compromised, blast radius is limited
|
|
477
|
-
- Clean separation — sync folder lives under `Apps/<your-app-name>/`
|
|
320
|
+
**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`.
|
|
478
321
|
|
|
479
|
-
|
|
322
|
+
#### General first-sync checklist
|
|
480
323
|
|
|
481
|
-
|
|
324
|
+
1. Run a `--dry-run` first to see what would happen: `openclaw workspace-sync sync --dry-run`
|
|
325
|
+
2. Check the output for unexpected deletions
|
|
326
|
+
3. If everything looks right, run the actual sync
|
|
327
|
+
4. Only then enable periodic sync (`interval` in config)
|
|
482
328
|
|
|
483
|
-
|
|
484
|
-
- **Use `exclude` patterns liberally** — skip `node_modules`, `.git`, `__pycache__`, build output, and anything you don't need synced. Fewer files = fewer API calls.
|
|
485
|
-
- **If you see `too_many_requests` errors** in the logs, increase the interval and add more excludes.
|
|
329
|
+
> For maintenance, recovery, and common problems, see [TROUBLESHOOTING.md](./TROUBLESHOOTING.md).
|
|
486
330
|
|
|
487
|
-
|
|
331
|
+
### Sync safety
|
|
488
332
|
|
|
489
333
|
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:
|
|
490
334
|
|
|
@@ -504,7 +348,7 @@ Cloud sync involves two copies of your data. When things go wrong, one side can
|
|
|
504
348
|
|
|
505
349
|
> For recovery procedures, mode switching, and maintenance tips, see [TROUBLESHOOTING.md](./TROUBLESHOOTING.md).
|
|
506
350
|
|
|
507
|
-
|
|
351
|
+
#### Important: `--resync` is destructive (bisync only)
|
|
508
352
|
|
|
509
353
|
**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:
|
|
510
354
|
|
|
@@ -519,15 +363,15 @@ Normal bisync (without `--resync`) only transfers files that changed since the l
|
|
|
519
363
|
openclaw workspace-sync sync --resync
|
|
520
364
|
```
|
|
521
365
|
|
|
522
|
-
|
|
366
|
+
### Sync troubleshooting
|
|
523
367
|
|
|
524
|
-
|
|
368
|
+
#### Token expired
|
|
525
369
|
|
|
526
370
|
```bash
|
|
527
371
|
openclaw workspace-sync authorize
|
|
528
372
|
```
|
|
529
373
|
|
|
530
|
-
|
|
374
|
+
#### Conflicts (bisync only)
|
|
531
375
|
|
|
532
376
|
Files modified on both sides get a `.conflict` suffix. The winner is determined by `conflictResolve` (default: `newer`). To find conflict files:
|
|
533
377
|
|
|
@@ -535,7 +379,7 @@ Files modified on both sides get a `.conflict` suffix. The winner is determined
|
|
|
535
379
|
find <workspace>/shared -name "*.conflict"
|
|
536
380
|
```
|
|
537
381
|
|
|
538
|
-
|
|
382
|
+
#### Stale lock files
|
|
539
383
|
|
|
540
384
|
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.
|
|
541
385
|
|
|
@@ -545,7 +389,7 @@ If you still see lock errors, you can manually clear them:
|
|
|
545
389
|
rclone deletefile ~/.cache/rclone/bisync/<lockfile>.lck
|
|
546
390
|
```
|
|
547
391
|
|
|
548
|
-
|
|
392
|
+
#### Sync times out
|
|
549
393
|
|
|
550
394
|
Increase the `timeout` config (in seconds). The default is 1800 (30 min). For large workspaces:
|
|
551
395
|
|
|
@@ -555,28 +399,21 @@ Increase the `timeout` config (in seconds). The default is 1800 (30 min). For la
|
|
|
555
399
|
}
|
|
556
400
|
```
|
|
557
401
|
|
|
558
|
-
|
|
402
|
+
#### Permission errors
|
|
559
403
|
|
|
560
404
|
```bash
|
|
561
405
|
chmod -R 755 <workspace>/shared
|
|
562
406
|
```
|
|
563
407
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
If you are running OpenClaw on a cloud container (Fly.io, Railway, Render) or a VPS:
|
|
408
|
+
#### Dropbox rate limiting
|
|
567
409
|
|
|
568
|
-
|
|
569
|
-
- **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.
|
|
570
|
-
- **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.
|
|
571
|
-
|
|
572
|
-
These recommendations apply regardless of whether you use this plugin. Cloud sync adds convenience but is not a substitute for proper backups.
|
|
410
|
+
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:
|
|
573
411
|
|
|
574
|
-
|
|
412
|
+
- **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.
|
|
413
|
+
- **Use `exclude` patterns liberally** — skip `node_modules`, `.git`, `__pycache__`, build output, and anything you don't need synced. Fewer files = fewer API calls.
|
|
414
|
+
- **If you see `too_many_requests` errors** in the logs, increase the interval and add more excludes.
|
|
575
415
|
|
|
576
|
-
|
|
577
|
-
- **Sensitive files**: Don't sync secrets, API keys, or credentials
|
|
578
|
-
- **Encryption**: Consider [rclone crypt](https://rclone.org/crypt/) for sensitive data
|
|
579
|
-
- **App folder**: Use Dropbox app folder access for minimal permissions
|
|
416
|
+
---
|
|
580
417
|
|
|
581
418
|
## Encrypted backups
|
|
582
419
|
|
|
@@ -595,32 +432,6 @@ Back up your entire agent system — workspace, config, cron jobs, memory, sessi
|
|
|
595
432
|
|
|
596
433
|
> **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.
|
|
597
434
|
|
|
598
|
-
### Configuration
|
|
599
|
-
|
|
600
|
-
Add `sync` and `backup` blocks to your plugin config. The backup provider can differ from your sync provider — sync to Dropbox for live mirror, backup to S3 for disaster recovery:
|
|
601
|
-
|
|
602
|
-
```json
|
|
603
|
-
{
|
|
604
|
-
"sync": {
|
|
605
|
-
"provider": "dropbox",
|
|
606
|
-
"mode": "mailbox",
|
|
607
|
-
"remotePath": "",
|
|
608
|
-
"interval": 180
|
|
609
|
-
},
|
|
610
|
-
"backup": {
|
|
611
|
-
"enabled": true,
|
|
612
|
-
"provider": "s3",
|
|
613
|
-
"bucket": "my-backups",
|
|
614
|
-
"prefix": "habibi/",
|
|
615
|
-
"interval": 86400,
|
|
616
|
-
"encrypt": true,
|
|
617
|
-
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
618
|
-
"include": ["workspace", "config", "cron", "memory"],
|
|
619
|
-
"retain": { "daily": 7, "weekly": 4 }
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
```
|
|
623
|
-
|
|
624
435
|
### Backup config reference
|
|
625
436
|
|
|
626
437
|
| Key | Type | Default | Description |
|
|
@@ -656,7 +467,7 @@ Add `sync` and `backup` blocks to your plugin config. The backup provider can di
|
|
|
656
467
|
|
|
657
468
|
Default: `["workspace", "config", "cron", "memory"]`
|
|
658
469
|
|
|
659
|
-
### CLI commands
|
|
470
|
+
### Backup CLI commands
|
|
660
471
|
|
|
661
472
|
```bash
|
|
662
473
|
# Create a backup now
|
|
@@ -682,7 +493,7 @@ openclaw workspace-sync backup status
|
|
|
682
493
|
|
|
683
494
|
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.
|
|
684
495
|
|
|
685
|
-
###
|
|
496
|
+
### Backup provider examples
|
|
686
497
|
|
|
687
498
|
**Cloudflare R2 (free tier: 10GB):**
|
|
688
499
|
|
|
@@ -743,6 +554,148 @@ By default, `restore` extracts to a staging directory (`~/.openclaw/.backup-rest
|
|
|
743
554
|
}
|
|
744
555
|
```
|
|
745
556
|
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## Provider-specific options
|
|
560
|
+
|
|
561
|
+
These provider blocks work for both sync and backup. Place them inside the `sync` or `backup` config block as needed.
|
|
562
|
+
|
|
563
|
+
**Dropbox with app folder (recommended for security):**
|
|
564
|
+
|
|
565
|
+
```json
|
|
566
|
+
{
|
|
567
|
+
"provider": "dropbox",
|
|
568
|
+
"remotePath": "",
|
|
569
|
+
"dropbox": {
|
|
570
|
+
"appFolder": true,
|
|
571
|
+
"appKey": "your-app-key",
|
|
572
|
+
"appSecret": "your-app-secret",
|
|
573
|
+
"token": "{\"access_token\":\"...\"}"
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
With `appFolder: true`, set `remotePath` to `""`. The app folder root is your sync root — do not repeat the app folder name in `remotePath` or rclone will fail with "directory not found."
|
|
579
|
+
|
|
580
|
+
**Google Drive:**
|
|
581
|
+
|
|
582
|
+
```json
|
|
583
|
+
{
|
|
584
|
+
"provider": "gdrive",
|
|
585
|
+
"remotePath": "openclaw-sync",
|
|
586
|
+
"gdrive": {
|
|
587
|
+
"token": "{\"access_token\":\"...\"}",
|
|
588
|
+
"teamDrive": "0ABcDeFgHiJ",
|
|
589
|
+
"rootFolderId": "folder-id"
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
`teamDrive` and `rootFolderId` are optional — omit them for personal Google Drive.
|
|
595
|
+
|
|
596
|
+
**OneDrive:**
|
|
597
|
+
|
|
598
|
+
```json
|
|
599
|
+
{
|
|
600
|
+
"provider": "onedrive",
|
|
601
|
+
"remotePath": "openclaw-sync",
|
|
602
|
+
"onedrive": {
|
|
603
|
+
"token": "{\"access_token\":\"...\"}",
|
|
604
|
+
"driveId": "drive-id",
|
|
605
|
+
"driveType": "business"
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
`driveType` can be `personal`, `business`, or `sharepoint`. Both fields are optional.
|
|
611
|
+
|
|
612
|
+
**S3 / Cloudflare R2 / Minio:**
|
|
613
|
+
|
|
614
|
+
```json
|
|
615
|
+
{
|
|
616
|
+
"provider": "s3",
|
|
617
|
+
"remotePath": "openclaw-sync",
|
|
618
|
+
"s3": {
|
|
619
|
+
"endpoint": "https://s3.us-east-1.amazonaws.com",
|
|
620
|
+
"bucket": "your-bucket",
|
|
621
|
+
"region": "us-east-1",
|
|
622
|
+
"accessKeyId": "AKID...",
|
|
623
|
+
"secretAccessKey": "SECRET..."
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
**Any rclone backend (SFTP, B2, Mega, pCloud, etc.):**
|
|
629
|
+
|
|
630
|
+
```json
|
|
631
|
+
{
|
|
632
|
+
"provider": "custom",
|
|
633
|
+
"remotePath": "openclaw-sync",
|
|
634
|
+
"custom": {
|
|
635
|
+
"rcloneType": "sftp",
|
|
636
|
+
"rcloneOptions": {
|
|
637
|
+
"host": "example.com",
|
|
638
|
+
"user": "deploy",
|
|
639
|
+
"key_file": "/path/to/key"
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
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`.
|
|
646
|
+
|
|
647
|
+
### Supported providers
|
|
648
|
+
|
|
649
|
+
| Provider | Config value | Auth method | Config-driven |
|
|
650
|
+
|----------|-------------|-------------|---------------|
|
|
651
|
+
| Dropbox | `dropbox` | OAuth token | Full (token, appKey, appSecret, appFolder) |
|
|
652
|
+
| Google Drive | `gdrive` | OAuth token | Full (token, teamDrive, rootFolderId) |
|
|
653
|
+
| OneDrive | `onedrive` | OAuth token | Full (token, driveId, driveType) |
|
|
654
|
+
| S3/R2/Minio | `s3` | Access keys | Full (endpoint, bucket, region, credentials) |
|
|
655
|
+
| Any rclone backend | `custom` | Varies | Full (rcloneType + rcloneOptions) |
|
|
656
|
+
|
|
657
|
+
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.).
|
|
658
|
+
|
|
659
|
+
### Dropbox app folder access (recommended)
|
|
660
|
+
|
|
661
|
+
For better security, create a scoped Dropbox app that only accesses a single folder:
|
|
662
|
+
|
|
663
|
+
1. Go to [Dropbox App Console](https://www.dropbox.com/developers/apps)
|
|
664
|
+
2. Click **Create app** > **Scoped access** > **App folder**
|
|
665
|
+
3. Name it (e.g., `openclaw-sync`)
|
|
666
|
+
4. In **Settings** tab, add a **Redirect URI**: `http://localhost:53682/`
|
|
667
|
+
- This is required for rclone's OAuth flow to work. Without it, Dropbox returns "Invalid redirect_uri" during authorization.
|
|
668
|
+
5. In **Permissions** tab, enable:
|
|
669
|
+
- `files.metadata.read` / `files.metadata.write`
|
|
670
|
+
- `files.content.read` / `files.content.write`
|
|
671
|
+
6. Copy **App key** and **App secret** from Settings
|
|
672
|
+
|
|
673
|
+
> **Important:** When using an app folder scoped app, set `"remotePath": ""` (empty string) in your config. The app folder **is** the root — rclone sees it as `/`. If you set `remotePath` to your app folder name (e.g., `"openclaw-sync"`), rclone will look for a subfolder *inside* the app folder with that name and fail with "directory not found."
|
|
674
|
+
|
|
675
|
+
Benefits:
|
|
676
|
+
- Token only accesses one folder, not your entire Dropbox
|
|
677
|
+
- If token is compromised, blast radius is limited
|
|
678
|
+
- Clean separation — sync folder lives under `Apps/<your-app-name>/`
|
|
679
|
+
|
|
680
|
+
---
|
|
681
|
+
|
|
682
|
+
## Deployment recommendations
|
|
683
|
+
|
|
684
|
+
If you are running OpenClaw on a cloud container (Fly.io, Railway, Render) or a VPS:
|
|
685
|
+
|
|
686
|
+
- **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.
|
|
687
|
+
- **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.
|
|
688
|
+
- **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.
|
|
689
|
+
- **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.
|
|
690
|
+
|
|
691
|
+
## Security notes
|
|
692
|
+
|
|
693
|
+
- **Token storage**: rclone tokens are stored in `rclone.conf` with `0600` permissions
|
|
694
|
+
- **Sensitive files**: Don't sync secrets, API keys, or credentials
|
|
695
|
+
- **Encryption**: Backups support AES-256 client-side encryption. For sync, consider [rclone crypt](https://rclone.org/crypt/) for sensitive data.
|
|
696
|
+
- **App folder**: Use Dropbox app folder access for minimal permissions
|
|
697
|
+
- **Passphrase safety**: Use environment variables (`${BACKUP_PASSPHRASE}`) — never hardcode passphrases in config files
|
|
698
|
+
|
|
746
699
|
## Development
|
|
747
700
|
|
|
748
701
|
```bash
|