Help us shape the future of Go! Take the 2026 Go Developer Survey

davsync

package
v0.1.2520 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 45 Imported by: 0

Documentation

Overview

Package davsync keeps magpie's setup the same on every computer through a WebDAV folder, an S3-compatible bucket or a GitHub repository. 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. A computer joining a folder keeps the gateway keys the folder's store has never seen; after the join, a key removed on the folder goes from every computer.

Index

Constants

View Source
const Every = 3 * time.Minute

Every is how often the gateway's magpie syncs.

View Source
const Manual = -1

Manual is AutoEvery's never: sync runs only when asked.

Variables

View Source
var AutoChoices = []int{Manual, 3, 15, 30, 60}

AutoChoices are the minutes SetAuto takes, Manual first.

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 ErrOff = errors.New("sync is off")

ErrOff is a Restore, Undo or SetAuto asked for with sync off.

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, and with a restore's, its undo.

func Follow added in v0.1.2372

func Follow(ctx context.Context) error

Follow gives this computer's own agent fields back to sync, and syncs: the server's values come in, and the others' picks follow again.

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, and so does what this computer last synced with it: turned on again to the same server, it is not a new computer, so what was changed here while it was off goes up rather than the server's older setup coming down over it (#939: every agent back to how it was when sync was turned off). How the last sync went, its notice and a restore's undo go.

func Restore added in v0.1.942

func Restore(ctx context.Context) ([]string, error)

Restore makes this computer's setup the server's, whatever changed here: each part synced that differs is brought in, as a sync brings in a part changed only there. What was here first is sealed into the sync folder, with the API keys, and Undo brings it back. It is the parts brought in.

func Run

func Run(ctx context.Context)

Run syncs a little after it starts and every AutoEvery after that, until ctx ends — less often while the server is limiting requests, and never while sync is set to run only when asked. 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 SetAuto added in v0.1.942

func SetAuto(minutes int) error

SetAuto sets how many minutes apart the gateway's magpie syncs by itself, one of AutoChoices; Manual: never, only when asked (#847).

func SyncNow added in v0.1.653

func SyncNow(ctx context.Context) error

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

func Undo added in v0.1.942

func Undo() ([]string, error)

Undo puts back the setup the last Restore replaced. The next sync takes it to the server, as any change made here.

func Upload added in v0.1.1134

func Upload(ctx context.Context) error

Upload writes this computer's setup over the server's file when that file isn't a backup a sync can read — empty, cut short, another app's — so a sync stopped on it has a way on that the user chooses. A file that opens as a backup, one sealed with another passphrase, a newer magpie's, and a page the server answered with instead of a file are never written over. What the server held is kept in the sync folder first, and nothing is written when it can't be. The write is made over the version read, so a file another computer wrote meanwhile isn't.

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"`
	// GitHub alone: an empty branch uses the repository's default branch.
	Branch string `json:"branch,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 most recently left server, retained for older clients.
	// Servers holds every inactive kind. Nothing syncs to them.
	Other *Server `json:"other,omitempty"`
	// Servers keeps every inactive kind, including Other for older clients.
	Servers map[string]Server `json:"servers,omitempty"`
	// AutoEvery is how many minutes apart the gateway's magpie syncs by
	// itself: 0 is Every's 3, Manual never — then only Sync now syncs
	// (#847). Set by SetAuto alone; Configure keeps it.
	AutoEvery int `json:"autoEvery,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. For github://owner/repo/prefix, Password is the repository's Contents token, independent of GitHubToken in settings (the library's).

func Load

func Load() (Config, bool)

Load reads the setup; false when sync is off.

func (Config) GitHub added in v0.1.1225

func (c Config) GitHub() bool

GitHub is whether c keeps the file in a GitHub repository.

func (Config) Kept added in v0.1.1225

func (c Config) Kept(kind string) (Server, bool)

Kept is an inactive server, including setups saved before Servers existed.

func (Config) Kind added in v0.1.484

func (c Config) Kind() string

Kind is the server's kind, as the user reads it.

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
	// Restored is a Restore's notice: Here are the parts it brought in,
	// what was here before kept in Saved, which Undo brings back
	Restored bool `json:"restored,omitempty"`
}

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", "s3" or "github"
	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"`
	Branch      string `json:"branch,omitempty"`
}

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

type OwnField added in v0.1.2372

type OwnField struct {
	Agent string `json:"agent"` // the agent's name
	Field string `json:"field"` // the field's label: model, effort…
}

OwnField is an agent field kept on this computer, as Settings names 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"`
	Branch    string `json:"branch,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 ServerFile added in v0.1.1134

type ServerFile struct {
	// What is "empty", "cut" (a magpie backup cut short), "page" (a web
	// page), "xml", "format" (another app's JSON file, named by its
	// "format"), "json" or "other"
	What   string `json:"what"`
	Size   int    `json:"size"`
	Title  string `json:"title,omitempty"`  // a page's <title>
	Format string `json:"format,omitempty"` // a JSON file's own "format"
	Type   string `json:"type,omitempty"`   // the kind of file, as its first bytes tell
	Moved  string `json:"moved,omitempty"`  // where a redirect took the read: host and path
	// Replace is whether the file is one Upload may write over: a page or
	// an XML answer is the server's (or a proxy's), not a file at that path
	Replace bool `json:"replace,omitempty"`
}

ServerFile is what the server held, or answered with, where the backup should be, when it isn't one: what the Settings page says of it, and whether Upload may write this computer's setup over it. It never carries the file's contents — only its size, its kind, and a page's title.

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", "s3" or "github", when on
	Endpoint      string `json:"endpoint,omitempty"`
	Region        string `json:"region,omitempty"`
	PathStyle     bool   `json:"pathStyle,omitempty"`
	Branch        string `json:"branch,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"`
	Servers map[string]OtherView `json:"servers,omitempty"`
	// Auto is how many minutes apart it syncs by itself; 0 never: only when
	// asked
	Auto int `json:"auto"`
	// Undo is whether the last Restore can be undone
	Undo bool `json:"undo,omitempty"`
	// File is what the server holds instead of a backup, when Error is
	// that it isn't one; File.Replace offers Upload
	File *ServerFile `json:"serverFile,omitempty"`
	// SignIn is the subscriptions whose settings sync brought with no
	// account here: sync carries no sign-in, so each is to be signed in to
	// on this computer before it is listed
	SignIn []string `json:"signIn,omitempty"`
	// Own is the agent fields picked on this computer after a sync set
	// them, which sync leaves as they are here (own.go)
	Own []OwnField `json:"own,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