feat(sync): wire up sync.mode config to change sync behavior

Implements hq-ew1mbr.27: The sync.mode config now actually changes how
bd sync operates:

- git-portable (default): JSONL exported on push, imported on pull
- realtime: JSONL exported on every change (placeholder for daemon hook)
- dolt-native: Uses Dolt Push/Pull, skips JSONL workflow entirely
- belt-and-suspenders: Both Dolt remotes AND JSONL for redundancy

Changes:
- Add sync_mode.go with mode constants, Get/Set functions, and helpers
- Update bd sync --status to show actual mode from config
- Add --set-mode flag to bd sync for configuring the mode
- Modify doExportSync to respect mode (Dolt push for dolt-native)
- Modify doPullFirstSync to use Dolt pull for dolt-native mode
- Add RemoteStorage interface for Push/Pull operations
- Add comprehensive tests for sync mode functionality

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beads/crew/emma
2026-01-17 13:59:53 -08:00
committed by Steve Yegge
parent c99bd00ca7
commit 356ab92b78
6 changed files with 494 additions and 520 deletions

View File

@@ -117,3 +117,33 @@ func AsVersioned(s Storage) (VersionedStorage, bool) {
vs, ok := s.(VersionedStorage)
return vs, ok
}
// RemoteStorage extends VersionedStorage with remote synchronization capabilities.
// This interface is implemented by storage backends that support push/pull to
// remote repositories (e.g., Dolt with DoltHub remotes).
type RemoteStorage interface {
VersionedStorage
// Push pushes commits to the configured remote.
Push(ctx context.Context) error
// Pull pulls changes from the configured remote.
Pull(ctx context.Context) error
// AddRemote adds a new remote with the given name and URL.
AddRemote(ctx context.Context, name, url string) error
}
// IsRemote checks if a storage instance supports remote synchronization.
// Returns true if the storage implements RemoteStorage.
func IsRemote(s Storage) bool {
_, ok := s.(RemoteStorage)
return ok
}
// AsRemote attempts to cast a Storage to RemoteStorage.
// Returns the RemoteStorage and true if successful, nil and false otherwise.
func AsRemote(s Storage) (RemoteStorage, bool) {
rs, ok := s.(RemoteStorage)
return rs, ok
}