davsync

package
v0.1.708 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Overview

Package davsync keeps magpie's setup the same on every computer through a WebDAV folder or an S3-compatible bucket. What goes there is a backup (see internal/backup), sealed with a passphrase before it leaves the computer, so the server only ever holds a file it can't read.

The magpie serving the gateway syncs every few minutes. The setup is taken in five parts: providers (with their pictures and groups), settings, profiles, the agents' models and the library (instructions, MCP servers and skills). A part changed only here is pushed; one changed only on the server is brought in; one changed on both since the last sync keeps the newer, and the one it replaced is saved in the sync folder beside magpie's files and named in a notice. What the server holds is mirrored: a provider removed on one computer goes from the others.

Index

Constants

View Source
const Every = 3 * time.Minute

Every is how often the gateway's magpie syncs.

Variables

View Source
var ErrBusy = errors.New("another magpie is syncing: try again in a moment")

ErrBusy is a wait for another magpie's sync that ran out of time.

View Source
var ErrNoObject = errors.New("not in the bucket")

ErrNoObject is a name with nothing at it.

View Source
var Parts = []string{"providers", "settings", "profiles", "agents", "library"}

Parts, in the order they are told.

Functions

func Check added in v0.1.484

func Check(c Config) error

Check is Configure's look at the address (and an S3 endpoint), for a caller to make before asking for the password and passphrase.

func Configure

func Configure(c Config) error

Configure turns sync on, or changes it. A password or passphrase left empty keeps the one set before — the password only for the same server and user: it is never sent to another, and is asked for again there.

func Dismiss

func Dismiss() error

Dismiss clears the notice.

func Now

func Now(ctx context.Context) error

Now syncs once; nothing when sync is off. Usage is shared at most every usageEvery.

func Off

func Off() error

Off turns sync off. The file on the server stays.

func Run

func Run(ctx context.Context)

Run syncs a little after it starts and every Every after that, until ctx ends — less often while the server is limiting requests. A failure is logged once, not on every try.

func SavedPassword added in v0.1.250

func SavedPassword(c Config) (kept, needed bool)

SavedPassword is Configure's look at the saved password for c, with c's own left empty, for a caller to make before asking for one: whether it is kept, or a new one is needed.

func SyncNow added in v0.1.653

func SyncNow(ctx context.Context) error

SyncNow is Now asked for: usage is shared whatever the time.

Types

type Bucket added in v0.1.577

type Bucket struct {
	// contains filtered or unexported fields
}

Bucket is the S3 sync's bucket for files other than the backup — the gateway's request archive — each at <prefix>/magpie/<name>, beside the backup, written as it is: no passphrase seals them, so they can be read in the bucket too.

func S3Bucket added in v0.1.577

func S3Bucket() (*Bucket, bool)

S3Bucket is the bucket sync keeps the backup in; false when sync is off or to a WebDAV folder.

func (*Bucket) Get added in v0.1.577

func (b *Bucket) Get(ctx context.Context, name string) ([]byte, error)

Get reads what is at name, its first 16 MiB; ErrNoObject when there is nothing.

func (*Bucket) Open added in v0.1.600

func (b *Bucket) Open(ctx context.Context, name string) (io.ReadCloser, int64, error)

Open is what is at name as it is read, however large, and its size (-1 when the server doesn't say); ErrNoObject when there is nothing. The caller closes it.

func (*Bucket) Put added in v0.1.577

func (b *Bucket) Put(ctx context.Context, name string, data []byte) error

Put writes data at name, over what is there.

func (*Bucket) Where added in v0.1.577

func (b *Bucket) Where() string

Where names the bucket, its prefix and its server, as messages do.

type Config

type Config struct {
	URL        string `json:"url"`
	User       string `json:"user,omitempty"`
	Password   string `json:"password,omitempty"`
	Passphrase string `json:"passphrase"`
	// S3 alone: the server (none is AWS), its region (none is us-east-1,
	// auto for R2), and the bucket in the path rather than the host name
	Endpoint  string `json:"endpoint,omitempty"`
	Region    string `json:"region,omitempty"`
	PathStyle bool   `json:"pathStyle,omitempty"`
	Keys      bool   `json:"keys"`   // providers carry their API keys
	Agents    bool   `json:"agents"` // the agents' models go too
	// Library is whether the library goes too; nil, as in a setup made
	// before it could, is yes
	Library *bool `json:"library,omitempty"`
	// Usage is whether this computer shares its usage with the others
	// syncing to the server, and sees theirs (#542)
	Usage bool `json:"usage,omitempty"`
	// Other is the other kind's server, kept when sync moved from it (a
	// WebDAV folder's while an S3 bucket is synced to, or the other way):
	// moving back finds it as it was, its password too. Nothing syncs to it.
	Other *Server `json:"other,omitempty"`
}

Config is the sync's setup, kept in sync.json beside magpie's other files, readable by the user alone, as provider keys are. An s3://bucket/prefix address is an S3-compatible bucket, User its access key ID and Password the secret, kept as a WebDAV password is.

func Load

func Load() (Config, bool)

Load reads the setup; false when sync is off.

func (Config) Kind added in v0.1.484

func (c Config) Kind() string

Kind is the server's kind, as the user reads it: "WebDAV" or "S3".

func (Config) S3 added in v0.1.484

func (c Config) S3() bool

S3 is whether c keeps the file in an S3 bucket rather than a WebDAV folder.

type Notice

type Notice struct {
	At    time.Time `json:"at"`
	Here  []string  `json:"here,omitempty"`  // this computer's parts, replaced by the server's
	There []string  `json:"there,omitempty"` // the server's parts, replaced by this computer's
	Saved string    `json:"saved,omitempty"` // the folder the replaced copies are kept in
}

Notice says what a sync replaced when a part had changed on both sides, or when this computer first joined a folder with a setup in it.

type OtherView added in v0.1.587

type OtherView struct {
	Kind        string `json:"kind"` // "webdav" or "s3"
	URL         string `json:"url"`
	User        string `json:"user,omitempty"`
	PasswordSet bool   `json:"passwordSet,omitempty"`
	Endpoint    string `json:"endpoint,omitempty"`
	Region      string `json:"region,omitempty"`
	PathStyle   bool   `json:"pathStyle,omitempty"`
}

OtherView is the other kind's server as the Settings page shows it.

type Server added in v0.1.587

type Server struct {
	URL       string `json:"url"`
	User      string `json:"user,omitempty"`
	Password  string `json:"password,omitempty"`
	Endpoint  string `json:"endpoint,omitempty"`
	Region    string `json:"region,omitempty"`
	PathStyle bool   `json:"pathStyle,omitempty"`
}

Server is where a Config syncs to, without what it syncs or the passphrase: the other kind's, kept beside the one synced to.

type View

type View struct {
	On            bool   `json:"on"`
	URL           string `json:"url,omitempty"`
	User          string `json:"user,omitempty"`
	PasswordSet   bool   `json:"passwordSet,omitempty"`
	PassphraseSet bool   `json:"passphraseSet,omitempty"`
	Keys          bool   `json:"keys"`
	Agents        bool   `json:"agents"`
	Kind          string `json:"kind,omitempty"` // "webdav" or "s3", when on
	Endpoint      string `json:"endpoint,omitempty"`
	Region        string `json:"region,omitempty"`
	PathStyle     bool   `json:"pathStyle,omitempty"`
	Library       bool   `json:"library"`
	Usage         bool   `json:"usage,omitempty"`
	// UsageError is why usage couldn't be shared the last time it was tried
	UsageError string    `json:"usageError,omitempty"`
	Last       time.Time `json:"last,omitzero"`
	Error      string    `json:"error,omitempty"`
	Notice     *Notice   `json:"notice,omitempty"`
	// Other is the other kind's server, kept for moving back to: not
	// synced to
	Other *OtherView `json:"other,omitempty"`
}

View is sync as the Settings page shows it: never the secrets.

func Status

func Status() View

Status is sync's setup and how the last sync went.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL