Documentation
¶
Overview ¶
Package installer provides the mechanics behind "sync82 install [target]" and "sync82 uninstall [target] [--purge]": the Target type describing each supported MCP client, the fixed Targets list, the Env the targets resolve their paths against, InstallTarget and UninstallTarget, which register or remove sync82 in one target by invoking the client's own MCP subcommands (KindCLI) or editing its JSON config files (KindFile), and the purge helpers listing and deleting the files of sync82's data directory. The command-line flows — listing detected targets, confirming, dispatching across all of them, and summarizing results — live in cmd/sync82's RunInstall and RunUninstall.
Index ¶
- Constants
- Variables
- func ConfiguredVaults(env Env, cwd string) []string
- func DataDir(homeDir string) string
- func DeleteFiles(homeDir string, files []string) []error
- func PurgeCandidates(homeDir string) []string
- func TargetNames() []string
- func TargetNamesIn(targets []Target) []string
- type Env
- type Kind
- type Result
- type Shape
- type Target
Constants ¶
const InstallTimeout = 30 * time.Second
InstallTimeout bounds how long each of a CLI target's own subcommands may run.
Variables ¶
var Targets = []Target{ { Kind: KindCLI, Name: "claude", DetectCmd: "claude", Command: "claude", Args: func(bin string) []string { return []string{"mcp", "add", "--scope", "user", serverName, "--", bin} }, GetArgs: []string{"mcp", "get", serverName}, RemoveArgs: func(scope string) []string { return []string{"mcp", "remove", "--scope", scope, serverName} }, Scope: claudeScope, }, { Kind: KindFile, Name: "claude-desktop", Shape: shapeMCPServers, Unsupported: func(env Env) string { if claudeDesktopDir(env) == "" { return "Claude Desktop is only available for macOS, Windows and Linux" } return "" }, DetectDirs: claudeDesktopDirs, ConfigPaths: claudeDesktopConfigPaths, RemovePaths: func(env Env) []string { var paths []string for _, dir := range claudeDesktopDirs(env) { paths = append(paths, filepath.Join(dir, "claude_desktop_config.json")) } return paths }, }, { Kind: KindFile, Name: "antigravity", Shape: shapeMCPServers, DetectCmd: "agy", DetectDirs: func(env Env) []string { return []string{antigravityConfigDir(env), antigravityLegacyDir(env)} }, ConfigPaths: fixedPaths(antigravityGlobalConfigPath), RemovePaths: func(env Env) []string { return []string{ antigravityGlobalConfigPath(env), filepath.Join(antigravityLegacyDir(env), "mcp_config.json"), filepath.Join(env.HomeDir, ".gemini", "antigravity-ide", "mcp_config.json"), } }, }, { Kind: KindCLI, Name: "codex", DetectCmd: "codex", Command: "codex", Args: func(bin string) []string { return []string{"mcp", "add", serverName, "--", bin} }, GetArgs: []string{"mcp", "get", serverName}, RemoveArgs: func(string) []string { return []string{"mcp", "remove", serverName} }, }, { Kind: KindFile, Name: "opencode", Shape: shapeOpenCode, DetectCmd: "opencode", ConfigPaths: fixedPaths(opencodeInstallPath), RemovePaths: opencodeConfigPaths, }, { Kind: KindFile, Name: "cursor", Shape: shapeCursor, DetectDirs: fixedPaths(cursorDir), ConfigPaths: fixedPaths(func(env Env) string { return filepath.Join(cursorDir(env), "mcp.json") }), }, { Kind: KindFile, Name: "zed", Shape: shapeZed, DetectDirs: fixedPaths(zedDir), ConfigPaths: fixedPaths(func(env Env) string { return filepath.Join(zedDir(env), "settings.json") }), }, { Kind: KindFile, Name: "cline", Shape: shapeMCPServers, DetectDirs: func(env Env) []string { marker, _ := clineCLIDirs(env) dirs := []string{clineExtensionDir(env), marker} if override := clineSettingsOverride(env); override != "" { dirs = append(dirs, filepath.Dir(override)) } return dirs }, ConfigPaths: func(env Env) []string { var paths []string if ext := clineExtensionDir(env); dirExists(ext) { paths = append(paths, clineSettingsPath(ext)) } marker, _ := clineCLIDirs(env) if override := clineSettingsOverride(env); dirExists(marker) || (override != "" && dirExists(filepath.Dir(override))) { paths = append(paths, clineCLISettingsPath(env)) } return paths }, RemovePaths: func(env Env) []string { _, data := clineCLIDirs(env) paths := []string{clineSettingsPath(clineExtensionDir(env)), clineSettingsPath(data)} if override := clineSettingsOverride(env); override != "" && override != paths[1] { paths = append(paths, override) } return paths }, }, }
Targets is the fixed set of install targets, in the order "install" and "uninstall" process them.
claude and codex are registered through their own CLIs, with the command after "--", after removing any existing registration: claude per scope (local and user; a project registration is reported and left unchanged), codex through its single configuration. Every other target is a JSON config file edited in place.
Functions ¶
func ConfiguredVaults ¶
ConfiguredVaults returns the vault paths configured away from the default <homeDir>/.sync82/knowledge.db, which a purge leaves untouched: the SYNC82_DB_PATH variable, the global config's vaultPath and lastVaultPath, and the "path" of a .sync82.json found at cwd or one of its parents. Paths are made absolute and listed once each.
func DeleteFiles ¶
DeleteFiles removes every file in files, then removes the data directory under homeDir when it is left empty. It returns one error per file that could not be removed; a file already gone is not an error.
func PurgeCandidates ¶
PurgeCandidates returns every existing file a purge deletes from the data directory under homeDir: the purgeFileNames entries plus every config.json.corrupt-* file. Nothing else in the directory is listed.
func TargetNames ¶
func TargetNames() []string
TargetNames returns the names of every install target, in Targets order.
func TargetNamesIn ¶
TargetNamesIn returns the names of every target in targets, in order.
Types ¶
type Env ¶
type Env struct {
GOOS string
HomeDir string
Getenv func(key string) string
LookPath func(file string) (string, error)
}
Env is the host environment the targets resolve their paths and detection against: the operating system, the home directory, an environment variable lookup, and a PATH lookup.
type Kind ¶
type Kind string
Kind distinguishes the two installer strategies: a "cli" target is installed by invoking the client's own MCP subcommands; a "file" target is installed by read-merge-write of a JSON config file.
type Result ¶
type Result string
Result is the outcome of installing into, or uninstalling from, a single target.
const ( ResultOK Result = "ok" ResultSkip Result = "skip" ResultManual Result = "manual" ResultFail Result = "fail" )
Result values: ResultOK means the registration was written or removed, ResultSkip means the target was unsupported, not detected or had nothing to remove, ResultManual means a config file holds comments or trailing commas, so it was left unchanged and the entry printed to add by hand, and ResultFail means the operation failed.
func InstallTarget ¶
func InstallTarget(ctx context.Context, t Target, env Env, binaryPath string, stdout, stderr io.Writer) Result
InstallTarget installs sync82 into a single target, dispatching by kind, and prints "configured." for a new registration or "updated." when one already existed, followed by any warning. A target unsupported on env.GOOS or not detected is skipped. stdout/stderr receive the progress lines; a CLI target's MCP-add subprocess also inherits them (plus stdin), so its output and prompts reach the user directly.
binaryPath is the absolute path of the sync82 binary the client is configured to launch.
func UninstallTarget ¶
UninstallTarget removes sync82's registration from a single target. A CLI target is cleaned through its own CLI and skipped when its client is not detected; a file target has the sync82 key deleted from each of its RemovePaths files whether or not its client is still installed. A target with nothing registered is reported as "not configured, skipping" and returns ResultSkip. Warnings are printed after the status line.
type Shape ¶
Shape describes where a client's JSON config keeps its MCP servers: Key is the top-level object holding one entry per server, and Entry builds sync82's entry for binaryPath. Entry is nil for a shape that is only ever read or cleaned, never written.
type Target ¶
type Target struct {
Name string
Kind Kind
// Unsupported, when set and returning a non-empty reason, marks the
// target as unavailable on env.GOOS; it is then never detected, and
// install and uninstall skip it.
Unsupported func(env Env) string
// A target is detected when DetectCmd is on PATH or any directory
// returned by DetectDirs exists. Either may be empty.
DetectCmd string
DetectDirs func(env Env) []string
// CLI targets only. Command is the client's executable. Args returns
// its MCP-add arguments for binaryPath. GetArgs exits with status 0
// only while sync82 is registered. RemoveArgs returns the arguments
// removing sync82 from one scope; a client without scopes receives ""
// and ignores it. Scope, when set, marks a client keeping
// registrations in several scopes and extracts from the GetArgs output
// the scope of the registration it reports, or "" when none is named.
Command string
Args func(binaryPath string) []string
GetArgs []string
RemoveArgs func(scope string) []string
Scope func(getOutput []byte) string
// File targets only. Shape is the layout of the target's JSON config
// files. Install merges sync82's entry into every ConfigPaths file.
// Uninstall cleans every RemovePaths file (ConfigPaths when nil).
Shape Shape
ConfigPaths func(env Env) []string
RemovePaths func(env Env) []string
}
Target describes one MCP client install target.
func DetectedIn ¶
DetectedIn returns the targets of targets detected on env, in order.
func UninstallCandidatesIn ¶ added in v1.2.0
UninstallCandidatesIn returns the targets of targets an uninstall with no target acts on, in targets order: every detected one, plus every file target that isn't detected any more but whose config files still hold a sync82 entry (its client was removed, or moved off PATH), so the entry isn't left behind.