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
- Variables
- func Check(c Config) error
- func Configure(c Config) error
- func Dismiss() error
- func Follow(ctx context.Context) error
- func Now(ctx context.Context) error
- func Off() error
- func Restore(ctx context.Context) ([]string, error)
- func Run(ctx context.Context)
- func SavedPassword(c Config) (kept, needed bool)
- func SetAuto(minutes int) error
- func SyncNow(ctx context.Context) error
- func Undo() ([]string, error)
- func Upload(ctx context.Context) error
- type Bucket
- type Config
- type Notice
- type OtherView
- type OwnField
- type Server
- type ServerFile
- type View
Constants ¶
const Every = 3 * time.Minute
Every is how often the gateway's magpie syncs.
const Manual = -1
Manual is AutoEvery's never: sync runs only when asked.
Variables ¶
var AutoChoices = []int{Manual, 3, 15, 30, 60}
AutoChoices are the minutes SetAuto takes, Manual first.
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.
var ErrNoObject = errors.New("not in the bucket")
ErrNoObject is a name with nothing at it.
var ErrOff = errors.New("sync is off")
ErrOff is a Restore, Undo or SetAuto asked for with sync off.
var Parts = []string{"providers", "settings", "profiles", "agents", "library"}
Parts, in the order they are told.
Functions ¶
func Check ¶ added in v0.1.484
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 ¶
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 Follow ¶ added in v0.1.2372
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 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
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 ¶
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
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
SetAuto sets how many minutes apart the gateway's magpie syncs by itself, one of AutoChoices; Manual: never, only when asked (#847).
func Undo ¶ added in v0.1.942
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
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
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
Get reads what is at name, its first 16 MiB; ErrNoObject when there is nothing.
func (*Bucket) Open ¶ added in v0.1.600
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.
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 (Config) GitHub ¶ added in v0.1.1225
GitHub is whether c keeps the file in a GitHub repository.
func (Config) Kept ¶ added in v0.1.1225
Kept is an inactive server, including setups saved before Servers existed.
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.