Add bidirectional workspace synchronization with cloud storage providers (Dropbox, Google Drive, OneDrive, S3/R2) using rclone. Features: - Config-driven setup via workspace.sync in moltbot.json - Native CLI: moltbot workspace setup/sync/status/authorize/list - Session hooks: onSessionStart/onSessionEnd triggers (no LLM cost) - Background interval sync via gateway (no LLM cost) - Auto-install rclone when missing (Homebrew/official script) - Dropbox app folder support for ringfenced security - Secure defaults: syncs shared/ subdirectory only New files: - src/infra/rclone.ts - rclone wrapper - src/cli/workspace-cli.ts - CLI commands - src/hooks/bundled/workspace-sync/ - session hooks - src/gateway/workspace-sync-manager.ts - background sync - src/config/types.workspace.ts - config types - docs/gateway/workspace-sync.md - full documentation Tests: 23 unit tests for rclone helpers and hook handler
124 lines
2.8 KiB
Bash
Executable File
124 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Workspace cloud sync using rclone bisync
|
|
# Docs: https://docs.molt.bot/gateway/workspace-sync
|
|
|
|
set -e
|
|
|
|
# Configuration (override via environment)
|
|
RCLONE_CONFIG="${RCLONE_CONFIG:-$HOME/.config/rclone/rclone.conf}"
|
|
RCLONE_REMOTE="${RCLONE_REMOTE:-cloud}"
|
|
REMOTE_PATH="${REMOTE_PATH:-moltbot-share}"
|
|
LOCAL_PATH="${LOCAL_PATH:-${MOLTBOT_STATE_DIR:-${CLAWDBOT_STATE_DIR:-$HOME/.clawdbot}}/workspace/shared}"
|
|
|
|
# Flags
|
|
RESYNC="${RESYNC:-false}"
|
|
VERBOSE="${VERBOSE:-false}"
|
|
DRY_RUN="${DRY_RUN:-false}"
|
|
|
|
usage() {
|
|
cat << 'EOF'
|
|
Usage: workspace-sync.sh [OPTIONS]
|
|
|
|
Bidirectional sync between cloud storage and workspace.
|
|
|
|
Options:
|
|
--resync Force resync (required on first run)
|
|
--dry-run Show what would be synced without doing it
|
|
--verbose Show detailed output
|
|
--help Show this help
|
|
|
|
Environment:
|
|
RCLONE_CONFIG Path to rclone.conf (default: ~/.config/rclone/rclone.conf)
|
|
RCLONE_REMOTE rclone remote name (default: cloud)
|
|
REMOTE_PATH Folder in cloud storage (default: moltbot-share)
|
|
LOCAL_PATH Local folder to sync (default: <state-dir>/workspace/shared)
|
|
|
|
Examples:
|
|
# First sync (establishes baseline)
|
|
./scripts/workspace-sync.sh --resync
|
|
|
|
# Regular sync
|
|
./scripts/workspace-sync.sh
|
|
|
|
# Preview changes
|
|
./scripts/workspace-sync.sh --dry-run --verbose
|
|
|
|
Setup: https://docs.molt.bot/gateway/workspace-sync
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
# Parse arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--resync)
|
|
RESYNC=true
|
|
shift
|
|
;;
|
|
--dry-run)
|
|
DRY_RUN=true
|
|
shift
|
|
;;
|
|
--verbose|-v)
|
|
VERBOSE=true
|
|
shift
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Check rclone is installed
|
|
if ! command -v rclone &> /dev/null; then
|
|
echo "Error: rclone not installed"
|
|
echo "Install: curl -s https://rclone.org/install.sh | bash"
|
|
exit 1
|
|
fi
|
|
|
|
# Check config exists
|
|
if [[ ! -f "$RCLONE_CONFIG" ]]; then
|
|
echo "Error: rclone config not found at $RCLONE_CONFIG"
|
|
echo "Setup: https://docs.molt.bot/gateway/workspace-sync"
|
|
exit 1
|
|
fi
|
|
|
|
# Ensure local directory exists
|
|
mkdir -p "$LOCAL_PATH"
|
|
|
|
# Build rclone command
|
|
RCLONE_ARGS=(
|
|
bisync
|
|
"${RCLONE_REMOTE}:${REMOTE_PATH}"
|
|
"$LOCAL_PATH"
|
|
--config "$RCLONE_CONFIG"
|
|
--conflict-resolve newer
|
|
--conflict-suffix .conflict
|
|
--exclude ".git/**"
|
|
--exclude "node_modules/**"
|
|
--exclude "*.log"
|
|
--exclude ".DS_Store"
|
|
)
|
|
|
|
if [[ "$RESYNC" == "true" ]]; then
|
|
RCLONE_ARGS+=(--resync)
|
|
fi
|
|
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
|
RCLONE_ARGS+=(--dry-run)
|
|
fi
|
|
|
|
if [[ "$VERBOSE" == "true" ]]; then
|
|
RCLONE_ARGS+=(--verbose)
|
|
fi
|
|
|
|
# Run sync
|
|
echo "Syncing: ${RCLONE_REMOTE}:${REMOTE_PATH} <-> $LOCAL_PATH"
|
|
rclone "${RCLONE_ARGS[@]}"
|
|
|
|
echo "Sync complete: $(date)"
|