openclaw-workspace-sync 2.2.0 → 2.3.0
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 +189 -9
- package/README.src.md +206 -9
- package/dist/backup-manager.d.ts +67 -0
- package/dist/backup-manager.d.ts.map +1 -0
- package/dist/backup-manager.js +520 -0
- package/dist/backup-manager.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +159 -2
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/diagrams/mode-3.svg +42 -0
- package/openclaw.plugin.json +122 -1
- package/package.json +1 -1
- package/skills/workspace-sync/SKILL.md +57 -10
package/README.md
CHANGED
|
@@ -221,15 +221,28 @@ Add to your `openclaw.json`:
|
|
|
221
221
|
"openclaw-workspace-sync": {
|
|
222
222
|
"enabled": true,
|
|
223
223
|
"config": {
|
|
224
|
-
"
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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
|
+
}
|
|
233
246
|
}
|
|
234
247
|
}
|
|
235
248
|
}
|
|
@@ -237,6 +250,8 @@ Add to your `openclaw.json`:
|
|
|
237
250
|
}
|
|
238
251
|
```
|
|
239
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
|
+
|
|
240
255
|
### Config reference
|
|
241
256
|
|
|
242
257
|
| Key | Type | Default | Description |
|
|
@@ -563,6 +578,171 @@ These recommendations apply regardless of whether you use this plugin. Cloud syn
|
|
|
563
578
|
- **Encryption**: Consider [rclone crypt](https://rclone.org/crypt/) for sensitive data
|
|
564
579
|
- **App folder**: Use Dropbox app folder access for minimal permissions
|
|
565
580
|
|
|
581
|
+
## Encrypted backups
|
|
582
|
+
|
|
583
|
+
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.
|
|
584
|
+
|
|
585
|
+
### How it works
|
|
586
|
+
|
|
587
|
+
<p align="center">
|
|
588
|
+
<img src="https://raw.githubusercontent.com/ashbrener/openclaw-workspace-sync/main/docs/diagrams/mode-3.svg" alt="backup pipeline diagram" width="700" />
|
|
589
|
+
</p>
|
|
590
|
+
|
|
591
|
+
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.
|
|
592
|
+
2. Optionally encrypts with AES-256 (client-side, before upload) via `openssl`
|
|
593
|
+
3. Uploads via rclone to any supported provider (S3, R2, Backblaze B2, Dropbox, etc.)
|
|
594
|
+
4. Prunes old snapshots based on your retention policy
|
|
595
|
+
|
|
596
|
+
> **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
|
+
|
|
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
|
+
### Backup config reference
|
|
625
|
+
|
|
626
|
+
| Key | Type | Default | Description |
|
|
627
|
+
|-----|------|---------|-------------|
|
|
628
|
+
| `enabled` | boolean | `false` | Enable scheduled backups |
|
|
629
|
+
| `provider` | string | parent provider | Cloud provider for backup storage |
|
|
630
|
+
| `bucket` | string | — | S3/R2 bucket name |
|
|
631
|
+
| `prefix` | string | `""` | Path prefix within the bucket (e.g., `habibi/`) |
|
|
632
|
+
| `interval` | number | `86400` | Backup interval in seconds (86400 = daily; clamped to min 300) |
|
|
633
|
+
| `encrypt` | boolean | `false` | Encrypt snapshots with AES-256 before upload |
|
|
634
|
+
| `passphrase` | string | — | Encryption passphrase (use `${BACKUP_PASSPHRASE}` env var) |
|
|
635
|
+
| `include` | string[] | see below | What to back up |
|
|
636
|
+
| `retain` | number or object | `7` | Retention: `7` = keep 7 latest, or `{ daily: 7, weekly: 4 }` |
|
|
637
|
+
| `exclude` | string[] | parent excludes | Glob patterns to exclude from workspace backup |
|
|
638
|
+
|
|
639
|
+
### Include options
|
|
640
|
+
|
|
641
|
+
| Item | What gets backed up |
|
|
642
|
+
|------|---------------------|
|
|
643
|
+
| `workspace` | The workspace directory (agent files, projects, etc.) |
|
|
644
|
+
| `config` | `openclaw.json` |
|
|
645
|
+
| `cron` | Cron job schedules and state |
|
|
646
|
+
| `memory` | Memory files (MEMORY.md, etc.) |
|
|
647
|
+
| `sessions` | Session metadata and store |
|
|
648
|
+
| `credentials` | Auth profile credentials |
|
|
649
|
+
| `skills` | Skill files |
|
|
650
|
+
| `hooks` | Webhook configurations and state (Gmail watch, custom hooks) |
|
|
651
|
+
| `extensions` | Installed plugins/extensions (for reproducible restores) |
|
|
652
|
+
| `env` | Environment variables file (`.env`) |
|
|
653
|
+
| `agents` | Multi-agent state (per-agent sessions, subagent registry) |
|
|
654
|
+
| `pages` | Custom pages served by the gateway |
|
|
655
|
+
| `transcripts` | Full conversation logs (JSONL session transcripts) |
|
|
656
|
+
|
|
657
|
+
Default: `["workspace", "config", "cron", "memory"]`
|
|
658
|
+
|
|
659
|
+
### CLI commands
|
|
660
|
+
|
|
661
|
+
```bash
|
|
662
|
+
# Create a backup now
|
|
663
|
+
openclaw workspace-sync backup now
|
|
664
|
+
|
|
665
|
+
# List available snapshots
|
|
666
|
+
openclaw workspace-sync backup list
|
|
667
|
+
|
|
668
|
+
# Restore the latest snapshot
|
|
669
|
+
openclaw workspace-sync backup restore
|
|
670
|
+
|
|
671
|
+
# Restore a specific snapshot
|
|
672
|
+
openclaw workspace-sync backup restore --snapshot backup-20260310T020000Z.tar.gz.enc
|
|
673
|
+
|
|
674
|
+
# Restore to a specific directory (safe — doesn't overwrite live data)
|
|
675
|
+
openclaw workspace-sync backup restore --to /tmp/restore-test
|
|
676
|
+
|
|
677
|
+
# Check backup service status
|
|
678
|
+
openclaw workspace-sync backup status
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### Restore safety
|
|
682
|
+
|
|
683
|
+
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
|
+
|
|
685
|
+
### Provider examples
|
|
686
|
+
|
|
687
|
+
**Cloudflare R2 (free tier: 10GB):**
|
|
688
|
+
|
|
689
|
+
```json
|
|
690
|
+
{
|
|
691
|
+
"backup": {
|
|
692
|
+
"enabled": true,
|
|
693
|
+
"provider": "s3",
|
|
694
|
+
"encrypt": true,
|
|
695
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
696
|
+
"s3": {
|
|
697
|
+
"endpoint": "https://<account-id>.r2.cloudflarestorage.com",
|
|
698
|
+
"bucket": "openclaw-backups",
|
|
699
|
+
"region": "auto",
|
|
700
|
+
"accessKeyId": "${R2_ACCESS_KEY}",
|
|
701
|
+
"secretAccessKey": "${R2_SECRET_KEY}"
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
**AWS S3:**
|
|
708
|
+
|
|
709
|
+
```json
|
|
710
|
+
{
|
|
711
|
+
"backup": {
|
|
712
|
+
"enabled": true,
|
|
713
|
+
"provider": "s3",
|
|
714
|
+
"encrypt": true,
|
|
715
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
716
|
+
"s3": {
|
|
717
|
+
"bucket": "my-openclaw-backups",
|
|
718
|
+
"region": "us-east-1",
|
|
719
|
+
"accessKeyId": "${AWS_ACCESS_KEY_ID}",
|
|
720
|
+
"secretAccessKey": "${AWS_SECRET_ACCESS_KEY}"
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
**Backblaze B2:**
|
|
727
|
+
|
|
728
|
+
```json
|
|
729
|
+
{
|
|
730
|
+
"backup": {
|
|
731
|
+
"enabled": true,
|
|
732
|
+
"provider": "s3",
|
|
733
|
+
"encrypt": true,
|
|
734
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
735
|
+
"s3": {
|
|
736
|
+
"endpoint": "https://s3.us-west-002.backblazeb2.com",
|
|
737
|
+
"bucket": "openclaw-backups",
|
|
738
|
+
"region": "us-west-002",
|
|
739
|
+
"accessKeyId": "${B2_KEY_ID}",
|
|
740
|
+
"secretAccessKey": "${B2_APP_KEY}"
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
```
|
|
745
|
+
|
|
566
746
|
## Development
|
|
567
747
|
|
|
568
748
|
```bash
|
package/README.src.md
CHANGED
|
@@ -262,15 +262,28 @@ Add to your `openclaw.json`:
|
|
|
262
262
|
"openclaw-workspace-sync": {
|
|
263
263
|
"enabled": true,
|
|
264
264
|
"config": {
|
|
265
|
-
"
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
265
|
+
"sync": {
|
|
266
|
+
"provider": "dropbox",
|
|
267
|
+
"mode": "mailbox",
|
|
268
|
+
"remotePath": "",
|
|
269
|
+
"localPath": "/",
|
|
270
|
+
"interval": 60,
|
|
271
|
+
"timeout": 1800,
|
|
272
|
+
"onSessionStart": true,
|
|
273
|
+
"onSessionEnd": false,
|
|
274
|
+
"exclude": [".git/**", "node_modules/**", "*.log"]
|
|
275
|
+
},
|
|
276
|
+
"backup": {
|
|
277
|
+
"enabled": true,
|
|
278
|
+
"provider": "s3",
|
|
279
|
+
"bucket": "my-backups",
|
|
280
|
+
"prefix": "habibi/",
|
|
281
|
+
"interval": 86400,
|
|
282
|
+
"encrypt": true,
|
|
283
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
284
|
+
"include": ["workspace", "config", "cron", "memory"],
|
|
285
|
+
"retain": 7
|
|
286
|
+
}
|
|
274
287
|
}
|
|
275
288
|
}
|
|
276
289
|
}
|
|
@@ -278,6 +291,8 @@ Add to your `openclaw.json`:
|
|
|
278
291
|
}
|
|
279
292
|
```
|
|
280
293
|
|
|
294
|
+
> **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.
|
|
295
|
+
|
|
281
296
|
### Config reference
|
|
282
297
|
|
|
283
298
|
| Key | Type | Default | Description |
|
|
@@ -604,6 +619,188 @@ These recommendations apply regardless of whether you use this plugin. Cloud syn
|
|
|
604
619
|
- **Encryption**: Consider [rclone crypt](https://rclone.org/crypt/) for sensitive data
|
|
605
620
|
- **App folder**: Use Dropbox app folder access for minimal permissions
|
|
606
621
|
|
|
622
|
+
## Encrypted backups
|
|
623
|
+
|
|
624
|
+
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.
|
|
625
|
+
|
|
626
|
+
### How it works
|
|
627
|
+
|
|
628
|
+
```mermaid
|
|
629
|
+
flowchart TD
|
|
630
|
+
subgraph GW["Gateway"]
|
|
631
|
+
WS["/workspace"]
|
|
632
|
+
CFG["config / cron / memory"]
|
|
633
|
+
end
|
|
634
|
+
TAR["tar cz"]
|
|
635
|
+
ENC["openssl enc\n(AES-256)"]
|
|
636
|
+
RCAT["rclone rcat"]
|
|
637
|
+
subgraph REMOTE["Your Bucket (S3 / R2 / B2)"]
|
|
638
|
+
SNAP["backup-2026…Z.tar.gz.enc"]
|
|
639
|
+
OLD["older snapshots"]
|
|
640
|
+
end
|
|
641
|
+
WS --> TAR
|
|
642
|
+
CFG --> TAR
|
|
643
|
+
TAR -- "pipe" --> ENC
|
|
644
|
+
ENC -- "pipe" --> RCAT
|
|
645
|
+
RCAT --> SNAP
|
|
646
|
+
SNAP -. "retention prune" .-> OLD
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
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.
|
|
650
|
+
2. Optionally encrypts with AES-256 (client-side, before upload) via `openssl`
|
|
651
|
+
3. Uploads via rclone to any supported provider (S3, R2, Backblaze B2, Dropbox, etc.)
|
|
652
|
+
4. Prunes old snapshots based on your retention policy
|
|
653
|
+
|
|
654
|
+
> **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.
|
|
655
|
+
|
|
656
|
+
### Configuration
|
|
657
|
+
|
|
658
|
+
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:
|
|
659
|
+
|
|
660
|
+
```json
|
|
661
|
+
{
|
|
662
|
+
"sync": {
|
|
663
|
+
"provider": "dropbox",
|
|
664
|
+
"mode": "mailbox",
|
|
665
|
+
"remotePath": "",
|
|
666
|
+
"interval": 180
|
|
667
|
+
},
|
|
668
|
+
"backup": {
|
|
669
|
+
"enabled": true,
|
|
670
|
+
"provider": "s3",
|
|
671
|
+
"bucket": "my-backups",
|
|
672
|
+
"prefix": "habibi/",
|
|
673
|
+
"interval": 86400,
|
|
674
|
+
"encrypt": true,
|
|
675
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
676
|
+
"include": ["workspace", "config", "cron", "memory"],
|
|
677
|
+
"retain": { "daily": 7, "weekly": 4 }
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
### Backup config reference
|
|
683
|
+
|
|
684
|
+
| Key | Type | Default | Description |
|
|
685
|
+
|-----|------|---------|-------------|
|
|
686
|
+
| `enabled` | boolean | `false` | Enable scheduled backups |
|
|
687
|
+
| `provider` | string | parent provider | Cloud provider for backup storage |
|
|
688
|
+
| `bucket` | string | — | S3/R2 bucket name |
|
|
689
|
+
| `prefix` | string | `""` | Path prefix within the bucket (e.g., `habibi/`) |
|
|
690
|
+
| `interval` | number | `86400` | Backup interval in seconds (86400 = daily; clamped to min 300) |
|
|
691
|
+
| `encrypt` | boolean | `false` | Encrypt snapshots with AES-256 before upload |
|
|
692
|
+
| `passphrase` | string | — | Encryption passphrase (use `${BACKUP_PASSPHRASE}` env var) |
|
|
693
|
+
| `include` | string[] | see below | What to back up |
|
|
694
|
+
| `retain` | number or object | `7` | Retention: `7` = keep 7 latest, or `{ daily: 7, weekly: 4 }` |
|
|
695
|
+
| `exclude` | string[] | parent excludes | Glob patterns to exclude from workspace backup |
|
|
696
|
+
|
|
697
|
+
### Include options
|
|
698
|
+
|
|
699
|
+
| Item | What gets backed up |
|
|
700
|
+
|------|---------------------|
|
|
701
|
+
| `workspace` | The workspace directory (agent files, projects, etc.) |
|
|
702
|
+
| `config` | `openclaw.json` |
|
|
703
|
+
| `cron` | Cron job schedules and state |
|
|
704
|
+
| `memory` | Memory files (MEMORY.md, etc.) |
|
|
705
|
+
| `sessions` | Session metadata and store |
|
|
706
|
+
| `credentials` | Auth profile credentials |
|
|
707
|
+
| `skills` | Skill files |
|
|
708
|
+
| `hooks` | Webhook configurations and state (Gmail watch, custom hooks) |
|
|
709
|
+
| `extensions` | Installed plugins/extensions (for reproducible restores) |
|
|
710
|
+
| `env` | Environment variables file (`.env`) |
|
|
711
|
+
| `agents` | Multi-agent state (per-agent sessions, subagent registry) |
|
|
712
|
+
| `pages` | Custom pages served by the gateway |
|
|
713
|
+
| `transcripts` | Full conversation logs (JSONL session transcripts) |
|
|
714
|
+
|
|
715
|
+
Default: `["workspace", "config", "cron", "memory"]`
|
|
716
|
+
|
|
717
|
+
### CLI commands
|
|
718
|
+
|
|
719
|
+
```bash
|
|
720
|
+
# Create a backup now
|
|
721
|
+
openclaw workspace-sync backup now
|
|
722
|
+
|
|
723
|
+
# List available snapshots
|
|
724
|
+
openclaw workspace-sync backup list
|
|
725
|
+
|
|
726
|
+
# Restore the latest snapshot
|
|
727
|
+
openclaw workspace-sync backup restore
|
|
728
|
+
|
|
729
|
+
# Restore a specific snapshot
|
|
730
|
+
openclaw workspace-sync backup restore --snapshot backup-20260310T020000Z.tar.gz.enc
|
|
731
|
+
|
|
732
|
+
# Restore to a specific directory (safe — doesn't overwrite live data)
|
|
733
|
+
openclaw workspace-sync backup restore --to /tmp/restore-test
|
|
734
|
+
|
|
735
|
+
# Check backup service status
|
|
736
|
+
openclaw workspace-sync backup status
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
### Restore safety
|
|
740
|
+
|
|
741
|
+
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.
|
|
742
|
+
|
|
743
|
+
### Provider examples
|
|
744
|
+
|
|
745
|
+
**Cloudflare R2 (free tier: 10GB):**
|
|
746
|
+
|
|
747
|
+
```json
|
|
748
|
+
{
|
|
749
|
+
"backup": {
|
|
750
|
+
"enabled": true,
|
|
751
|
+
"provider": "s3",
|
|
752
|
+
"encrypt": true,
|
|
753
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
754
|
+
"s3": {
|
|
755
|
+
"endpoint": "https://<account-id>.r2.cloudflarestorage.com",
|
|
756
|
+
"bucket": "openclaw-backups",
|
|
757
|
+
"region": "auto",
|
|
758
|
+
"accessKeyId": "${R2_ACCESS_KEY}",
|
|
759
|
+
"secretAccessKey": "${R2_SECRET_KEY}"
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
**AWS S3:**
|
|
766
|
+
|
|
767
|
+
```json
|
|
768
|
+
{
|
|
769
|
+
"backup": {
|
|
770
|
+
"enabled": true,
|
|
771
|
+
"provider": "s3",
|
|
772
|
+
"encrypt": true,
|
|
773
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
774
|
+
"s3": {
|
|
775
|
+
"bucket": "my-openclaw-backups",
|
|
776
|
+
"region": "us-east-1",
|
|
777
|
+
"accessKeyId": "${AWS_ACCESS_KEY_ID}",
|
|
778
|
+
"secretAccessKey": "${AWS_SECRET_ACCESS_KEY}"
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
**Backblaze B2:**
|
|
785
|
+
|
|
786
|
+
```json
|
|
787
|
+
{
|
|
788
|
+
"backup": {
|
|
789
|
+
"enabled": true,
|
|
790
|
+
"provider": "s3",
|
|
791
|
+
"encrypt": true,
|
|
792
|
+
"passphrase": "${BACKUP_PASSPHRASE}",
|
|
793
|
+
"s3": {
|
|
794
|
+
"endpoint": "https://s3.us-west-002.backblazeb2.com",
|
|
795
|
+
"bucket": "openclaw-backups",
|
|
796
|
+
"region": "us-west-002",
|
|
797
|
+
"accessKeyId": "${B2_KEY_ID}",
|
|
798
|
+
"secretAccessKey": "${B2_APP_KEY}"
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
```
|
|
803
|
+
|
|
607
804
|
## Development
|
|
608
805
|
|
|
609
806
|
```bash
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup manager — encrypted snapshot backups to cloud storage.
|
|
3
|
+
*
|
|
4
|
+
* Streams tar | [openssl enc] | rclone rcat directly to the remote —
|
|
5
|
+
* zero local disk usage. Optionally encrypts with AES-256 via openssl.
|
|
6
|
+
* Prunes old snapshots based on retention policy.
|
|
7
|
+
*/
|
|
8
|
+
import type { WorkspaceSyncConfig } from "./types.js";
|
|
9
|
+
type Logger = {
|
|
10
|
+
debug?: (msg: string) => void;
|
|
11
|
+
info: (msg: string) => void;
|
|
12
|
+
warn: (msg: string) => void;
|
|
13
|
+
error: (msg: string) => void;
|
|
14
|
+
};
|
|
15
|
+
export type BackupResult = {
|
|
16
|
+
ok: true;
|
|
17
|
+
snapshotName: string;
|
|
18
|
+
encrypted: boolean;
|
|
19
|
+
sizeBytes: number;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
error: string;
|
|
23
|
+
};
|
|
24
|
+
export type RestoreResult = {
|
|
25
|
+
ok: true;
|
|
26
|
+
snapshotName: string;
|
|
27
|
+
restoredTo: string;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
error: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function runBackup(params: {
|
|
33
|
+
syncConfig: WorkspaceSyncConfig;
|
|
34
|
+
workspaceDir: string;
|
|
35
|
+
stateDir: string;
|
|
36
|
+
logger: Logger;
|
|
37
|
+
}): Promise<BackupResult>;
|
|
38
|
+
export declare function listBackupSnapshots(params: {
|
|
39
|
+
syncConfig: WorkspaceSyncConfig;
|
|
40
|
+
stateDir: string;
|
|
41
|
+
logger: Logger;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
ok: true;
|
|
44
|
+
snapshots: string[];
|
|
45
|
+
} | {
|
|
46
|
+
ok: false;
|
|
47
|
+
error: string;
|
|
48
|
+
}>;
|
|
49
|
+
export declare function runRestore(params: {
|
|
50
|
+
syncConfig: WorkspaceSyncConfig;
|
|
51
|
+
workspaceDir: string;
|
|
52
|
+
stateDir: string;
|
|
53
|
+
snapshotName: string | "latest";
|
|
54
|
+
restoreTo: string;
|
|
55
|
+
logger: Logger;
|
|
56
|
+
}): Promise<RestoreResult>;
|
|
57
|
+
export declare function startBackupManager(syncConfig: WorkspaceSyncConfig, workspaceDir: string, stateDir: string, logger: Logger): void;
|
|
58
|
+
export declare function stopBackupManager(): void;
|
|
59
|
+
export declare function getBackupManagerStatus(): {
|
|
60
|
+
running: boolean;
|
|
61
|
+
lastBackupAt: Date | null;
|
|
62
|
+
lastBackupOk: boolean | null;
|
|
63
|
+
backupCount: number;
|
|
64
|
+
errorCount: number;
|
|
65
|
+
};
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=backup-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup-manager.d.ts","sourceRoot":"","sources":["../src/backup-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAiD,mBAAmB,EAAyB,MAAM,YAAY,CAAC;AAa5H,KAAK,MAAM,GAAG;IACZ,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B,CAAC;AAiTF,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,wBAAsB,SAAS,CAAC,MAAM,EAAE;IACtC,UAAU,EAAE,mBAAmB,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiFxB;AA2BD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,UAAU,EAAE,mBAAmB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAe5E;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,UAAU,EAAE,mBAAmB,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,QAAQ,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,aAAa,CAAC,CAoGzB;AAoED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,mBAAmB,EAC/B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,IAAI,CAyBN;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAUxC;AAED,wBAAgB,sBAAsB,IAAI;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAQA"}
|