openclaw-workspace-sync 1.0.0 → 1.0.2

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 CHANGED
@@ -21,7 +21,7 @@ Local Machine Cloud Provider Remote Gateway
21
21
  ## Install
22
22
 
23
23
  ```bash
24
- openclaw plugins install @openclaw/workspace-sync
24
+ openclaw plugins install openclaw-workspace-sync
25
25
  ```
26
26
 
27
27
  Or clone into your extensions directory:
@@ -57,7 +57,7 @@ Add to your `openclaw.json`:
57
57
  {
58
58
  "plugins": {
59
59
  "entries": {
60
- "workspace-sync": {
60
+ "openclaw-workspace-sync": {
61
61
  "enabled": true,
62
62
  "config": {
63
63
  "provider": "dropbox",
@@ -292,13 +292,13 @@ chmod -R 755 <workspace>/shared
292
292
 
293
293
  ```bash
294
294
  # Install dependencies
295
- pnpm install
295
+ npm install
296
296
 
297
297
  # Run tests
298
- pnpm test
298
+ npm test
299
299
 
300
300
  # Type check
301
- pnpm tsgo --noEmit
301
+ npx tsc --noEmit
302
302
  ```
303
303
 
304
304
  ## License
@@ -0,0 +1,21 @@
1
+ /**
2
+ * OpenClaw Workspace Sync Plugin
3
+ *
4
+ * Bidirectional workspace cloud sync via rclone.
5
+ * Supports Dropbox, Google Drive, S3, OneDrive, and 70+ providers.
6
+ *
7
+ * Features:
8
+ * - CLI commands: openclaw workspace sync/status/setup/authorize/list
9
+ * - Background periodic sync (pure rclone, zero LLM cost)
10
+ * - Session start/end hooks for automatic sync
11
+ * - Config-driven rclone setup (no manual rclone config needed)
12
+ */
13
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
14
+ declare const workspaceSyncPlugin: {
15
+ id: string;
16
+ name: string;
17
+ description: string;
18
+ register(api: OpenClawPluginApi): void;
19
+ };
20
+ export default workspaceSyncPlugin;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAyB7D,QAAA,MAAM,mBAAmB;;;;kBAMT,iBAAiB;CAmmBhC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,527 @@
1
+ /**
2
+ * OpenClaw Workspace Sync Plugin
3
+ *
4
+ * Bidirectional workspace cloud sync via rclone.
5
+ * Supports Dropbox, Google Drive, S3, OneDrive, and 70+ providers.
6
+ *
7
+ * Features:
8
+ * - CLI commands: openclaw workspace sync/status/setup/authorize/list
9
+ * - Background periodic sync (pure rclone, zero LLM cost)
10
+ * - Session start/end hooks for automatic sync
11
+ * - Config-driven rclone setup (no manual rclone config needed)
12
+ */
13
+ import * as clack from "@clack/prompts";
14
+ import { setLogger, isRcloneInstalled, ensureRcloneInstalled, isRcloneConfigured, ensureRcloneConfigFromConfig, resolveSyncConfig, runBisync, runSync, checkRemote, listRemote, authorizeRclone, writeRcloneConfig, generateRcloneConfig, } from "./rclone.js";
15
+ import { startSyncManager, stopSyncManager, getSyncManagerStatus } from "./sync-manager.js";
16
+ function parsePluginConfig(raw) {
17
+ if (!raw)
18
+ return {};
19
+ return raw;
20
+ }
21
+ const workspaceSyncPlugin = {
22
+ id: "openclaw-workspace-sync",
23
+ name: "Workspace Cloud Sync",
24
+ description: "Bidirectional workspace sync with cloud storage (Dropbox, Google Drive, S3, OneDrive, 70+ providers) via rclone",
25
+ register(api) {
26
+ const syncConfig = parsePluginConfig(api.pluginConfig);
27
+ setLogger(api.logger);
28
+ api.logger.info(`workspace-sync: registered (provider: ${syncConfig.provider ?? "not configured"})`);
29
+ // ========================================================================
30
+ // CLI Commands
31
+ // ========================================================================
32
+ api.registerCli(({ program, workspaceDir }) => {
33
+ const workspace = program
34
+ .command("workspace")
35
+ .description("Workspace management and cloud sync");
36
+ // openclaw workspace sync
37
+ workspace
38
+ .command("sync")
39
+ .description("Sync workspace with cloud storage")
40
+ .option("--agent <id>", "Agent ID (default: main)")
41
+ .option("--resync", "Force resync (required for first sync)")
42
+ .option("--dry-run", "Preview changes without syncing")
43
+ .option("--direction <dir>", "One-way sync: pull or push")
44
+ .option("-v, --verbose", "Verbose output")
45
+ .action(async (opts) => {
46
+ const cfgSync = syncConfig;
47
+ const wsDir = workspaceDir ?? process.cwd();
48
+ if (!cfgSync.provider || cfgSync.provider === "off") {
49
+ console.error("Workspace sync not configured.");
50
+ console.error("Run: openclaw workspace setup");
51
+ process.exit(1);
52
+ }
53
+ const installed = await isRcloneInstalled();
54
+ if (!installed) {
55
+ console.error("rclone not installed.");
56
+ console.error("Run: openclaw workspace setup");
57
+ process.exit(1);
58
+ }
59
+ const resolved = resolveSyncConfig(cfgSync, wsDir);
60
+ ensureRcloneConfigFromConfig(cfgSync, resolved.configPath, resolved.remoteName);
61
+ if (!isRcloneConfigured(resolved.configPath, resolved.remoteName)) {
62
+ console.error(`rclone not configured for remote "${resolved.remoteName}".`);
63
+ console.error("Run: openclaw workspace authorize");
64
+ process.exit(1);
65
+ }
66
+ console.log(`Syncing ${resolved.remoteName}:${resolved.remotePath}`);
67
+ console.log(`Local: ${resolved.localPath}`);
68
+ let result;
69
+ if (opts.direction) {
70
+ result = await runSync({
71
+ configPath: resolved.configPath,
72
+ remoteName: resolved.remoteName,
73
+ remotePath: resolved.remotePath,
74
+ localPath: resolved.localPath,
75
+ direction: opts.direction,
76
+ exclude: resolved.exclude,
77
+ dryRun: opts.dryRun,
78
+ verbose: opts.verbose,
79
+ });
80
+ }
81
+ else {
82
+ result = await runBisync({
83
+ configPath: resolved.configPath,
84
+ remoteName: resolved.remoteName,
85
+ remotePath: resolved.remotePath,
86
+ localPath: resolved.localPath,
87
+ conflictResolve: resolved.conflictResolve,
88
+ exclude: resolved.exclude,
89
+ copySymlinks: resolved.copySymlinks,
90
+ resync: opts.resync,
91
+ dryRun: opts.dryRun,
92
+ verbose: opts.verbose,
93
+ });
94
+ }
95
+ if (result.ok) {
96
+ console.log("Sync completed");
97
+ if (result.filesTransferred) {
98
+ console.log(`Files transferred: ${result.filesTransferred}`);
99
+ }
100
+ }
101
+ else {
102
+ console.error(`Sync failed: ${result.error}`);
103
+ if (result.error?.includes("--resync")) {
104
+ console.error("First sync requires --resync: openclaw workspace sync --resync");
105
+ }
106
+ process.exit(1);
107
+ }
108
+ });
109
+ // openclaw workspace status
110
+ workspace
111
+ .command("status")
112
+ .description("Show workspace sync status")
113
+ .option("--agent <id>", "Agent ID (default: main)")
114
+ .option("-v, --verbose", "Verbose output")
115
+ .action(async (opts) => {
116
+ const cfgSync = syncConfig;
117
+ const wsDir = workspaceDir ?? process.cwd();
118
+ console.log("Workspace Sync Status");
119
+ console.log("");
120
+ if (!cfgSync.provider || cfgSync.provider === "off") {
121
+ console.log("Provider: not configured");
122
+ console.log("Configure in openclaw.json plugins.entries.workspace-sync.config");
123
+ return;
124
+ }
125
+ const resolved = resolveSyncConfig(cfgSync, wsDir);
126
+ console.log(`Provider: ${cfgSync.provider}`);
127
+ console.log(`Remote: ${resolved.remoteName}:${resolved.remotePath}`);
128
+ console.log(`Local: ${resolved.localPath}`);
129
+ console.log(`Config: ${resolved.configPath}`);
130
+ console.log("");
131
+ const installed = await isRcloneInstalled();
132
+ if (!installed) {
133
+ console.log("rclone: NOT installed");
134
+ return;
135
+ }
136
+ console.log("rclone: installed");
137
+ ensureRcloneConfigFromConfig(cfgSync, resolved.configPath, resolved.remoteName);
138
+ const configured = isRcloneConfigured(resolved.configPath, resolved.remoteName);
139
+ if (!configured) {
140
+ console.log("rclone config: NOT configured");
141
+ console.log("Run: openclaw workspace authorize");
142
+ return;
143
+ }
144
+ console.log("rclone config: OK");
145
+ const check = await checkRemote({
146
+ configPath: resolved.configPath,
147
+ remoteName: resolved.remoteName,
148
+ });
149
+ if (!check.ok) {
150
+ console.log(`Connection: FAILED (${check.error})`);
151
+ return;
152
+ }
153
+ console.log("Connection: OK");
154
+ const list = await listRemote({
155
+ configPath: resolved.configPath,
156
+ remoteName: resolved.remoteName,
157
+ remotePath: resolved.remotePath,
158
+ });
159
+ if (list.ok) {
160
+ console.log("");
161
+ console.log(`Remote files: ${list.files.length}`);
162
+ if (opts.verbose && list.files.length > 0) {
163
+ for (const file of list.files.slice(0, 10)) {
164
+ console.log(` ${file}`);
165
+ }
166
+ if (list.files.length > 10) {
167
+ console.log(` ... and ${list.files.length - 10} more`);
168
+ }
169
+ }
170
+ }
171
+ // Background sync manager status
172
+ const mgrStatus = getSyncManagerStatus();
173
+ console.log("");
174
+ console.log("Background sync:");
175
+ console.log(` Running: ${mgrStatus.running ? "yes" : "no"}`);
176
+ console.log(` On session start: ${resolved.onSessionStart ? "yes" : "no"}`);
177
+ console.log(` On session end: ${resolved.onSessionEnd ? "yes" : "no"}`);
178
+ if (resolved.interval > 0) {
179
+ console.log(` Interval: ${resolved.interval}s (pure rclone, zero LLM cost)`);
180
+ }
181
+ else {
182
+ console.log(" Interval: disabled");
183
+ }
184
+ if (mgrStatus.lastSyncAt) {
185
+ console.log(` Last sync: ${mgrStatus.lastSyncAt.toISOString()}`);
186
+ console.log(` Last sync OK: ${mgrStatus.lastSyncOk}`);
187
+ console.log(` Total syncs: ${mgrStatus.syncCount}`);
188
+ console.log(` Errors: ${mgrStatus.errorCount}`);
189
+ }
190
+ });
191
+ // openclaw workspace setup — interactive wizard
192
+ workspace
193
+ .command("setup")
194
+ .description("Interactive setup wizard for cloud sync")
195
+ .action(async () => {
196
+ clack.intro("Workspace Cloud Sync Setup");
197
+ const rcloneInstalled = await isRcloneInstalled();
198
+ if (!rcloneInstalled) {
199
+ const installed = await ensureRcloneInstalled(async (message, defaultValue) => {
200
+ const result = await clack.confirm({ message, initialValue: defaultValue });
201
+ return !clack.isCancel(result) && result;
202
+ });
203
+ if (!installed) {
204
+ clack.note("Install rclone manually:\n\n" +
205
+ " macOS: brew install rclone\n" +
206
+ " Linux: curl -s https://rclone.org/install.sh | sudo bash\n" +
207
+ " Docker: Add to Dockerfile: RUN curl -s https://rclone.org/install.sh | bash", "Installation required");
208
+ clack.outro("Install rclone and run this command again.");
209
+ process.exit(1);
210
+ return;
211
+ }
212
+ }
213
+ clack.log.success("rclone is installed");
214
+ const provider = (await clack.select({
215
+ message: "Select cloud provider",
216
+ options: [
217
+ { value: "dropbox", label: "Dropbox", hint: "Recommended - easy setup" },
218
+ { value: "gdrive", label: "Google Drive", hint: "Requires service account" },
219
+ { value: "onedrive", label: "OneDrive", hint: "Microsoft 365" },
220
+ { value: "s3", label: "S3 / R2 / Minio", hint: "Access key authentication" },
221
+ ],
222
+ }));
223
+ if (clack.isCancel(provider)) {
224
+ clack.cancel("Setup cancelled.");
225
+ return;
226
+ }
227
+ const remotePath = (await clack.text({
228
+ message: "Remote folder name",
229
+ placeholder: "openclaw-share",
230
+ initialValue: "openclaw-share",
231
+ validate: (value = "") => {
232
+ if (!value.trim())
233
+ return "Folder name is required";
234
+ if (value.includes("/"))
235
+ return "Use a simple folder name, not a path";
236
+ return undefined;
237
+ },
238
+ }));
239
+ if (clack.isCancel(remotePath)) {
240
+ clack.cancel("Setup cancelled.");
241
+ return;
242
+ }
243
+ let appKey;
244
+ let appSecret;
245
+ if (provider === "dropbox") {
246
+ const accessType = (await clack.select({
247
+ message: "Dropbox access type",
248
+ options: [
249
+ { value: "full", label: "Full Dropbox", hint: "Simpler setup" },
250
+ { value: "app", label: "App Folder only", hint: "More secure" },
251
+ ],
252
+ }));
253
+ if (clack.isCancel(accessType)) {
254
+ clack.cancel("Setup cancelled.");
255
+ return;
256
+ }
257
+ if (accessType === "app") {
258
+ clack.note("1. Go to https://www.dropbox.com/developers/apps\n" +
259
+ "2. Create app: Scoped access > App folder\n" +
260
+ "3. Enable: files.metadata.read/write, files.content.read/write\n" +
261
+ "4. Copy App key and App secret", "Create Dropbox App");
262
+ appKey = (await clack.text({
263
+ message: "Dropbox App key",
264
+ placeholder: "your-app-key",
265
+ }));
266
+ if (clack.isCancel(appKey)) {
267
+ clack.cancel("Setup cancelled.");
268
+ return;
269
+ }
270
+ appSecret = (await clack.text({
271
+ message: "Dropbox App secret",
272
+ placeholder: "your-app-secret",
273
+ }));
274
+ if (clack.isCancel(appSecret)) {
275
+ clack.cancel("Setup cancelled.");
276
+ return;
277
+ }
278
+ }
279
+ }
280
+ const intervalChoice = (await clack.select({
281
+ message: "Background sync interval",
282
+ options: [
283
+ { value: "0", label: "Manual only", hint: "Run 'openclaw workspace sync' when needed" },
284
+ { value: "300", label: "Every 5 minutes", hint: "Recommended" },
285
+ { value: "600", label: "Every 10 minutes" },
286
+ { value: "1800", label: "Every 30 minutes" },
287
+ { value: "3600", label: "Every hour" },
288
+ ],
289
+ }));
290
+ if (clack.isCancel(intervalChoice)) {
291
+ clack.cancel("Setup cancelled.");
292
+ return;
293
+ }
294
+ const interval = parseInt(intervalChoice, 10);
295
+ const onSessionStart = (await clack.confirm({
296
+ message: "Sync when session starts?",
297
+ initialValue: true,
298
+ }));
299
+ if (clack.isCancel(onSessionStart)) {
300
+ clack.cancel("Setup cancelled.");
301
+ return;
302
+ }
303
+ // OAuth authorization
304
+ clack.log.info("Starting OAuth authorization...");
305
+ clack.note("A browser window will open.\nLog in and authorize access, then return here.", "Authorization");
306
+ const authResult = await authorizeRclone(provider, appKey, appSecret);
307
+ if (!authResult.ok) {
308
+ clack.log.error(`Authorization failed: ${authResult.error}`);
309
+ clack.outro("Fix the error and run 'openclaw workspace setup' again.");
310
+ process.exit(1);
311
+ return;
312
+ }
313
+ clack.log.success("Authorization successful");
314
+ // Save rclone config
315
+ const stateDir = process.env.OPENCLAW_STATE_DIR ?? `${process.env.HOME}/.openclaw`;
316
+ const configPath = `${stateDir}/.config/rclone/rclone.conf`;
317
+ const remoteName = "cloud";
318
+ const configContent = generateRcloneConfig(provider, remoteName, authResult.token, {
319
+ dropbox: appKey ? { appKey, appSecret } : undefined,
320
+ });
321
+ writeRcloneConfig(configPath, configContent);
322
+ clack.log.success(`rclone config saved to ${configPath}`);
323
+ // Print config snippet for user to add to openclaw.json
324
+ clack.note(`Add to your openclaw.json:\n\n` +
325
+ `"plugins": {\n` +
326
+ ` "entries": {\n` +
327
+ ` "workspace-sync": {\n` +
328
+ ` "enabled": true,\n` +
329
+ ` "config": {\n` +
330
+ ` "provider": "${provider}",\n` +
331
+ ` "remotePath": "${remotePath.trim()}",\n` +
332
+ ` "interval": ${interval},\n` +
333
+ ` "onSessionStart": ${onSessionStart}\n` +
334
+ ` }\n` +
335
+ ` }\n` +
336
+ ` }\n` +
337
+ `}`, "Plugin Configuration");
338
+ clack.outro("Workspace sync configured! Run: openclaw workspace sync --resync");
339
+ });
340
+ // openclaw workspace authorize
341
+ workspace
342
+ .command("authorize")
343
+ .description("Authorize rclone with cloud provider")
344
+ .option("--provider <name>", "Provider: dropbox, gdrive, onedrive, s3")
345
+ .option("--app-key <key>", "Dropbox app key")
346
+ .option("--app-secret <secret>", "Dropbox app secret")
347
+ .action(async (opts) => {
348
+ const provider = opts.provider ||
349
+ syncConfig.provider ||
350
+ "dropbox";
351
+ if (provider === "off" || provider === "custom") {
352
+ console.error("Please specify a provider: --provider dropbox");
353
+ process.exit(1);
354
+ }
355
+ const installed = await isRcloneInstalled();
356
+ if (!installed) {
357
+ console.error("rclone not installed.");
358
+ console.error("Install: curl -s https://rclone.org/install.sh | bash");
359
+ process.exit(1);
360
+ }
361
+ console.log(`Authorizing with ${provider}...`);
362
+ console.log("A browser window will open for authentication.");
363
+ console.log("");
364
+ const result = await authorizeRclone(provider, opts.appKey || syncConfig.dropbox?.appKey, opts.appSecret || syncConfig.dropbox?.appSecret);
365
+ if (!result.ok) {
366
+ console.error(`Authorization failed: ${result.error}`);
367
+ process.exit(1);
368
+ }
369
+ console.log("Authorization successful");
370
+ const stateDir = process.env.OPENCLAW_STATE_DIR ?? `${process.env.HOME}/.openclaw`;
371
+ const remoteName = syncConfig.remoteName || "cloud";
372
+ const configPath = syncConfig.configPath || `${stateDir}/.config/rclone/rclone.conf`;
373
+ const configContent = generateRcloneConfig(provider, remoteName, result.token, {
374
+ dropbox: syncConfig.dropbox,
375
+ s3: syncConfig.s3,
376
+ });
377
+ writeRcloneConfig(configPath, configContent);
378
+ console.log(`Config saved to: ${configPath}`);
379
+ console.log("");
380
+ console.log("Next: openclaw workspace sync --resync");
381
+ });
382
+ // openclaw workspace list
383
+ workspace
384
+ .command("list")
385
+ .description("List files in remote storage")
386
+ .option("--agent <id>", "Agent ID (default: main)")
387
+ .action(async (opts) => {
388
+ const cfgSync = syncConfig;
389
+ const wsDir = workspaceDir ?? process.cwd();
390
+ if (!cfgSync.provider || cfgSync.provider === "off") {
391
+ console.error("Workspace sync not configured.");
392
+ process.exit(1);
393
+ }
394
+ const resolved = resolveSyncConfig(cfgSync, wsDir);
395
+ ensureRcloneConfigFromConfig(cfgSync, resolved.configPath, resolved.remoteName);
396
+ if (!isRcloneConfigured(resolved.configPath, resolved.remoteName)) {
397
+ console.error("rclone not configured.");
398
+ console.error("Run: openclaw workspace authorize");
399
+ process.exit(1);
400
+ }
401
+ const result = await listRemote({
402
+ configPath: resolved.configPath,
403
+ remoteName: resolved.remoteName,
404
+ remotePath: resolved.remotePath,
405
+ });
406
+ if (!result.ok) {
407
+ console.error(`Failed to list: ${result.error}`);
408
+ process.exit(1);
409
+ }
410
+ if (result.files.length === 0) {
411
+ console.log("No files in remote.");
412
+ return;
413
+ }
414
+ console.log(`${resolved.remoteName}:${resolved.remotePath}/`);
415
+ for (const file of result.files) {
416
+ console.log(` ${file}`);
417
+ }
418
+ console.log(`\n${result.files.length} files`);
419
+ });
420
+ }, { commands: ["workspace"] });
421
+ // ========================================================================
422
+ // Session Hooks
423
+ // ========================================================================
424
+ if (syncConfig.onSessionStart) {
425
+ api.on("session_start", async (_event, ctx) => {
426
+ if (!syncConfig.provider || syncConfig.provider === "off")
427
+ return;
428
+ api.logger.info("[workspace-sync] triggered on session start");
429
+ try {
430
+ const installed = await isRcloneInstalled();
431
+ if (!installed) {
432
+ api.logger.warn("[workspace-sync] rclone not installed, skipping sync");
433
+ return;
434
+ }
435
+ const wsDir = ctx.agentId
436
+ ? api.resolvePath(`agents/${ctx.agentId}/workspace`)
437
+ : api.resolvePath("workspace");
438
+ const resolved = resolveSyncConfig(syncConfig, wsDir);
439
+ ensureRcloneConfigFromConfig(syncConfig, resolved.configPath, resolved.remoteName);
440
+ if (!isRcloneConfigured(resolved.configPath, resolved.remoteName)) {
441
+ api.logger.warn(`[workspace-sync] rclone not configured for "${resolved.remoteName}", skipping`);
442
+ return;
443
+ }
444
+ api.logger.info(`[workspace-sync] syncing ${resolved.remoteName}:${resolved.remotePath} <-> ${resolved.localPath}`);
445
+ const result = await runBisync({
446
+ configPath: resolved.configPath,
447
+ remoteName: resolved.remoteName,
448
+ remotePath: resolved.remotePath,
449
+ localPath: resolved.localPath,
450
+ conflictResolve: resolved.conflictResolve,
451
+ exclude: resolved.exclude,
452
+ copySymlinks: resolved.copySymlinks,
453
+ });
454
+ if (result.ok) {
455
+ api.logger.info("[workspace-sync] session start sync completed");
456
+ }
457
+ else if (result.error?.includes("--resync")) {
458
+ api.logger.warn("[workspace-sync] first sync requires manual --resync. Run: openclaw workspace sync --resync");
459
+ }
460
+ else {
461
+ api.logger.error(`[workspace-sync] sync failed: ${result.error}`);
462
+ }
463
+ }
464
+ catch (err) {
465
+ api.logger.error(`[workspace-sync] error: ${err instanceof Error ? err.message : String(err)}`);
466
+ }
467
+ });
468
+ }
469
+ if (syncConfig.onSessionEnd) {
470
+ api.on("session_end", async (_event, ctx) => {
471
+ if (!syncConfig.provider || syncConfig.provider === "off")
472
+ return;
473
+ api.logger.info("[workspace-sync] triggered on session end");
474
+ try {
475
+ const installed = await isRcloneInstalled();
476
+ if (!installed)
477
+ return;
478
+ const wsDir = ctx.agentId
479
+ ? api.resolvePath(`agents/${ctx.agentId}/workspace`)
480
+ : api.resolvePath("workspace");
481
+ const resolved = resolveSyncConfig(syncConfig, wsDir);
482
+ ensureRcloneConfigFromConfig(syncConfig, resolved.configPath, resolved.remoteName);
483
+ if (!isRcloneConfigured(resolved.configPath, resolved.remoteName))
484
+ return;
485
+ const result = await runBisync({
486
+ configPath: resolved.configPath,
487
+ remoteName: resolved.remoteName,
488
+ remotePath: resolved.remotePath,
489
+ localPath: resolved.localPath,
490
+ conflictResolve: resolved.conflictResolve,
491
+ exclude: resolved.exclude,
492
+ copySymlinks: resolved.copySymlinks,
493
+ });
494
+ if (result.ok) {
495
+ api.logger.info("[workspace-sync] session end sync completed");
496
+ }
497
+ else {
498
+ api.logger.error(`[workspace-sync] sync failed: ${result.error}`);
499
+ }
500
+ }
501
+ catch (err) {
502
+ api.logger.error(`[workspace-sync] error: ${err instanceof Error ? err.message : String(err)}`);
503
+ }
504
+ });
505
+ }
506
+ // ========================================================================
507
+ // Background Sync Service
508
+ // ========================================================================
509
+ api.registerService({
510
+ id: "openclaw-workspace-sync",
511
+ start: (ctx) => {
512
+ if (!syncConfig.provider || syncConfig.provider === "off") {
513
+ api.logger.info("[workspace-sync] service: sync not configured, idle");
514
+ return;
515
+ }
516
+ const wsDir = ctx.workspaceDir ?? api.resolvePath("workspace");
517
+ startSyncManager(syncConfig, wsDir, ctx.stateDir, ctx.logger);
518
+ },
519
+ stop: () => {
520
+ stopSyncManager();
521
+ api.logger.info("[workspace-sync] service stopped");
522
+ },
523
+ });
524
+ },
525
+ };
526
+ export default workspaceSyncPlugin;
527
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}