Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/gateway/sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ describe('syncToR2', () => {
expect(rsyncCall).toContain('--delete');
expect(rsyncCall).toContain('/root/.clawdbot/');
expect(rsyncCall).toContain('/data/moltbot/');
expect(rsyncCall).toContain('/root/clawd/');
expect(rsyncCall).toContain('/data/moltbot/clawd/');
expect(rsyncCall).toContain("--include='MEMORY.md'");
expect(rsyncCall).toContain("--include='IDENTITY.md'");
expect(rsyncCall).toContain("--include='USER.md'");
expect(rsyncCall).toContain("--include='SOUL.md'");
expect(rsyncCall).toContain("--include='memory/***'");
});
});
});
4 changes: 2 additions & 2 deletions src/gateway/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ export async function syncToR2(sandbox: Sandbox, env: MoltbotEnv): Promise<SyncR

// Run rsync to backup config to R2
// Note: Use --no-times because s3fs doesn't support setting timestamps
const syncCmd = `rsync -r --no-times --delete --exclude='*.lock' --exclude='*.log' --exclude='*.tmp' /root/.clawdbot/ ${R2_MOUNT_PATH}/clawdbot/ && rsync -r --no-times --delete /root/clawd/skills/ ${R2_MOUNT_PATH}/skills/ && date -Iseconds > ${R2_MOUNT_PATH}/.last-sync`;
const syncCmd = `rsync -r --no-times --delete --exclude='*.lock' --exclude='*.log' --exclude='*.tmp' /root/.clawdbot/ ${R2_MOUNT_PATH}/clawdbot/ && rsync -r --no-times --delete /root/clawd/skills/ ${R2_MOUNT_PATH}/skills/ && rsync -r --no-times --delete --include='MEMORY.md' --include='IDENTITY.md' --include='USER.md' --include='SOUL.md' --include='memory/***' --exclude='*' /root/clawd/ ${R2_MOUNT_PATH}/clawd/ && date -Iseconds > ${R2_MOUNT_PATH}/.last-sync`;

try {
const proc = await sandbox.startProcess(syncCmd);
await waitForProcess(proc, 30000); // 30 second timeout for sync

// Check for success by reading the timestamp file
// (process status may not update reliably in sandbox API)
// Note: backup structure is ${R2_MOUNT_PATH}/clawdbot/ and ${R2_MOUNT_PATH}/skills/
// Note: backup structure is ${R2_MOUNT_PATH}/clawdbot/, ${R2_MOUNT_PATH}/skills/, and ${R2_MOUNT_PATH}/clawd/
const timestampProc = await sandbox.startProcess(`cat ${R2_MOUNT_PATH}/.last-sync`);
await waitForProcess(timestampProc, 5000);
const timestampLogs = await timestampProc.getLogs();
Expand Down
18 changes: 18 additions & 0 deletions start-moltbot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,24 @@ if [ -d "$BACKUP_DIR/skills" ] && [ "$(ls -A $BACKUP_DIR/skills 2>/dev/null)" ];
fi
fi

# Restore clawd memory artifacts from R2 backup if available (only if R2 is newer)
CLAWD_DIR="/root/clawd"
if [ -d "$BACKUP_DIR/clawd" ]; then
if should_restore_from_r2; then
echo "Restoring clawd memory artifacts from $BACKUP_DIR/clawd..."
mkdir -p "$CLAWD_DIR"
cp -a "$BACKUP_DIR/clawd/MEMORY.md" "$CLAWD_DIR/" 2>/dev/null || true
cp -a "$BACKUP_DIR/clawd/IDENTITY.md" "$CLAWD_DIR/" 2>/dev/null || true
cp -a "$BACKUP_DIR/clawd/USER.md" "$CLAWD_DIR/" 2>/dev/null || true
cp -a "$BACKUP_DIR/clawd/SOUL.md" "$CLAWD_DIR/" 2>/dev/null || true
if [ -d "$BACKUP_DIR/clawd/memory" ]; then
mkdir -p "$CLAWD_DIR/memory"
cp -a "$BACKUP_DIR/clawd/memory/." "$CLAWD_DIR/memory/" 2>/dev/null || true
fi
echo "Restored clawd memory artifacts from R2 backup"
fi
fi

# If config file still doesn't exist, create from template
if [ ! -f "$CONFIG_FILE" ]; then
echo "No existing config found, initializing from template..."
Expand Down