library

package
v0.1.1252 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 63 Imported by: 0

Documentation

Overview

Package library keeps what every agent should know, once: the instructions each reads before a conversation, the MCP servers it can call and the skills it can load. magpie writes them into each agent's own files in that agent's own format, and takes back only what it wrote — whatever else is in those files stays as it was.

Index

Constants

View Source
const (
	HowLink = "link"
	HowCopy = "copy"
)

The ways an agent can be given its skills.

View Source
const RTKURL = "https://www.rtk-ai.app"

RTKURL is where rtk is installed from.

Variables

View Source
var GitHubTokenEnv = ghtoken.Env

GitHubTokenEnv names the environment variables a token is taken from when Settings has none, in the order they are looked at.

View Source
var HookEvents = []string{"turn-end", "after-tool", "before-tool", "prompt", "session-start"}

HookEvents are the portable events, in the order the page offers them.

View Source
var HookTools = []string{"shell", "edit"}

HookTools are the kinds of tools a portable tool event can be narrowed to.

Functions

func BackupDir

func BackupDir() string

BackupDir is where a file is copied before magpie first changes it in a change: one folder a change, named by when, a folder an agent in it.

func Changed added in v0.1.182

func Changed() time.Time

Changed is when the library was last changed: library.json, or a file of its own (links not followed).

func CheckChannel added in v0.1.1224

func CheckChannel(v *RTKView)

CheckChannel asks the package manager upgrade runs what rtk it has, and keeps the answer for six hours (see rtkChannelLatest), so that the next read of the tab draws with it without waiting. It is asked in the background, after the tab has gone out: it is a question for the package manager, which takes seconds, and it answers nothing anyone needs unless a release newer than the one installed is out (#1025).

func CheckServers added in v0.1.794

func CheckServers(ctx context.Context, names []string, fresh bool) (map[string]ServerHealth, error)

CheckServers checks the library's servers called names (every one when there are none). One checked already this session, as it is now, isn't started again unless fresh.

func Dir

func Dir() string

Dir is where the library's own files are: the instructions and the skills.

func GitHubToken added in v0.1.662

func GitHubToken() (token, from string)

GitHubToken is the token requests to GitHub's API carry, and where it came from: "settings", the environment variable's name, or "" for none.

func Holds added in v0.1.1209

func Holds(s *Setup) bool

Holds reports whether the library is as s has it: Restore would put back nothing that differs. A server or skill s names that the library no longer has isn't compared, as Restore can't give it either, nor one added since s was taken, which Restore leaves as it is.

func Icon

func Icon(u string) ([]byte, string, error)

Icon is a market icon, fetched once and kept on disk: only an icon the market gave out is fetched, so the page can't have magpie fetch anything else.

func IgnoreNewSkills added in v0.1.1091

func IgnoreNewSkills(ids []string) error

IgnoreNewSkills sets aside the new skills a check found, by their IDs: a later check doesn't offer them again.

func InUse added in v0.1.1225

func InUse() (int, error)

InUse counts what the library gives agents: each server, skill, hook and project folder it keeps, and the shared instructions while an agent gets them. The library built-in plugin stays on while it is more than 0. A library.json that can't be read is an error, never 0.

func KeepLinked added in v0.1.1227

func KeepLinked(interval time.Duration)

KeepLinked runs SyncLinked every interval, for as long as the app runs.

func ProjectMCPFile added in v0.1.629

func ProjectMCPFile(agent string) string

ProjectMCPFile is the file, in a project, an agent reads the project's MCP servers from: "" for one magpie can't give a project's servers to.

func ProjectNoSSE added in v0.1.635

func ProjectNoSSE(agent string) bool

ProjectNoSSE says whether an agent's project file can't take a server over SSE (Codex's, Pi's), whatever its user-wide one can.

func ProjectSkillsDir added in v0.1.243

func ProjectSkillsDir(agent string) string

ProjectSkillsDir is the folder, in a project, an agent reads its skills from: "" for one magpie can't give a project's skills to.

func RTKLatest added in v0.1.328

func RTKLatest() string

RTKLatest is rtk's latest release, from GitHub unless it was read lately; "" when GitHub can't be reached and never could.

func RTKNewer added in v0.1.328

func RTKNewer(a, b string) bool

RTKNewer says whether version a is after b, by their numbers.

func RTKTakes added in v0.1.124

func RTKTakes(q string) (string, error)

RTKTakes is the id of the agent q names when rtk can be given to it.

func RegroupSkills added in v0.1.1213

func RegroupSkills() (int, error)

RegroupSkills traces the library's skills again (the Library page's Group again): each GitHub repository a skill is traced to is fetched, and the skills it has that aren't grouped with it yet are noted as from there, as installing from it again would. It gives how many were grouped; an error only when no repository could be fetched.

func SignInServer added in v0.1.694

func SignInServer(ctx context.Context, name string) (mcpauth.State, error)

SignInServer starts signing magpie in to the library's server called name: the State's URL is the page to open in a browser.

func SignOutServer added in v0.1.694

func SignOutServer(name string) error

SignOutServer forgets magpie's sign-in to the server called name, and gives the agents the server's own address again.

func SkillPath

func SkillPath(name string) string

SkillPath is where a library skill's folder is.

func SkillText

func SkillText(name string) (string, error)

SkillText is a library skill's SKILL.md, for the page to show.

func SkillsAbout

func SkillsAbout(ids []string) map[string]string

SkillsAbout is what each skill says of itself, by id (owner/repo/skill), from its SKILL.md; kept on disk once known.

func Takes added in v0.1.113

func Takes(q, kind string) (string, error)

Takes is the id of the agent q names (its id, an alias, its name) when the library can give it kind — "instructions", "mcp" or "skills" — or why not: an agent it has no place for isn't recorded as getting it and then given nothing.

Types

type AgentInstructions

type AgentInstructions struct {
	Agent    string `json:"agent"`
	Name     string `json:"name"`
	Icon     string `json:"icon"`
	Path     string `json:"path"`
	On       bool   `json:"on"`
	Extra    string `json:"extra"`              // what this agent gets besides
	Own      int    `json:"own"`                // lines of the user's own in the file
	Edited   bool   `json:"edited,omitempty"`   // magpie's part was changed in the file
	Override string `json:"override,omitempty"` // a file the agent reads instead
}

AgentInstructions is one agent's instructions file as the page shows it.

type AgentView

type AgentView struct {
	ID           string `json:"id"`
	Name         string `json:"name"`
	Icon         string `json:"icon"`
	Instructions string `json:"instructions,omitempty"`
	MCP          string `json:"mcp,omitempty"`
	Skills       string `json:"skills,omitempty"`
	// ProjectSkills is the folder in a project it reads skills from
	ProjectSkills string `json:"projectSkills,omitempty"`
	// ProjectMCP is the file, in a project, it reads MCP servers from
	ProjectMCP string `json:"projectMCP,omitempty"`
	// ProjectNoSSE: its project file can't take a server over SSE
	ProjectNoSSE bool     `json:"projectNoSSE,omitempty"`
	SkillsAlso   []string `json:"skillsAlso,omitempty"`
	Note         string   `json:"note,omitempty"`
	NoSSE        bool     `json:"noSSE,omitempty"`
	NoRemote     bool     `json:"noRemote,omitempty"`
	// NoEnvRefs: it reads no ${NAME} from its MCP config, so a server
	// whose headers or environment have one isn't given to it (envref.go)
	NoEnvRefs bool `json:"noEnvRefs,omitempty"`
	// ToolsOff: it can be told to leave out single tools of a server
	// (mcp_tools_off.go); the page names those that can't
	ToolsOff bool   `json:"toolsOff,omitempty"`
	MCPVia   string `json:"mcpVia,omitempty"`
	// How is the way it is given its skills, link or copy, and HowOwn its
	// own over the library's; MustCopy is one that can only take copies
	// (in WSL)
	How      string `json:"how,omitempty"`
	HowOwn   bool   `json:"howOwn,omitempty"`
	MustCopy bool   `json:"mustCopy,omitempty"`
	// Gone: not installed here any more, and listed only for what magpie
	// gave it to be taken out (held); it is given nothing new
	Gone bool `json:"gone,omitempty"`
}

AgentView is an agent as the page lists it, with where it keeps each.

type Applied

type Applied struct {
	Instructions bool     `json:"instructions,omitempty"`
	InstrHash    string   `json:"instrHash,omitempty"` // of the part last written
	MCP          []string `json:"mcp,omitempty"`
	Skills       []string `json:"skills,omitempty"`
	// ToolsOff are, for each server, the tools magpie put in the list its
	// entry has of those the agent leaves out; ToolRules the rules beside
	// the servers magpie added to leave tools out (Claude Code's deny
	// rules, OpenCode's tools keys). Neither holds one the user had.
	ToolsOff  map[string][]string `json:"toolsOff,omitempty"`
	ToolRules []string            `json:"toolRules,omitempty"`
	// Hooks are the entries magpie wrote into the agent's hooks, each
	// exactly as written: one changed since is the user's (hooks.go)
	Hooks []HookEntry `json:"hooks,omitempty"`
}

Applied is what magpie last wrote into one agent.

type Bundle added in v0.1.182

type Bundle struct {
	Instructions Instructions      `json:"instructions"`
	Texts        map[string]string `json:"texts,omitempty"` // set → its text
	Extra        map[string]string `json:"extra,omitempty"` // agent → what it gets besides
	MCP          []*Server         `json:"mcp"`
	Skills       []*CarriedSkill   `json:"skills"`
	Icons        map[string]string `json:"icons,omitempty"`
}

Bundle is the library as a backup carries it to another computer: the instruction sets and the one on, what each agent gets besides, the MCP servers and the skills with their files. What magpie wrote into each agent (Applied) is this computer's own and stays out. It is made the same way every time — no times, everything in order — so two computers with the same library carry the same bundle.

func Collect added in v0.1.182

func Collect() (*Bundle, error)

Collect is the library as it is now; nil when there is none yet.

func (*Bundle) WithSecrets added in v0.1.182

func (b *Bundle) WithSecrets(have *Bundle, secret func(string) bool) *Bundle

WithSecrets is b with the values WithoutSecrets emptied filled from the servers of the same name in have, so a bundle made without keys doesn't take away the ones kept here.

func (*Bundle) WithoutSecrets added in v0.1.182

func (b *Bundle) WithoutSecrets(secret func(string) bool)

WithoutSecrets empties the values of the servers' environment variables and headers that secret says hold one; their names stay, to be filled in.

type Candidate

type Candidate struct {
	Path        string `json:"path"` // in the repository or the folder; "" for its root
	Name        string `json:"name"`
	Description string `json:"description"`
	Have        bool   `json:"have"` // the library has a skill by that name
}

Candidate is a skill found where the user pointed: in a repository, or in a folder.

type CarriedSkill added in v0.1.182

type CarriedSkill struct {
	Name   string            `json:"name"`
	Source *Source           `json:"source,omitempty"`
	Agents []string          `json:"agents"`
	Files  map[string][]byte `json:"files"`          // by path in the folder, with /
	Exec   []string          `json:"exec,omitempty"` // the files that run
	Left   []string          `json:"left,omitempty"` // files too big to carry
}

CarriedSkill is a skill with its folder's files.

type Custom added in v0.1.800

type Custom struct {
	Name      string   `json:"name"`
	Transport string   `json:"transport"`
	URL       string   `json:"url,omitempty"`
	Command   string   `json:"command,omitempty"`
	Args      []string `json:"args,omitempty"`
}

Custom is a server to add by hand at an address nothing the market lists is at: a remote one at an endpoint, or one named for its repository whose command is filled in.

func CustomAt added in v0.1.800

func CustomAt(q string, found []MarketServer) *Custom

CustomAt is the server to add by hand for a search, when it's an address and none of what was found is at it.

type EditedError added in v0.1.1151

type EditedError struct{ Name string }

EditedError is an update refused because the skill was changed here since it was fetched from GitHub.

func (*EditedError) Error added in v0.1.1151

func (e *EditedError) Error() string

type Found

type Found struct {
	Server *Server  `json:"server"`
	Others []string `json:"others,omitempty"`
	Icon   string   `json:"icon,omitempty"`
	// Own: the agent's app puts it there itself, each time it starts
	// (Codex's node_repl and cua_repl): it isn't one to bring in, and
	// taking it out doesn't last.
	Own bool `json:"own,omitempty"`
}

Found is a server an agent has that the library doesn't: the agents that have it as it is, and those that have another by that name.

type FoundSkill

type FoundSkill struct {
	Name        string   `json:"name"`
	Description string   `json:"description"`
	Agents      []string `json:"agents"`           // the agents that have this very folder
	Others      []string `json:"others,omitempty"` // agents with another by that name
	// Copies are the agents with another folder by that name holding the
	// very same files (CC Switch copies a skill into each agent): brought
	// in, they get the library's in its place
	Copies []string `json:"copies,omitempty"`
	Link   string   `json:"link,omitempty"` // where it really is, when it's a link
	// Shared is its entry in the user-wide ~/.agents/skills, when it is
	// there; the agents that have it are those whose entry is a link (or a
	// junction) to the very same folder
	Shared string `json:"shared,omitempty"`
	// Library is its folder in the library's own skills folder, put there
	// by hand (or left by a library.json that lost it): brought in, it is
	// listed where it is (#595)
	Library string `json:"library,omitempty"`
	// contains filtered or unexported fields
}

FoundSkill is a skill an agent has that the library doesn't.

type Hook added in v0.1.1214

type Hook struct {
	Name string `json:"name"`
	// Description says what the hook is for, in any language (#2011):
	// the name is letters, digits, - and _, which says little to someone
	// who reads Chinese. Only the library keeps it; no agent is given it.
	Description string `json:"description,omitempty"`
	// Event is a portable event (HookEvents), or an agent's own,
	// "<agent>:<Event>" as that agent names it
	Event string `json:"event"`
	// Matcher narrows a tool event to some tools: for a portable event
	// "shell" or "edit" (each agent's own tool names for them), for an
	// agent's own event the agent's own matcher; "" is every tool
	Matcher string   `json:"matcher,omitempty"`
	Command string   `json:"command"`
	Timeout int      `json:"timeout,omitempty"` // seconds; 0 is the agent's own
	Agents  []string `json:"agents"`
}

Hook is a command the agents ticked for it run at Event.

type HookAgentView added in v0.1.1214

type HookAgentView struct {
	ID string `json:"id"`
	// File is where its hooks are; No is why magpie can't give it any
	File string `json:"file,omitempty"`
	No   string `json:"no,omitempty"`
	// WSL: No is that it runs in WSL, which magpie gives no hooks yet
	WSL bool `json:"wsl,omitempty"`
	// Off: it has every hook turned off in its settings
	Off bool `json:"off,omitempty"`
	// Events are its own events, for a hook of its alone
	Events []string `json:"events,omitempty"`
}

HookAgentView is an agent the Hooks tab lists.

type HookEntry added in v0.1.1214

type HookEntry struct {
	Name  string          `json:"name"`
	Event string          `json:"event"`
	Entry json.RawMessage `json:"entry"`
}

HookEntry is one entry magpie wrote into an agent's hooks: the hook it is of, the agent's event it is under, and the entry exactly as written.

type HookView added in v0.1.1214

type HookView struct {
	*Hook
	// Native is what each agent it can go to calls its event
	Native map[string]string `json:"native,omitempty"`
	// Problems are the agents it couldn't be given to, and why
	Problems map[string]string `json:"problems,omitempty"`
}

HookView is a library hook, and what each agent makes of it.

type Input

type Input struct {
	Key         string `json:"key"`
	Where       string `json:"where"` // env, header or arg
	Label       string `json:"label"`
	Description string `json:"description,omitempty"`
	Placeholder string `json:"placeholder,omitempty"`
	Secret      bool   `json:"secret,omitempty"`
	Required    bool   `json:"required,omitempty"`
	// contains filtered or unexported fields
}

Input is something a server needs from the user before it can start: a key in its environment, a header it sends, or an argument.

type InstrSet added in v0.1.181

type InstrSet struct {
	ID   string `json:"id"`
	Name string `json:"name"` // "" for the first, which the page calls Default
	// File is a file of the user's own the set's text is kept in instead,
	// read each time and written when the set is saved: one shared file
	// such as ~/.agents/AGENTS.md, kept by hand or by another tool.
	File string `json:"file,omitempty"`
}

InstrSet is one set of shared instructions: its text is in its own file.

type Instructions

type Instructions struct {
	Agents []string `json:"agents"` // the agents the shared text is written to
	// Sets are the named texts to pick the shared one from; with none kept
	// there is the one magpie always had, "default"
	Sets   []InstrSet `json:"sets,omitempty"`
	Active string     `json:"active,omitempty"` // the set agents get; "" is "default"
}

Instructions are one shared text, and for each agent whether it gets it and what it gets besides (kept in files beside library.json). The shared text is one of several sets kept to switch between (#106), the one on.

type InstructionsChange

type InstructionsChange struct {
	Shared *string            `json:"shared,omitempty"`
	Agents []string           `json:"agents,omitempty"`
	Extra  map[string]*string `json:"extra,omitempty"`
	// Rewrite writes magpie's part again into these agents' files, over
	// edits made there.
	Rewrite []string `json:"rewrite,omitempty"`
	// The sets: texts by set, a set to switch the agents to, one to add
	// (id and name), one to rename and one to remove. Shared is the text
	// of the set on, as it is after Activate.
	Texts    map[string]*string `json:"texts,omitempty"`
	Activate string             `json:"activate,omitempty"`
	Create   *InstrSet          `json:"create,omitempty"`
	Rename   *InstrSet          `json:"rename,omitempty"`
	Remove   string             `json:"remove,omitempty"`
}

InstructionsChange is what the page saves: the shared text, which agents get it, and what each gets besides. A nil field is left as it is.

type InstructionsView

type InstructionsView struct {
	Shared string              `json:"shared"` // the set on's text
	Sets   []SetView           `json:"sets"`
	Agents []AgentInstructions `json:"agents"`
}

InstructionsView is the Instructions page.

func ReadInstructions

func ReadInstructions() (*InstructionsView, error)

ReadInstructions is the shared text and each agent's file.

type LeftOut added in v0.1.1231

type LeftOut struct {
	Path string `json:"path"`
	Size int64  `json:"size"`
}

LeftOut is a skill of a repository too big to install on its own (fetchSkillFiles): where it is, and what its files come to.

type Library

type Library struct {
	Instructions Instructions `json:"instructions"`
	MCP          []*Server    `json:"mcp"`
	Skills       []*Skill     `json:"skills"`
	// Projects are folders whose agents get some of the skills there
	Projects []*Project `json:"projects,omitempty"`
	// Hooks are commands the agents ticked for each run at a point of
	// their turn (hooks.go, #1790)
	Hooks []*Hook `json:"hooks,omitempty"`
	// Applied is what magpie wrote into each agent, so that what it takes
	// away is only ever its own.
	Applied map[string]*Applied `json:"applied,omitempty"`
	// Icons are the icons of the servers added from the market, by what
	// each runs, for the page to show them by
	Icons map[string]string `json:"icons,omitempty"`
	// SkillGroups are the groups the user made of some skills on the
	// page, each shown as a group of its own (#791)
	SkillGroups []*SkillGroup `json:"skillGroups,omitempty"`
	// CopySkills gives the agents copies of their skills rather than links
	// to the library's, and SkillHow is an agent's own way over it, link or
	// copy (#896, skill_how.go)
	CopySkills bool              `json:"copySkills,omitempty"`
	SkillHow   map[string]string `json:"skillHow,omitempty"`
	// SeenSkills are, by repository and ref ("owner/repo@ref"), the
	// folders of skills there the page has offered: picked or not at
	// install, or set aside after a check. A check offers only the others
	// as new (skillnew.go).
	SeenSkills map[string][]string `json:"seenSkills,omitempty"`
	// contains filtered or unexported fields
}

Library is library.json: what magpie keeps, and which agents get it.

type Limited added in v0.1.662

type Limited struct {
	Until string `json:"until,omitempty"`
	Token bool   `json:"token,omitempty"`
}

Limited is GitHub's rate limit used up: until when (RFC 3339, "" when GitHub didn't say), and whether the requests carried a GitHub token.

type MarketServer

type MarketServer struct {
	ID          string `json:"id"`
	Name        string `json:"name"` // what the library calls it
	Title       string `json:"title"`
	Description string `json:"description"`
	Publisher   string `json:"publisher,omitempty"`
	Icon        string `json:"icon,omitempty"`
	Homepage    string `json:"homepage,omitempty"`
	Transport   string `json:"transport"`
	// Runs is what starts a local one: npx, uvx or docker
	Runs string `json:"runs,omitempty"`
	// SignIn is a remote one that has the agent sign in, in the browser,
	// the first time it's used
	SignIn   bool `json:"signIn,omitempty"`
	Featured bool `json:"featured,omitempty"`
	// OptIn is one no agent is given unless it is picked for it
	OptIn  bool    `json:"optIn,omitempty"`
	Inputs []Input `json:"inputs"`
	// Have is the library's server that is this one
	Have string `json:"have,omitempty"`
	// Match is one found at the address searched for: its repository, page,
	// endpoint or package is it
	Match bool `json:"match,omitempty"`
	// contains filtered or unexported fields
}

MarketServer is a server the market offers.

func MarketServers

func MarketServers(q string) ([]MarketServer, error)

MarketServers is what the market shows for a search: the featured servers that match it, then the registry's. A search that is an address — a repository, a page, an endpoint, a package — finds the ones at it.

type MarketSkill

type MarketSkill struct {
	ID       string `json:"id"`     // owner/repo/skill
	Source   string `json:"source"` // owner/repo
	SkillID  string `json:"skillId"`
	Name     string `json:"name"`
	Installs int    `json:"installs"`
	Official bool   `json:"official,omitempty"`
	// Featured is magpie's own, not one skills.sh lists
	Featured bool   `json:"featured,omitempty"`
	Icon     string `json:"icon"`
	// Description is known once it has been fetched
	Description string `json:"description,omitempty"`
	Have        string `json:"have,omitempty"`
}

MarketSkill is a skill the market offers, from a GitHub repository.

func MarketSkills

func MarketSkills(q string) ([]MarketSkill, error)

MarketSkills is what the market shows for a search: magpie's own skills that match it, the most installed skills that do, then what skills.sh finds for it.

type NewSkill added in v0.1.1091

type NewSkill struct {
	// ID is the skill's folder on GitHub, what the page adds it from and
	// sets it aside by
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	Repo        string `json:"repo"`
	Ref         string `json:"ref,omitempty"`
	Path        string `json:"path"`
	// From is the repository's folder the check found it in, what Add
	// installs it from
	From string `json:"from"`
	// Agents are those that have the repository's other skills: the ones
	// an Add gives it to
	Agents []string `json:"agents"`
}

NewSkill is a skill a check for updates found in a GitHub repository the library has skills from, beside them, that the library doesn't have and that the page hasn't offered before: one the repository added since its skills were installed. The page offers to add it, or to set it aside.

type OAuthApp added in v0.1.1217

type OAuthApp struct {
	ClientID     string `json:"clientId"`
	ClientSecret string `json:"clientSecret,omitempty"`
	// CallbackPort is the port of the callback URL the app was made with;
	// 0 for one made with http://localhost/callback, which takes any
	CallbackPort int `json:"callbackPort,omitempty"`
}

OAuthApp is an OAuth app made with a server's vendor, by the names Claude Code gives one (--client-id, --client-secret, --callback-port; "oauth": {"clientId", "callbackPort"}).

type Probe

type Probe struct {
	Source     string      `json:"source"`
	Kind       string      `json:"kind"`
	Candidates []Candidate `json:"candidates"`
	// Left is the skills there too big to install on their own, left out
	// of the candidates (#2062)
	Left []LeftOut `json:"left,omitempty"`
	// contains filtered or unexported fields
}

Probe is what was found at a source.

func ProbeSkills

func ProbeSkills(input string) (*Probe, error)

ProbeSkills looks for skills at what the user typed: a GitHub repository (or a folder in one), or a folder on this machine.

type Problem

type Problem struct {
	Agent string `json:"agent"`
	What  string `json:"what"` // instructions, mcp:<name>, skill:<name>
	Error string `json:"error"`
	// Own is a skill the agent has a folder of its own for, not the
	// library's: the page offers to use the library's or keep the agent's
	Own bool `json:"own,omitempty"`
}

Problem is one thing that couldn't be given to an agent.

type Project added in v0.1.243

type Project struct {
	Dir string `json:"dir"`
	// Copy puts copies of the skills there, not links to the library's
	// (for Windows, or a folder synced or shared where a link won't do);
	// a copy is made again when the library's skill changes
	Copy bool `json:"copy,omitempty"`
	// Skills are the library's skills the project has, and for which agents
	Skills map[string][]string `json:"skills,omitempty"`
	// Placed are the entries magpie put in the folder (.claude/skills/pdf),
	// the only ones it ever takes away
	Placed []string `json:"placed,omitempty"`
	// Made are the folders magpie made to place them in, taken away again
	// once they're empty; Gitignore is whether it made the .gitignore
	Made      []string `json:"made,omitempty"`
	Gitignore bool     `json:"gitignore,omitempty"`
	// Servers are the library's MCP servers the project has, and for which
	// agents (project_mcp.go)
	Servers map[string][]string `json:"servers,omitempty"`
	// Wrote are, by the project's file (.mcp.json), the servers magpie
	// wrote in it, the only entries it ever takes out
	Wrote map[string][]string `json:"wrote,omitempty"`
	// MadeFiles are the files magpie made to write servers in, listed in
	// the .gitignore and taken away again once nothing's left in them
	MadeFiles []string `json:"madeFiles,omitempty"`
}

Project is a folder of the user's whose agents get some of the library's skills there, as the project's own: each is placed in the folder the agent reads a project's skills from, and kept out of git.

type ProjectView added in v0.1.243

type ProjectView struct {
	Dir     string              `json:"dir"`
	Name    string              `json:"name"`
	Copy    bool                `json:"copy"`
	Skills  map[string][]string `json:"skills"`
	Placed  []string            `json:"placed"`
	Servers map[string][]string `json:"servers"`
	// Wrote are, by the project's file, the servers magpie wrote there
	Wrote   map[string][]string `json:"wrote"`
	Missing bool                `json:"missing,omitempty"` // the folder is gone
	// Problems are, by skill ("" for the project's own), what couldn't be done
	Problems map[string]string `json:"problems,omitempty"`
}

ProjectView is a project as the page shows it.

type RTKAgent added in v0.1.124

type RTKAgent struct {
	ID   string `json:"id"`
	Name string `json:"name"`
	Icon string `json:"icon"`
	On   bool   `json:"on"`
	// Blocked says why rtk can't be switched on for it here (OpenCode 2);
	// one that has it can still be switched off
	Blocked string `json:"blocked,omitempty"`
	// NoHook: rtk has no hook for it at all (rtkNoHook), and Blocked says why
	NoHook bool `json:"noHook,omitempty"`
}

RTKAgent is one agent rtk can be given to, and whether it has it.

type RTKDay added in v0.1.328

type RTKDay struct {
	Date     string  `json:"date"` // 2006-01-02, local
	Commands int     `json:"commands"`
	Input    int64   `json:"input"`
	Saved    int64   `json:"saved"`
	Pct      float64 `json:"pct"`
}

RTKDay is what rtk saved on one day it ran commands.

type RTKGain added in v0.1.124

type RTKGain struct {
	Commands int     `json:"commands"`
	Input    int64   `json:"input"`
	Saved    int64   `json:"saved"`
	Pct      float64 `json:"pct"`
}

RTKGain is what rtk says it saved, over every command it has recorded.

type RTKView added in v0.1.124

type RTKView struct {
	Path    string   `json:"path,omitempty"` // "" when rtk isn't installed
	Version string   `json:"version,omitempty"`
	Gain    *RTKGain `json:"gain,omitempty"`
	// GainErr is why what rtk saved isn't known: rtk gain failed or
	// printed nothing readable
	GainErr string `json:"gainErr,omitempty"`
	// CodexSandbox is the Windows sandbox Codex runs its commands in,
	// when it has rtk: what rtk saves there isn't counted in Gain
	CodexSandbox string `json:"codexSandbox,omitempty"`
	// Days are what it saved each day it ran commands, oldest first
	Days []RTKDay `json:"days,omitempty"`
	// Latest is rtk's latest release, "" when it isn't known (see
	// CheckLatest); Upgrade the command Upgrade RTK runs, "" when magpie
	// doesn't know how this rtk was installed
	Latest  string `json:"latest,omitempty"`
	Upgrade string `json:"upgrade,omitempty"`
	// Admin is the folder rtk is in when only an administrator can change
	// it (winget's for every user, under Program Files): Upgrade asks
	// Windows for one first
	Admin string `json:"admin,omitempty"`
	// Waiting is the package manager this rtk was installed with (winget,
	// Homebrew) when Latest is out but it has nothing newer than this rtk
	// yet, WaitingHas what it has: an upgrade through it would change
	// nothing, so the page offers none (#1025)
	Waiting    string `json:"waiting,omitempty"`
	WaitingHas string `json:"waitingHas,omitempty"`
	// Note is what an upgrade left to say: Homebrew's rtk behind rtk's
	// own release
	Note string `json:"note,omitempty"`
	// OffPath: rtk isn't on the PATH an agent started now gets, so its
	// hooks, which run rtk by name, do nothing (Pi's says "rtk binary not
	// found in PATH"). PathDir is where Put RTK on PATH makes it found — a
	// link to it made in that folder (PathLink), or (Windows) that folder,
	// rtk's own, added to the user's PATH; "" when magpie has nowhere
	PathDir  string     `json:"pathDir,omitempty"`
	PathLink bool       `json:"pathLink,omitempty"`
	OffPath  bool       `json:"offPath,omitempty"`
	Agents   []RTKAgent `json:"agents"`
	URL      string     `json:"url"`
	// Install is the command Install RTK runs, shown before it is clicked
	Install string `json:"install,omitempty"`
	// Restart are the agents a change reached, to be restarted to see it
	Restart []string `json:"restart,omitempty"`
	Backup  string   `json:"backup,omitempty"`
}

RTKView is the RTK part of the Library page.

func InstallRTK added in v0.1.131

func InstallRTK() (*RTKView, error)

InstallRTK installs rtk, when the user asks for it.

func PathRTK added in v0.1.681

func PathRTK() (*RTKView, error)

PathRTK puts the rtk magpie found on the PATH agents get, when the user asks for it (see rtkOnPath).

func ReadRTK added in v0.1.124

func ReadRTK() *RTKView

ReadRTK says whether rtk is installed, what it saved, and which agents have it.

func SetRTK added in v0.1.124

func SetRTK(id string, on bool) (*RTKView, error)

SetRTK gives rtk to an agent with rtk's own installer, or takes it away by taking out what that put in — which needs no rtk, so an agent left with the hook of an rtk since removed can be put right.

func UpgradeRTK added in v0.1.328

func UpgradeRTK() (*RTKView, error)

UpgradeRTK brings rtk up to its latest release the way it was installed.

func (*RTKView) CheckLatest added in v0.1.328

func (v *RTKView) CheckLatest()

CheckLatest fills in rtk's latest release (see RTKLatest), and, when it is newer than this rtk, what the package manager that installed it has — but only what that said before, and within its own age (Waiting): asking a package manager is slow (`winget show` refreshes its sources — seconds, on a slow or unreachable network far more), and a read that waits for it holds up the whole tab for a grey tag beside the version. CheckChannel asks in the background instead, and the next read draws with its answer.

type Result

type Result struct {
	Changed  []string  `json:"changed"`  // agents whose files were written
	Problems []Problem `json:"problems"` // what couldn't be written, and why
	Backup   string    `json:"backup,omitempty"`
	// Missing are the servers and skills (mcp:<name>, skill:<name>) a
	// profile named that the library no longer has
	Missing []string `json:"missing,omitempty"`
	// Updated and Unupdated are, for an update of every skill, the ones
	// fetched again and the ones that couldn't be (What is skill:<name>)
	Updated   []string  `json:"updated,omitempty"`
	Unupdated []Problem `json:"unupdated,omitempty"`
	// Unimported are, for skills brought in together, the ones that
	// couldn't be (What is skill:<name>)
	Unimported []Problem `json:"unimported,omitempty"`
	// Unremoved are, for skills or servers taken out together, the ones
	// that couldn't be (What is skill:<name> or mcp:<name>)
	Unremoved []Problem `json:"unremoved,omitempty"`
	// Installed, Had and Skipped are, for skills installed together, the
	// ones added, the ones the library had already from the same source,
	// and the ones left out with why: another skill by that name, the
	// user's, is never written over (What is skill:<name>)
	Installed []string  `json:"installed,omitempty"`
	Had       []string  `json:"had,omitempty"`
	Skipped   []Problem `json:"skipped,omitempty"`
}

Result is what a change did to the agents.

func AddNewSkills added in v0.1.1091

func AddNewSkills(ids []string) (*Result, error)

AddNewSkills adds the new skills a check found, by their IDs, each to the agents that have its repository's other skills. The repository is fetched once for those of it.

func AddProject added in v0.1.243

func AddProject(dir string) (*Result, error)

AddProject adds a folder whose agents can be given library skills.

func EveryServerAgents added in v0.1.611

func EveryServerAgents(agents []string, on bool) (*Result, error)

EveryServerAgents gives every server in the library to the agents named, or takes every one from them, in one write rather than one for each server (#475). An agent not named keeps what it has, as with a server's All chip; on gives an agent only the servers it can reach (no SSE for Codex, no remote one for Claude Desktop), as its chips can't be lit for the others.

func EverySkillAgents added in v0.1.596

func EverySkillAgents(agents []string, on bool) (*Result, error)

EverySkillAgents gives every skill in the library to the agents named, or takes every one from them, in one write rather than one for each skill (#443). An agent not named keeps what it has, as with a skill's All chip.

func GroupSkills added in v0.1.896

func GroupSkills(old, name string, names []string) (*Result, error)

GroupSkills puts the skills named into the group called name, made when there is none, and takes them out of any other: a skill is in one group at most. old, when given, is a group renamed to name, and its skills are then those named when any are. No names and no old is nothing; a rename to a group there is already is refused.

func HookAgents added in v0.1.1214

func HookAgents(name string, agents []string) (*Result, error)

HookAgents sets which agents get a hook.

func ImportInstructions

func ImportInstructions(id string) (*Result, error)

ImportInstructions moves the user's own instructions out of an agent's file into the library: they are added to the shared text, taken out of the file (which is kept aside first), and the agent gets the shared text from then on — so what it reads is what it read before.

func ImportServer

func ImportServer(name string) (*Result, error)

ImportServer takes a server the agents have into the library: the agents that have it as it is get the library's from then on, the same entry.

func ImportSkill

func ImportSkill(name string) (*Result, error)

ImportSkill takes a skill the agents have of their own into the library: a folder is moved in, a link to a folder elsewhere is linked to from the library, and the agents that had it get the library's from then on.

func ImportSkills added in v0.1.491

func ImportSkills(names []string) (*Result, error)

ImportSkills is ImportSkill for several skills at once, written to the agents once. One that can't be brought in is said in Unimported, and the others are brought in all the same.

func InstallMarketSkill

func InstallMarketSkill(source, id string, agents []string) (*Result, error)

InstallMarketSkill adds a skill from the market, found in its repository, and gives it to the agents named — to every agent that can have skills when none are.

func InstallServer

func InstallServer(id string, values map[string]string, agents []string) (*Result, error)

InstallServer adds a market server to the library, filled in with values (by input key), and gives it to the agents named — to every agent that can have it when none are.

func InstallSkills

func InstallSkills(input string, paths, agents []string) (*Result, error)

InstallSkills adds the skills at those paths of the source to the library and gives them to the agents named. One the library has already, or one whose name is taken, is left as it is and said in the result; the others are installed all the same.

func KeepAgentSkill added in v0.1.498

func KeepAgentSkill(name, agentID string) (*Result, error)

KeepAgentSkill settles it the other way: the agent keeps its own, and the library no longer gives it that skill (nor any agent that reads the very same folder).

func KeepAgentSkills added in v0.1.1224

func KeepAgentSkills(names []string, agentID string) (*Result, error)

KeepAgentSkills is KeepAgentSkill for several of one agent's skills at once (#1896).

func ProjectCopy added in v0.1.243

func ProjectCopy(dir string, copy bool) (*Result, error)

ProjectCopy sets whether a project gets copies of its skills rather than links; those there are made again the other way.

func ProjectServer added in v0.1.629

func ProjectServer(dir, name string, agents []string) (*Result, error)

ProjectServer sets which agents get a library server in a project; none takes it out of the project.

func ProjectSkill added in v0.1.243

func ProjectSkill(dir, name string, agents []string) (*Result, error)

ProjectSkill sets which agents get a library skill in a project; none takes it out of the project.

func Put added in v0.1.182

func Put(b *Bundle) (*Result, error)

Put makes the library what b says — its instructions, servers and skills in place of the ones here — and writes it into the agents, which keep whatever of theirs isn't magpie's. The skills are written aside first, and only once all of them are there does any go in; a skill replaced or taken out is kept with the backups, and so is an instructions file that changes. A skill that comes linked to a folder this computer has too is linked to it; else it comes as its files. A skill whose files are as they are here is left alone.

func RemoveFoundServer added in v0.1.1191

func RemoveFoundServer(name string) (*Result, error)

RemoveFoundServer takes a server the agents have of their own out of every agent that has it as it is (#1618), without bringing it into the library first: its entry goes from each file the agent reads servers from (dsh's other profiles, Claude Desktop's Claude-3p file, Pi's other mcp.json too), each file copied to the backups before it is written, and the rest of each file — the user's other servers, their keys, comments — left as it is. Another server by that name (Others) is another server and stays. One the agent's app puts back each time it starts (Own) is left: taking it out wouldn't last. A file that can't be read now is never written: what it holds is unknown, not nothing.

func RemoveFoundSkill added in v0.1.1119

func RemoveFoundSkill(name string) (*Result, error)

RemoveFoundSkill takes a skill the agents have of their own out of every agent that has it (#1303), without bringing it into the library first: each agent's folder, and its copies of the very same files, go to the backups; its links are taken away. Its entry in the shared ~/.agents/skills, or a folder of it left in the library's own, goes to the backups too, as agents read those. A folder elsewhere that the agents only linked to is left where it is, and so is another skill by that name (Others): that is another skill.

func RemoveFoundSkills added in v0.1.1222

func RemoveFoundSkills(names []string) (*Result, error)

RemoveFoundSkills takes the skills named, of those the agents have of their own, out of every agent in one change, each exactly as RemoveFoundSkill takes one (wongxy on Discord: 批量删除). One that can't be taken out stays, and is said in Unremoved; the others go all the same. Only when none went does the change fail, with the first reason.

func RemoveHooks added in v0.1.1214

func RemoveHooks(names []string) (*Result, error)

RemoveHooks takes the hooks named out of the library, and what magpie wrote of them out of every agent. A name the library hasn't is said in Unremoved, the others gone all the same.

func RemoveProject added in v0.1.243

func RemoveProject(dir string, keep bool) (*Result, error)

RemoveProject takes every skill magpie placed out of a project, and the project off the list; what's left, it couldn't take away and says why. keep takes the project off the list alone (#514: a project given a few skills or servers once, to keep them): everything magpie put in the folder — skills, servers in the agents' files, its lines in the .gitignore — stays as it is, the user's from then on.

func RemoveServer

func RemoveServer(name string) (*Result, error)

RemoveServer takes a server out of the library and out of every agent magpie gave it to.

func RemoveServers added in v0.1.1090

func RemoveServers(names []string) (*Result, error)

RemoveServers takes the servers named out of the library and every agent in one write (#1027), each as RemoveServer does: only the entries magpie wrote (Applied) leave the agents' files, a server of the agent's own by another name stays, and each one's sign-in goes with it. One that can't be taken out stays, and is said in Unremoved.

func RemoveSkill

func RemoveSkill(name string) (*Result, error)

RemoveSkill takes a skill out of the library and every agent; its folder is kept aside with the backups, never just deleted.

func RemoveSkills added in v0.1.599

func RemoveSkills(names []string) (*Result, error)

RemoveSkills takes the skills named out of the library and every agent in one write (#449), each as RemoveSkill does: the folders kept aside together, in one backup, and a folder of the user's only unlinked. One that can't be taken out stays, and is said in Unremoved.

func Restore added in v0.1.58

func Restore(s *Setup) (*Result, error)

Restore gives the servers and skills to the agents s names and puts the instructions back as they were, then writes the library into the agents. A server or skill s names that the library no longer has is left out and listed in Result.Missing; one added to the library since s was taken is left with the agents it has, as s knows nothing of it. The library's own instructions files that change are kept aside with the agents' files, in the same backup.

func SaveHook added in v0.1.1214

func SaveHook(old string, h Hook) (*Result, error)

SaveHook adds a hook, or replaces the one called old (renaming it). An agent it can't be given is left out of it, said in the result.

func SaveInstructions

func SaveInstructions(c InstructionsChange) (*Result, error)

SaveInstructions saves the change and writes it into the agents.

func SaveServer

func SaveServer(old string, s Server) (*Result, error)

SaveServer adds a server, or replaces the one called old (renaming it).

func ServerAgents

func ServerAgents(name string, agents []string) (*Result, error)

ServerAgents sets which agents get a server.

func ServerTools added in v0.1.1183

func ServerTools(name string, off []string) (*Result, error)

ServerTools sets the tools of a server its agents leave out (nf1qaz2w on Discord); none turns every tool on again.

func SetSkillHow added in v0.1.1015

func SetSkillHow(agent, how string) (*Result, error)

SetSkillHow sets the way the library gives its skills to every agent (agent "") or to one ("" for how the library does it); the agents' links and copies are made again the new way.

func SkillAgents

func SkillAgents(name string, agents []string) (*Result, error)

SkillAgents sets which agents get a skill.

func SomeHooksAgents added in v0.1.1214

func SomeHooksAgents(names, agents []string, on bool) (*Result, error)

SomeHooksAgents gives the hooks named to the agents, or takes them from them, each to the agents that can take it: an agent's own event stays that agent's alone.

func SomeServersAgents added in v0.1.1090

func SomeServersAgents(names, agents []string, on bool) (*Result, error)

SomeServersAgents does as EveryServerAgents for the servers named alone: the ones picked on the page (#1027).

func SomeSkillsAgents added in v0.1.856

func SomeSkillsAgents(names, agents []string, on bool) (*Result, error)

SomeSkillsAgents does as EverySkillAgents for the skills named alone: a repository's skills, from its group's chips (#787).

func Sync

func Sync() (*Result, error)

Sync writes the library into the agents again: after an agent is installed, or a profile brings another library in. magpie does one at every start, and the Library page waits on the lock for each read and change: held for the whole sync, through every agent's skills, the first operations after opening magpie took seconds (#1624, Hipple). It lets go after each agent's part, for whatever waits to go first.

func SyncLinked added in v0.1.1227

func SyncLinked() (*Result, error)

SyncLinked writes the instructions into the agents again when the set they get is kept in a file of the user's that changed since it was last looked at — edited by hand, or by another tool that keeps it — and not otherwise: nil, nil. The first look at a file only notes it.

func UngroupSkills added in v0.1.896

func UngroupSkills(name string, names []string) (*Result, error)

UngroupSkills takes the group called name away; its skills go back to the groups by source. With names, only those leave it.

func UpdateSkill

func UpdateSkill(name string, replace bool) (*Result, error)

UpdateSkill fetches a skill from GitHub again, in place: the agents' links go on pointing at it. One changed here since it was fetched is an *EditedError unless replace is set, and then the changed version is kept with the backups (#1449).

func UpdateSkills added in v0.1.151

func UpdateSkills() (*Result, error)

UpdateSkills fetches again every skill that came from GitHub, each repository once, and writes the agents once. A skill that couldn't be fetched is said in Unupdated, as is one changed here since it was fetched, which is left as it is; the others are updated all the same.

func UpdateSomeSkills added in v0.1.240

func UpdateSomeSkills(names []string) (*Result, error)

UpdateSomeSkills is UpdateSkills for the skills named only: those a check found GitHub to have changed.

func UseLibrarySkill added in v0.1.498

func UseLibrarySkill(name, agentID string) (*Result, error)

UseLibrarySkill settles an agent's own skill that stands in the way of the library's by that name for the library's: the agent's folder is kept aside with the backups, and the library's linked in its place.

func UseLibrarySkills added in v0.1.1224

func UseLibrarySkills(names []string, agentID string) (*Result, error)

UseLibrarySkills is UseLibrarySkill for several of one agent's skills at once, as the Library's warning settles them together (#1896). Claude Desktop's own skills (Anthropic's built in, or made there) aren't put aside: they are listed in its manifest, not only a folder, so only KeepAgentSkills settles those.

type SearchError added in v0.1.1188

type SearchError struct {
	Source string // skills.sh, the MCP Registry
	Err    error
}

SearchError is a source the market searches that didn't answer; what the market has of its own is still listed beside it (#1589).

func (*SearchError) Error added in v0.1.1188

func (e *SearchError) Error() string

func (*SearchError) Unwrap added in v0.1.1188

func (e *SearchError) Unwrap() error

type Server

type Server struct {
	Name string `json:"name"`
	// Transport is stdio for a command, http (streamable) or sse for a URL.
	Transport string            `json:"transport"`
	Command   string            `json:"command,omitempty"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	URL       string            `json:"url,omitempty"`
	Headers   map[string]string `json:"headers,omitempty"`
	Agents    []string          `json:"agents"`
	// DisabledTools are the server's tools its agents leave out, by the
	// names the server gives them, written in each agent's own way where
	// it has one (mcp_tools_off.go)
	DisabledTools []string `json:"disabledTools,omitempty"`
	// OAuth is an OAuth app of the user's own that magpie signs in to the
	// server as, for one whose sign-in doesn't let magpie register itself
	// (GitHub's, 新v学员 on Discord). It is magpie's alone: the agents are
	// given the server as before.
	OAuth *OAuthApp `json:"oauth,omitempty"`
}

Server is one MCP server: a command magpie's agents start, or a URL they reach.

func ServerOf added in v0.1.136

func ServerOf(name string, cmd []string) (Server, error)

ServerOf is a server as it is typed: a URL, or a command and its arguments.

func (*Server) HasEnvRefs added in v0.1.1112

func (s *Server) HasEnvRefs() bool

HasEnvRefs says whether the server's headers or environment reference a variable.

func (*Server) Remote

func (s *Server) Remote() bool

Remote reports whether the server is reached by URL.

type ServerHealth added in v0.1.794

type ServerHealth struct {
	// State is ok (it answered, with Tools tools), auth (it asks for a
	// sign-in or a key) or error (Why says what went wrong)
	State string `json:"state"`
	Tools int    `json:"tools"`
	// ToolList is each tool's name and what it says it does, as tools/list
	// gave them, for the page to list (nf1qaz2w on Discord); at most
	// maxToolList, while Tools counts every one
	ToolList []Tool `json:"toolList,omitempty"`
	// Why is the kind of error, for the page to put in its own words:
	// notfound, start, exited, timeout, http, refused, unreachable,
	// protocol, novar (a ${NAME} magpie's environment hasn't: Detail names
	// them)
	Why    string `json:"why,omitempty"`
	Code   int    `json:"code,omitempty"`   // the exit code, or the HTTP status
	Detail string `json:"detail,omitempty"` // the last line it wrote to stderr, or the error's text
	// OAuth is a refusal that named a sign-in (WWW-Authenticate), which
	// magpie can do itself for a streamable HTTP server
	OAuth bool `json:"oauth,omitempty"`
	// SignIn is magpie's sign-in to a streamable HTTP server as the check
	// left it: one whose renewed token the server refused has run out
	// since, and the page's tag says so (新v学员 on Discord)
	SignIn *mcpauth.Status `json:"signIn,omitempty"`
	// Step is what a server that timed out was asked and didn't answer
	// (initialize, notifications/initialized, tools/list, or connect: an
	// SSE server's stream), and Waited how long it was waited for, in ms
	Step   string `json:"step,omitempty"`
	Waited int64  `json:"waited,omitempty"`
	At     int64  `json:"at"` // when it was checked, unix ms
}

ServerHealth is what a check of one server found.

func CheckServer added in v0.1.794

func CheckServer(ctx context.Context, s *Server) ServerHealth

CheckServer connects to one server and asks it for its tools.

type ServerView

type ServerView struct {
	*Server
	Icon string `json:"icon,omitempty"`
	// Problems are the agents it couldn't be given to, and why
	Problems map[string]string `json:"problems,omitempty"`
	// SignIn is magpie's sign-in to a streamable HTTP server, which the
	// agents then use (#615)
	SignIn *mcpauth.Status `json:"signIn,omitempty"`
}

ServerView is a library server, and what each agent it's on made of it.

type ServersConfig added in v0.1.1160

type ServersConfig struct {
	File    string   `json:"file"`
	Text    string   `json:"text"`
	Skipped []string `json:"skipped,omitempty"`
}

ServersConfig is what an agent's project file would hold with the library's servers called names in it, as magpie writes them into a project it has (syncProjectMCP): for the user to paste into a project magpie doesn't keep (#1478, xiaozhu1337: 不建项目、一次性添加项目级 MCP). File is the file in the project, Text the file whole, and Skipped the servers the agent can't reach that way (SSE for Codex or Pi).

func ConfigOfServers added in v0.1.1160

func ConfigOfServers(agent string, names []string) (*ServersConfig, error)

ConfigOfServers writes the servers into a fresh file in agent's project format, in a folder of its own, and reads it back: the same encoder, the same references to variables, a server magpie is signed in to through the gateway as a project of magpie's is given it.

type SetView added in v0.1.181

type SetView struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	Text   string `json:"text"`
	Active bool   `json:"active,omitempty"`
	File   string `json:"file,omitempty"` // the user's own file it is kept in
}

SetView is one set of shared instructions as the page shows it.

type Setup added in v0.1.58

type Setup struct {
	Instructions SetupInstructions   `json:"instructions"`
	MCP          map[string][]string `json:"mcp"`    // server → the agents that get it
	Skills       map[string][]string `json:"skills"` // skill → the agents that get it
}

Setup is which agents get what from the library, and the instructions, as a profile keeps them to switch back to. The servers and the skills themselves stay in the library: a setup only names them.

func Snapshot added in v0.1.58

func Snapshot() (*Setup, error)

Snapshot is the library's setup as it is now.

func (*Setup) Empty added in v0.1.58

func (s *Setup) Empty() bool

Empty reports whether the library had nothing in it when s was taken.

func (*Setup) GivesInstructions added in v0.1.58

func (s *Setup) GivesInstructions() bool

GivesInstructions reports whether any agent gets instructions from it.

func (*Setup) On added in v0.1.58

func (s *Setup) On() (servers, skills int)

On counts the servers and the skills a setup gives to at least one agent.

func (*Setup) Summary added in v0.1.58

func (s *Setup) Summary() string

Summary is what a setup gives out, in a few words: the servers and skills given to at least one agent, and whether any agent gets the instructions.

type SetupInstructions added in v0.1.58

type SetupInstructions struct {
	Set    string            `json:"set,omitempty"` // the set it is the text of
	Shared string            `json:"shared,omitempty"`
	Agents []string          `json:"agents"`
	Extra  map[string]string `json:"extra,omitempty"`
}

SetupInstructions is the shared text, the agents it is written to, and what each agent gets besides.

type Skill

type Skill struct {
	Name   string   `json:"name"`
	Source *Source  `json:"source,omitempty"`
	Agents []string `json:"agents"`
	// Hash is of the skill's files as last fetched from GitHub, and Commit
	// the last commit to have touched its folder there, once a check has
	// found the two to agree: together they tell whether GitHub has
	// changed the skill since.
	Hash   string `json:"hash,omitempty"`
	Commit string `json:"commit,omitempty"`
	// From is the repository one not installed from GitHub was found to
	// come from (skill_from.go), only to group it with the rest of it
	From string `json:"from,omitempty"`
}

Skill is a folder with a SKILL.md, kept in the library and linked into the agents that get it.

type SkillCheck added in v0.1.240

type SkillCheck struct {
	Name string `json:"name"`
	// Status is current when GitHub has the skill as the library does,
	// update when it has changed it since, and unknown when it couldn't be
	// told (Error says why)
	Status  string `json:"status"`
	Commit  string `json:"commit,omitempty"`  // the last commit to touch the skill's folder
	Date    string `json:"date,omitempty"`    // when it was made
	Message string `json:"message,omitempty"` // its first line
	// URL shows what changed: the commits since the one installed, or the
	// folder's history when which that was isn't known
	URL   string `json:"url,omitempty"`
	Error string `json:"error,omitempty"`
	// Limited is set when it couldn't be told because GitHub's rate limit
	// was used up, for the page to say so in its own words
	Limited *Limited `json:"limited,omitempty"`
}

SkillCheck is what a check for updates found of one skill from GitHub.

func CheckSkills added in v0.1.240

func CheckSkills() ([]SkillCheck, error)

CheckSkills asks GitHub, for every skill installed from there, for the last commit to touch its folder, and tells whether it's newer than what the library has: by the commit a skill is known to be at, or, while that isn't known yet, by fetching the repository once and comparing the folder's files with the skill's. A skill GitHub couldn't be asked about is unknown, and the others are checked all the same; once GitHub limits requests, the rest aren't asked about.

type SkillGroup added in v0.1.896

type SkillGroup struct {
	Name   string   `json:"name"`
	Skills []string `json:"skills"`
}

SkillGroup is a group the user made of some skills (#791, mintonight: 能不能在选择后自己创建分组呢): the page shows it as a group of its own, above the ones by source, with its skills taken out of theirs. It is only how the page shows them; the agents get each skill as before.

type SkillView

type SkillView struct {
	Name        string            `json:"name"`
	Description string            `json:"description"`
	Source      string            `json:"source,omitempty"`
	Kind        string            `json:"kind"`             // github, folder, or "" for one kept in the library
	Origin      string            `json:"origin,omitempty"` // on GitHub, as CC Switch installed it: it can be updated from there
	Repo        string            `json:"repo,omitempty"`   // the repository it came from, however it came in, for the page to group by
	Icon        string            `json:"icon,omitempty"`
	Agents      []string          `json:"agents"`
	Missing     bool              `json:"missing,omitempty"` // its folder is gone
	Problems    map[string]string `json:"problems,omitempty"`
	Check       *SkillCheck       `json:"check,omitempty"` // what the last check for updates found
	// Always are the agents that have it whatever the library gives them:
	// it is kept in ~/.agents/skills, which they read themselves (#595)
	Always []string `json:"always,omitempty"`
	// Behind are the agents given it as a copy whose copy differs from it,
	// till the next sync makes it again
	Behind []string `json:"behind,omitempty"`
	// Edited is set for one from GitHub changed here since it was fetched,
	// in the library or in an agent's copy: an update replaces that, so
	// the page asks first (#1449)
	Edited bool `json:"edited,omitempty"`
}

SkillView is a library skill as the page shows it.

type Source

type Source struct {
	Kind string `json:"kind"` // github | folder
	Repo string `json:"repo,omitempty"`
	Ref  string `json:"ref,omitempty"`
	Path string `json:"path,omitempty"` // in the repository
	Dir  string `json:"dir,omitempty"`  // the folder, for kind folder
}

Source is where a skill came from: a GitHub repository it can be updated from, or a folder on this machine the library links to, so that editing the folder is editing the skill.

func (*Source) String

func (s *Source) String() string

type Target

type Target struct {
	Agent *agent.Agent
	// Instructions is the file the agent reads before every conversation;
	// Override, when it exists, is read instead of it (Codex's
	// AGENTS.override.md), which the page warns of.
	Instructions, Override string
	MCP                    *mcpFile
	Skills                 string // the folder the agent finds skills in
	// SkillsAlso are agents whose skills this one reads as well, as
	// OpenCode reads Claude Code's.
	SkillsAlso []string
	// MCPVia is the extension the agent reads its MCP servers through, for
	// one that has none of its own.
	MCPVia string
	// Note is what the page says of the agent's instructions file.
	Note string
	// Copy is an agent that gets a copy of each skill, made again when
	// the library's changes, rather than a link: one in a WSL distro,
	// which can't follow a link to a Windows folder.
	Copy bool
	// Desktop are Claude Desktop's skills-plugin folders, one for each
	// account (desktop_skills.go): each gets a copy of the skills and their
	// entries in its manifest.json. Skills is the first one's skills.
	Desktop []string
	// Settings is Claude Code's settings.json, whose permissions.deny
	// leaves out the tools of a server turned off (mcp_tools_off.go)
	Settings string
	// Gone is an agent no longer installed here that still has what magpie
	// gave it (held): a sync only takes things out of it, as they are
	// unticked, and gives it nothing.
	Gone bool
}

Target is where one agent keeps each of the three: an empty path is something it has no user-wide place for.

func Targets

func Targets() []*Target

Targets are the agents on this machine that magpie can give any of the three to, in the order the rest of magpie lists them.

type Tool added in v0.1.1179

type Tool struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
}

Tool is one tool a server listed: its name, and the first paragraph of its description, cut short.

type View

type View struct {
	Agents  []AgentView  `json:"agents"`
	Servers []ServerView `json:"servers"`
	// Hooks are the library's hooks, and HookAgents what each agent on
	// this computer can take of them (hooks.go)
	Hooks        []HookView      `json:"hooks"`
	HookAgents   []HookAgentView `json:"hookAgents"`
	FoundServers []Found         `json:"foundServers"`
	Skills       []SkillView     `json:"skills"`
	FoundSkills  []FoundSkill    `json:"foundSkills"`
	// NewSkills are skills a check found its skills' repositories to have
	// added beside them, to add or set aside
	NewSkills    []NewSkill        `json:"newSkills"`
	Projects     []ProjectView     `json:"projects"`
	Instructions *InstructionsView `json:"instructions"`
	Dir          string            `json:"dir"`
	Backups      string            `json:"backups"`
	SkillGroups  []SkillGroup      `json:"skillGroups"`
	CopySkills   bool              `json:"copySkills"` // the library gives skills as copies (#896)
	// CheckDue is set when the skills from GitHub weren't checked for
	// updates since magpie started, or not for a while: the page checks
	// them as it shows them (#1449)
	CheckDue bool `json:"checkDue,omitempty"`
	// Partial is a glance (Glance): FoundSkills and each skill's Behind
	// aren't read yet
	Partial bool `json:"partial,omitempty"`
}

View is the Library page.

func Glance added in v0.1.1163

func Glance(problems []Problem) (*View, error)

Glance is the page but for what takes reading the agents' skill folders through: the skills the agents have of their own, and which copies are out of date (Partial). The page shows it at once, and Read's after it (0day404, #541): on a machine with many big skills in many agents, that part can take minutes the first time.

func Read

func Read(problems []Problem) (*View, error)

Read is the whole page: the library, and what's found in the agents. problems are those of the last change, for the page to keep showing.

Jump to

Keyboard shortcuts

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