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.md +395 -262
- package/README.src.md +412 -262
- 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 +247 -27
- 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 +2 -2
- package/skills/workspace-sync/SKILL.md +57 -10
|
@@ -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>
|
package/openclaw.plugin.json
CHANGED
|
@@ -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"
|
|
@@ -123,12 +127,54 @@
|
|
|
123
127
|
"label": "rclone Options",
|
|
124
128
|
"help": "Key-value pairs passed directly to rclone config",
|
|
125
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 }"
|
|
126
169
|
}
|
|
127
170
|
},
|
|
128
171
|
"configSchema": {
|
|
129
172
|
"type": "object",
|
|
130
|
-
"additionalProperties": false,
|
|
131
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
|
+
},
|
|
132
178
|
"provider": {
|
|
133
179
|
"type": "string",
|
|
134
180
|
"enum": [
|
|
@@ -196,6 +242,81 @@
|
|
|
196
242
|
"copySymlinks": {
|
|
197
243
|
"type": "boolean"
|
|
198
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
|
+
},
|
|
199
320
|
"s3": {
|
|
200
321
|
"type": "object",
|
|
201
322
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-workspace-sync",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Workspace cloud sync via rclone — mailbox
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"description": "Workspace cloud sync & encrypted backup via rclone — mailbox, mirror, bisync + AES-256 snapshots (Dropbox, S3, R2, 70+ providers)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -80,7 +80,7 @@ Lists files in the configured cloud storage path.
|
|
|
80
80
|
|
|
81
81
|
## Configuration
|
|
82
82
|
|
|
83
|
-
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):
|
|
84
84
|
|
|
85
85
|
```json
|
|
86
86
|
{
|
|
@@ -89,15 +89,17 @@ Workspace sync is configured via the plugin entry in `openclaw.json`:
|
|
|
89
89
|
"openclaw-workspace-sync": {
|
|
90
90
|
"enabled": true,
|
|
91
91
|
"config": {
|
|
92
|
-
"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
+
}
|
|
101
103
|
}
|
|
102
104
|
}
|
|
103
105
|
}
|
|
@@ -107,6 +109,8 @@ Workspace sync is configured via the plugin entry in `openclaw.json`:
|
|
|
107
109
|
|
|
108
110
|
### Config keys
|
|
109
111
|
|
|
112
|
+
These keys live under `sync` in the nested format, or at the config root in flat format.
|
|
113
|
+
|
|
110
114
|
| Key | Default | Description |
|
|
111
115
|
|-----|---------|-------------|
|
|
112
116
|
| `provider` | `"off"` | `dropbox`, `gdrive`, `onedrive`, `s3`, `custom`, or `off` |
|
|
@@ -179,3 +183,46 @@ rclone ls cloud:openclaw-share
|
|
|
179
183
|
- Only `**/.DS_Store` excluded by default — add your own excludes in config
|
|
180
184
|
- Sync operations run in background (no LLM tokens used)
|
|
181
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 }` |
|