openclaw-workspace-sync 2.1.4 → 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.
@@ -0,0 +1,42 @@
1
+ <svg id="my-svg" width="537.296875" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="flowchart" height="935" viewBox="0 0 537.296875 935" role="graphics-document document" aria-roledescription="flowchart-v2" style="background-color: white;"><style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:14px;fill:#333333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#50C878;}#my-svg .error-text{fill:#ffffff;stroke:#ffffff;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#5C6B77;stroke:#5C6B77;}#my-svg .marker.cross{stroke:#5C6B77;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:14px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ffffff;}#my-svg .cluster-label text{fill:#333333;}#my-svg .cluster-label span{color:#333333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#ffffff;color:#ffffff;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#4A90D9;stroke:#2E6EB5;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#5C6B77!important;stroke-width:0;stroke:#5C6B77;}#my-svg .arrowheadPath{fill:#0b0b0b;}#my-svg .edgePath .path{stroke:#5C6B77;stroke-width:2.0px;}#my-svg .flowchart-link{stroke:#5C6B77;fill:none;}#my-svg .edgeLabel{background-color:#ffffff;text-align:center;}#my-svg .edgeLabel p{background-color:#ffffff;}#my-svg .edgeLabel rect{opacity:0.5;background-color:#ffffff;fill:#ffffff;}#my-svg .labelBkg{background-color:rgba(255, 255, 255, 0.5);}#my-svg .cluster rect{fill:#F0F4F8;stroke:#94B8D9;stroke-width:1px;}#my-svg .cluster text{fill:#333333;}#my-svg .cluster span{color:#333333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:#50C878;border:1px solid #3BA35C;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333333;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:#ffffff;text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:#ffffff;padding:2px;}#my-svg .icon-shape rect,#my-svg .image-shape rect{opacity:0.5;background-color:#ffffff;fill:#ffffff;}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><marker id="my-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><g class="root"><g class="clusters"><g class="cluster" id="REMOTE" data-look="classic"><rect style="" x="87.46484375" y="644" width="324.890625" height="283"/><g class="cluster-label" transform="translate(167.48828125, 644)"><foreignObject width="164.84375" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>Your Bucket (S3 / R2 / B2)</p></span></div></foreignObject></g></g><g class="cluster" id="GW" data-look="classic"><rect style="" x="8" y="8" width="521.296875" height="131"/><g class="cluster-label" transform="translate(241.3046875, 8)"><foreignObject width="54.6875" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>Gateway</p></span></div></foreignObject></g></g></g><g class="edgePaths"><path d="M124.586,104L124.586,109.833C124.586,115.667,124.586,127.333,124.586,139C124.586,150.667,124.586,162.333,135.203,173.716C145.82,185.098,167.053,196.195,177.67,201.744L188.287,207.293" id="L_WS_TAR_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_WS_TAR_0" data-points="W3sieCI6MTI0LjU4NTkzNzUsInkiOjEwNH0seyJ4IjoxMjQuNTg1OTM3NSwieSI6MTM5fSx7IngiOjEyNC41ODU5Mzc1LCJ5IjoxNzR9LHsieCI6MTkxLjgzMjAzMTI1LCJ5IjoyMDkuMTQ1NzkzNzIyNTMyMTh9XQ==" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M375.234,104L375.234,109.833C375.234,115.667,375.234,127.333,375.234,139C375.234,150.667,375.234,162.333,364.618,173.716C354.001,185.098,332.767,196.195,322.15,201.744L311.533,207.293" id="L_CFG_TAR_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_CFG_TAR_0" data-points="W3sieCI6Mzc1LjIzNDM3NSwieSI6MTA0fSx7IngiOjM3NS4yMzQzNzUsInkiOjEzOX0seyJ4IjozNzUuMjM0Mzc1LCJ5IjoxNzR9LHsieCI6MzA3Ljk4ODI4MTI1LCJ5IjoyMDkuMTQ1NzkzNzIyNTMyMTh9XQ==" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M249.91,270L249.91,277.583C249.91,285.167,249.91,300.333,249.91,314.833C249.91,329.333,249.91,343.167,249.91,350.083L249.91,357" id="L_TAR_ENC_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_TAR_ENC_0" data-points="W3sieCI6MjQ5LjkxMDE1NjI1LCJ5IjoyNzB9LHsieCI6MjQ5LjkxMDE1NjI1LCJ5IjozMTUuNX0seyJ4IjoyNDkuOTEwMTU2MjUsInkiOjM2MX1d" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M249.91,422L249.91,429.583C249.91,437.167,249.91,452.333,249.91,466.833C249.91,481.333,249.91,495.167,249.91,502.083L249.91,509" id="L_ENC_RCAT_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_ENC_RCAT_0" data-points="W3sieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo0MjJ9LHsieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo0NjcuNX0seyJ4IjoyNDkuOTEwMTU2MjUsInkiOjUxM31d" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M249.91,574L249.91,579.833C249.91,585.667,249.91,597.333,249.91,609C249.91,620.667,249.91,632.333,249.91,643.333C249.91,654.333,249.91,664.667,249.91,669.833L249.91,675" id="L_RCAT_SNAP_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_RCAT_SNAP_0" data-points="W3sieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo1NzR9LHsieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo2MDl9LHsieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo2NDR9LHsieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo2Nzl9XQ==" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M249.91,740L249.91,747.583C249.91,755.167,249.91,770.333,249.91,784.833C249.91,799.333,249.91,813.167,249.91,820.083L249.91,827" id="L_SNAP_OLD_0" class="edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_SNAP_OLD_0" data-points="W3sieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo3NDB9LHsieCI6MjQ5LjkxMDE1NjI1LCJ5Ijo3ODUuNX0seyJ4IjoyNDkuOTEwMTU2MjUsInkiOjgzMX1d" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/></g><g class="edgeLabels"><g class="edgeLabel"><g class="label" data-id="L_WS_TAR_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_CFG_TAR_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(249.91015625, 315.5)"><g class="label" data-id="L_TAR_ENC_0" transform="translate(-13.6171875, -10.5)"><foreignObject width="27.234375" height="21"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"><p>pipe</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(249.91015625, 467.5)"><g class="label" data-id="L_ENC_RCAT_0" transform="translate(-13.6171875, -10.5)"><foreignObject width="27.234375" height="21"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"><p>pipe</p></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_RCAT_SNAP_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(249.91015625, 785.5)"><g class="label" data-id="L_SNAP_OLD_0" transform="translate(-49.5078125, -10.5)"><foreignObject width="99.015625" height="21"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"><p>retention prune</p></span></div></foreignObject></g></g></g><g class="nodes"><g class="node default" id="flowchart-WS-0" transform="translate(124.5859375, 73.5)"><rect class="basic label-container" style="" x="-76.5859375" y="-30.5" width="153.171875" height="61"/><g class="label" style="" transform="translate(-36.5859375, -10.5)"><rect/><foreignObject width="73.171875" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>/workspace</p></span></div></foreignObject></g></g><g class="node default" id="flowchart-CFG-1" transform="translate(375.234375, 73.5)"><rect class="basic label-container" style="" x="-114.0625" y="-30.5" width="228.125" height="61"/><g class="label" style="" transform="translate(-74.0625, -10.5)"><rect/><foreignObject width="148.125" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>config / cron / memory</p></span></div></foreignObject></g></g><g class="node default" id="flowchart-TAR-2" transform="translate(249.91015625, 239.5)"><rect class="basic label-container" style="" x="-58.078125" y="-30.5" width="116.15625" height="61"/><g class="label" style="" transform="translate(-18.078125, -10.5)"><rect/><foreignObject width="36.15625" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>tar cz</p></span></div></foreignObject></g></g><g class="node default" id="flowchart-ENC-3" transform="translate(249.91015625, 391.5)"><rect class="basic label-container" style="" x="-112.53125" y="-30.5" width="225.0625" height="61"/><g class="label" style="" transform="translate(-72.53125, -10.5)"><rect/><foreignObject width="145.0625" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>openssl enc\n(AES-256)</p></span></div></foreignObject></g></g><g class="node default" id="flowchart-RCAT-4" transform="translate(249.91015625, 543.5)"><rect class="basic label-container" style="" x="-74.3984375" y="-30.5" width="148.796875" height="61"/><g class="label" style="" transform="translate(-34.3984375, -10.5)"><rect/><foreignObject width="68.796875" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>rclone rcat</p></span></div></foreignObject></g></g><g class="node default" id="flowchart-SNAP-5" transform="translate(249.91015625, 709.5)"><rect class="basic label-container" style="" x="-122.4453125" y="-30.5" width="244.890625" height="61"/><g class="label" style="" transform="translate(-82.4453125, -10.5)"><rect/><foreignObject width="164.890625" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>backup-2026…Z.tar.gz.enc</p></span></div></foreignObject></g></g><g class="node default" id="flowchart-OLD-6" transform="translate(249.91015625, 861.5)"><rect class="basic label-container" style="" x="-88.6328125" y="-30.5" width="177.265625" height="61"/><g class="label" style="" transform="translate(-48.6328125, -10.5)"><rect/><foreignObject width="97.265625" height="21"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel"><p>older snapshots</p></span></div></foreignObject></g></g></g></g></g><style>.edgeLabel {
2
+ color: #333333 !important;
3
+ background-color: #ffffff !important;
4
+ }
5
+ .edgeLabel span {
6
+ color: #333333 !important;
7
+ fill: #333333 !important;
8
+ }
9
+ .edgeLabel p {
10
+ color: #333333 !important;
11
+ }
12
+ .labelBkg {
13
+ background-color: #ffffff !important;
14
+ }
15
+
16
+ /* Gateway subgraph — green tint */
17
+ #GW rect {
18
+ fill: #E8F5E9 !important;
19
+ stroke: #66BB6A !important;
20
+ }
21
+ #GW .cluster-label span {
22
+ color: #2E7D32 !important;
23
+ }
24
+
25
+ /* Cloud subgraph — amber tint */
26
+ #CLOUD rect {
27
+ fill: #FFF8E1 !important;
28
+ stroke: #FFB74D !important;
29
+ }
30
+ #CLOUD .cluster-label span {
31
+ color: #E65100 !important;
32
+ }
33
+
34
+ /* Local subgraph — blue tint */
35
+ #LOCAL rect {
36
+ fill: #E3F2FD !important;
37
+ stroke: #64B5F6 !important;
38
+ }
39
+ #LOCAL .cluster-label span {
40
+ color: #1565C0 !important;
41
+ }
42
+ </style></svg>
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "id": "openclaw-workspace-sync",
3
3
  "uiHints": {
4
+ "sync": {
5
+ "label": "Sync Settings",
6
+ "help": "Nested sync config (preferred). Same fields as flat config: provider, mode, interval, etc."
7
+ },
4
8
  "provider": {
5
9
  "label": "Cloud Provider",
6
10
  "help": "Cloud storage provider for workspace sync"
@@ -19,6 +23,10 @@
19
23
  "help": "Local subfolder name for ingestion (default: inbox). Mirror mode only.",
20
24
  "advanced": true
21
25
  },
26
+ "notifyOnInbox": {
27
+ "label": "Notify on Inbox",
28
+ "help": "Wake the agent when files arrive in _inbox after a mailbox drain. Off by default to avoid burning credits."
29
+ },
22
30
  "remotePath": {
23
31
  "label": "Remote Path",
24
32
  "placeholder": "openclaw-share",
@@ -119,12 +127,54 @@
119
127
  "label": "rclone Options",
120
128
  "help": "Key-value pairs passed directly to rclone config",
121
129
  "advanced": true
130
+ },
131
+ "backup.enabled": {
132
+ "label": "Enable Backups",
133
+ "help": "Encrypted snapshot backups to cloud storage"
134
+ },
135
+ "backup.provider": {
136
+ "label": "Backup Provider",
137
+ "help": "Cloud provider for backup storage (can differ from sync provider). Defaults to the sync provider."
138
+ },
139
+ "backup.bucket": {
140
+ "label": "Backup Bucket",
141
+ "help": "S3/R2 bucket name for backup snapshots"
142
+ },
143
+ "backup.prefix": {
144
+ "label": "Backup Prefix",
145
+ "placeholder": "habibi/",
146
+ "help": "Path prefix within the bucket for this agent's snapshots"
147
+ },
148
+ "backup.interval": {
149
+ "label": "Backup Interval (seconds)",
150
+ "placeholder": "86400",
151
+ "help": "How often to create backups (default: 86400 = daily)"
152
+ },
153
+ "backup.encrypt": {
154
+ "label": "Encrypt Backups",
155
+ "help": "Encrypt snapshots with AES-256 before upload"
156
+ },
157
+ "backup.passphrase": {
158
+ "label": "Encryption Passphrase",
159
+ "sensitive": true,
160
+ "help": "Passphrase for backup encryption. Use env var: ${BACKUP_PASSPHRASE}"
161
+ },
162
+ "backup.include": {
163
+ "label": "Backup Include",
164
+ "help": "What to include: workspace, config, cron, memory, sessions, credentials, skills, hooks, extensions, env, agents, pages, transcripts"
165
+ },
166
+ "backup.retain": {
167
+ "label": "Retention",
168
+ "help": "Number of snapshots to keep, or { daily: N, weekly: N, monthly: N }"
122
169
  }
123
170
  },
124
171
  "configSchema": {
125
172
  "type": "object",
126
- "additionalProperties": false,
127
173
  "properties": {
174
+ "sync": {
175
+ "type": "object",
176
+ "description": "Nested sync config (preferred). Contains the same fields as the flat config: provider, mode, interval, remotePath, etc."
177
+ },
128
178
  "provider": {
129
179
  "type": "string",
130
180
  "enum": [
@@ -146,6 +196,9 @@
146
196
  "ingestPath": {
147
197
  "type": "string"
148
198
  },
199
+ "notifyOnInbox": {
200
+ "type": "boolean"
201
+ },
149
202
  "remotePath": {
150
203
  "type": "string"
151
204
  },
@@ -189,6 +242,81 @@
189
242
  "copySymlinks": {
190
243
  "type": "boolean"
191
244
  },
245
+ "backup": {
246
+ "type": "object",
247
+ "additionalProperties": false,
248
+ "properties": {
249
+ "enabled": { "type": "boolean" },
250
+ "provider": {
251
+ "type": "string",
252
+ "enum": ["dropbox", "gdrive", "onedrive", "s3", "custom"]
253
+ },
254
+ "remoteName": { "type": "string" },
255
+ "configPath": { "type": "string" },
256
+ "remotePath": { "type": "string" },
257
+ "bucket": { "type": "string" },
258
+ "prefix": { "type": "string" },
259
+ "interval": { "type": "number", "minimum": 0 },
260
+ "encrypt": { "type": "boolean" },
261
+ "passphrase": { "type": "string" },
262
+ "include": {
263
+ "type": "array",
264
+ "items": {
265
+ "type": "string",
266
+ "enum": ["workspace", "config", "cron", "memory", "sessions", "credentials", "skills", "hooks", "extensions", "env", "agents", "pages", "transcripts"]
267
+ }
268
+ },
269
+ "retain": {
270
+ "description": "Number of snapshots to keep, or {daily, weekly, monthly} object for tiered retention"
271
+ },
272
+ "exclude": {
273
+ "type": "array",
274
+ "items": { "type": "string" }
275
+ },
276
+ "s3": {
277
+ "type": "object",
278
+ "properties": {
279
+ "endpoint": { "type": "string" },
280
+ "bucket": { "type": "string" },
281
+ "region": { "type": "string" },
282
+ "accessKeyId": { "type": "string" },
283
+ "secretAccessKey": { "type": "string" }
284
+ }
285
+ },
286
+ "dropbox": {
287
+ "type": "object",
288
+ "properties": {
289
+ "appFolder": { "type": "boolean" },
290
+ "appKey": { "type": "string" },
291
+ "appSecret": { "type": "string" },
292
+ "token": { "type": "string" }
293
+ }
294
+ },
295
+ "gdrive": {
296
+ "type": "object",
297
+ "properties": {
298
+ "token": { "type": "string" },
299
+ "teamDrive": { "type": "string" },
300
+ "rootFolderId": { "type": "string" }
301
+ }
302
+ },
303
+ "onedrive": {
304
+ "type": "object",
305
+ "properties": {
306
+ "token": { "type": "string" },
307
+ "driveId": { "type": "string" },
308
+ "driveType": { "type": "string", "enum": ["personal", "business", "sharepoint"] }
309
+ }
310
+ },
311
+ "custom": {
312
+ "type": "object",
313
+ "properties": {
314
+ "rcloneType": { "type": "string" },
315
+ "rcloneOptions": { "type": "object", "additionalProperties": { "type": "string" } }
316
+ }
317
+ }
318
+ }
319
+ },
192
320
  "s3": {
193
321
  "type": "object",
194
322
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-workspace-sync",
3
- "version": "2.1.4",
3
+ "version": "2.3.0",
4
4
  "description": "Workspace cloud sync via rclone — mailbox (inbox/outbox), mirror, or bisync (Dropbox, Google Drive, S3, OneDrive, 70+ providers)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,6 +31,8 @@ Each sync cycle: (1) pushes workspace to cloud excluding `_inbox/` and `_outbox/
31
31
 
32
32
  Users drop files in the local `_outbox/` folder (created by the cloud provider's desktop app). Files arrive in the agent's `_inbox/`. The agent or a skill processes them from there.
33
33
 
34
+ With `notifyOnInbox: true`, the agent is woken when files land in `_inbox`. A system event lists the new filenames so the agent can process them. Off by default — each notification costs an agent turn.
35
+
34
36
  ### Mirror mode with ingest
35
37
 
36
38
  With `ingest: true`, a local `inbox/` folder syncs one-way **up** to the remote workspace (additive only). For a more robust pattern, use `mailbox` mode instead.
@@ -78,7 +80,7 @@ Lists files in the configured cloud storage path.
78
80
 
79
81
  ## Configuration
80
82
 
81
- Workspace sync is configured via the plugin entry in `openclaw.json`:
83
+ Workspace sync is configured via the plugin entry in `openclaw.json`. The preferred format uses nested `sync` and `backup` blocks (flat config at root level is also supported):
82
84
 
83
85
  ```json
84
86
  {
@@ -87,15 +89,17 @@ Workspace sync is configured via the plugin entry in `openclaw.json`:
87
89
  "openclaw-workspace-sync": {
88
90
  "enabled": true,
89
91
  "config": {
90
- "provider": "dropbox",
91
- "mode": "mailbox",
92
- "remotePath": "",
93
- "localPath": "/",
94
- "interval": 60,
95
- "timeout": 1800,
96
- "onSessionStart": true,
97
- "onSessionEnd": true,
98
- "exclude": [".git/**", "node_modules/**", "*.log"]
92
+ "sync": {
93
+ "provider": "dropbox",
94
+ "mode": "mailbox",
95
+ "remotePath": "",
96
+ "localPath": "/",
97
+ "interval": 60,
98
+ "timeout": 1800,
99
+ "onSessionStart": true,
100
+ "onSessionEnd": true,
101
+ "exclude": [".git/**", "node_modules/**", "*.log"]
102
+ }
99
103
  }
100
104
  }
101
105
  }
@@ -105,12 +109,15 @@ Workspace sync is configured via the plugin entry in `openclaw.json`:
105
109
 
106
110
  ### Config keys
107
111
 
112
+ These keys live under `sync` in the nested format, or at the config root in flat format.
113
+
108
114
  | Key | Default | Description |
109
115
  |-----|---------|-------------|
110
116
  | `provider` | `"off"` | `dropbox`, `gdrive`, `onedrive`, `s3`, `custom`, or `off` |
111
117
  | `mode` | **required** | `mailbox` (inbox/outbox, safest), `mirror` (remote->local), or `bisync` (bidirectional) |
112
118
  | `ingest` | `false` | Enable local inbox for sending files to the agent (mirror mode only) |
113
119
  | `ingestPath` | `"inbox"` | Local subfolder name for ingestion |
120
+ | `notifyOnInbox` | `false` | Wake the agent when files arrive in `_inbox` (mailbox mode). Costs credits per notification. |
114
121
  | `remotePath` | `"openclaw-share"` | Folder name in cloud storage |
115
122
  | `localPath` | `"shared"` | Subfolder within workspace to sync |
116
123
  | `interval` | `0` | Background sync interval in seconds (0 = manual only, min 60) |
@@ -176,3 +183,46 @@ rclone ls cloud:openclaw-share
176
183
  - Only `**/.DS_Store` excluded by default — add your own excludes in config
177
184
  - Sync operations run in background (no LLM tokens used)
178
185
  - All rclone activity is logged at info level for visibility
186
+
187
+ ## Encrypted backups
188
+
189
+ Add a `backup` block to the plugin config for automated encrypted snapshots to your own cloud storage (S3, R2, B2, etc.). Backups stream directly (`tar | rclone rcat`) — no local temp files, so they work even when disk space is tight.
190
+
191
+ ### Backup commands
192
+
193
+ ```bash
194
+ openclaw workspace-sync backup now # Create a snapshot immediately
195
+ openclaw workspace-sync backup list # List available snapshots
196
+ openclaw workspace-sync backup restore # Restore latest snapshot
197
+ openclaw workspace-sync backup status # Check backup service status
198
+ ```
199
+
200
+ ### Backup config
201
+
202
+ ```json
203
+ {
204
+ "backup": {
205
+ "enabled": true,
206
+ "provider": "s3",
207
+ "bucket": "my-backups",
208
+ "prefix": "agent-name/",
209
+ "interval": 86400,
210
+ "encrypt": true,
211
+ "passphrase": "${BACKUP_PASSPHRASE}",
212
+ "include": ["workspace", "config", "cron", "memory"],
213
+ "retain": { "daily": 7, "weekly": 4 }
214
+ }
215
+ }
216
+ ```
217
+
218
+ | Key | Default | Description |
219
+ |-----|---------|-------------|
220
+ | `enabled` | `false` | Enable scheduled backups |
221
+ | `provider` | parent provider | Cloud provider (can differ from sync provider) |
222
+ | `bucket` | — | S3/R2 bucket name |
223
+ | `prefix` | `""` | Path prefix within the bucket |
224
+ | `interval` | `86400` | Backup interval in seconds (clamped to min 300) |
225
+ | `encrypt` | `false` | AES-256 client-side encryption |
226
+ | `passphrase` | — | Encryption passphrase (use env var) |
227
+ | `include` | `["workspace", "config", "cron", "memory"]` | What to back up |
228
+ | `retain` | `7` | Keep N snapshots, or `{ daily: N, weekly: N }` |