sync

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jan 21, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const BackupSuffix = ".bak"

BackupSuffix is the suffix used for backup files

View Source
const DefaultBackupCount = 3

DefaultBackupCount is the default number of backups to keep

View Source
const ManagedMarker = "_managedBy"

ManagedMarker is the key used to mark entries managed by agentctl

View Source
const ManagedValue = "agentctl"

ManagedValue is the value used to identify agentctl-managed entries

Variables

This section is empty.

Functions

func AtomicWriteFile added in v0.3.0

func AtomicWriteFile(path string, data []byte, perm os.FileMode) error

AtomicWriteFile writes data to a file atomically by first writing to a temporary file and then renaming it to the target path. This prevents corruption if the process is interrupted mid-write.

func CreateBackup added in v0.3.0

func CreateBackup(path string) (string, error)

CreateBackup creates a timestamped backup of the file at the given path. Returns the backup path or empty string if the source file doesn't exist.

func CreateSimpleBackup added in v0.3.0

func CreateSimpleBackup(path string) (string, error)

CreateSimpleBackup creates a simple .bak backup (overwrites previous backup). This is useful when you only need one backup file.

func FilterStdioServers

func FilterStdioServers(servers []*mcp.Server) []*mcp.Server

FilterStdioServers returns only servers that use stdio transport Use this for tools that don't support HTTP/SSE remote MCP servers

func FormatCommandMarkdown added in v0.3.0

func FormatCommandMarkdown(cmd *command.Command, fields []CommandFrontmatterField) string

FormatCommandMarkdown formats a command as markdown with YAML frontmatter

func GetMCPServersSection added in v0.3.0

func GetMCPServersSection(raw map[string]interface{}, key string) (map[string]interface{}, bool)

GetMCPServersSection gets or creates the mcpServers section from a raw config. Returns the section and a boolean indicating if it was newly created.

func GetServerName added in v0.3.0

func GetServerName(server *mcp.Server) string

GetServerName returns the effective name for a server (namespace if set, otherwise name)

func ListBackups added in v0.3.0

func ListBackups(path string) ([]string, error)

ListBackups returns a list of all backup files for the given path, sorted from oldest to newest.

func MustSanitizeName added in v0.3.0

func MustSanitizeName(name string)

MustSanitizeName is like SanitizeName but panics on error. Use only in contexts where the name has already been validated.

func ParseCommandMarkdown added in v0.3.0

func ParseCommandMarkdown(filename, content string, fields []CommandFrontmatterField) *command.Command

ParseCommandMarkdown parses a markdown command file with YAML frontmatter. Returns the parsed command with name derived from filename.

func ReadCommandsFromDir added in v0.3.0

func ReadCommandsFromDir(dir string, parseFunc func(filename, content string) *command.Command) ([]*command.Command, error)

ReadCommandsFromDir reads all .md command files from a directory

func ReadSkillsFromDir added in v0.3.0

func ReadSkillsFromDir(skillsDir string) ([]*skill.Skill, error)

ReadSkillsFromDir reads all skills from a skills directory. Each skill should be in its own subdirectory with a SKILL.md file.

func Register

func Register(adapter Adapter)

Register registers an adapter

func RemoveManagedServers added in v0.3.0

func RemoveManagedServers(mcpServers map[string]interface{})

RemoveManagedServers removes all servers marked as managed by agentctl

func RestoreBackup added in v0.3.0

func RestoreBackup(path string) (string, error)

RestoreBackup restores the most recent backup for the given file. Returns the backup path that was restored, or empty string if no backup exists.

func RotateBackups added in v0.3.0

func RotateBackups(path string, keepCount int) error

RotateBackups keeps only the most recent N backups for the given file. It looks for files matching the pattern: base.bak.TIMESTAMP.ext

func SafeWriteFile added in v0.3.0

func SafeWriteFile(path string, data []byte, perm os.FileMode, keepBackups int) error

SafeWriteFile combines backup creation, atomic write, and backup rotation. This is the recommended way to safely write config files.

func SafeWriteFileWithLock added in v0.3.0

func SafeWriteFileWithLock(path string, data []byte, perm os.FileMode, keepBackups int) error

SafeWriteFileWithLock combines file locking, backup, and atomic write. Use this when multiple processes might write to the same file.

func SanitizeName added in v0.3.0

func SanitizeName(name string) error

SanitizeName validates and sanitizes a resource name (server, command, skill, rule) to prevent path traversal attacks when used in filepath.Join(). This is a convenience wrapper around pathutil.SanitizeName.

func ServerFromRawMap added in v0.3.0

func ServerFromRawMap(name string, serverData map[string]interface{}) *mcp.Server

ServerFromRawMap parses a server from a raw map[string]interface{} representation. This handles the common mcpServers JSON format with command, args, env fields.

func ServerToRawMap added in v0.3.0

func ServerToRawMap(server *mcp.Server) map[string]interface{}

ServerToRawMap converts a server to a raw map for JSON serialization. Includes the _managedBy marker. Only includes stdio transport fields.

func ServerToRawMapWithTransport added in v0.3.0

func ServerToRawMapWithTransport(server *mcp.Server) map[string]interface{}

ServerToRawMapWithTransport converts a server to a raw map, including transport fields. Use for tools that support HTTP/SSE transport.

func ServersFromMCPSection added in v0.3.0

func ServersFromMCPSection(mcpServers map[string]interface{}) []*mcp.Server

ServersFromMCPSection parses all servers from an mcpServers section

func SupportsAgents added in v0.3.0

func SupportsAgents(a Adapter) bool

SupportsAgents checks if an adapter implements AgentsAdapter

func SupportsCommands added in v0.3.0

func SupportsCommands(a Adapter) bool

SupportsCommands checks if an adapter implements CommandsAdapter

func SupportsRules added in v0.3.0

func SupportsRules(a Adapter) bool

SupportsRules checks if an adapter implements RulesAdapter

func SupportsServers added in v0.3.0

func SupportsServers(a Adapter) bool

SupportsServers checks if an adapter implements ServerAdapter

func SupportsSkills added in v0.3.0

func SupportsSkills(a Adapter) bool

SupportsSkills checks if an adapter implements SkillsAdapter

func SupportsWorkspace

func SupportsWorkspace(a Adapter) bool

SupportsWorkspace checks if an adapter implements WorkspaceAdapter

func WriteAgentsToDir added in v0.3.0

func WriteAgentsToDir(agentsDir string, agents []*agent.Agent) error

WriteAgentsToDir writes agents to an agents directory. Each agent is written as a markdown file.

func WriteCommandsToDir added in v0.3.0

func WriteCommandsToDir(dir string, commands []*command.Command, formatFunc func(cmd *command.Command) string) error

WriteCommandsToDir writes commands as .md files to a directory

func WriteSkillsToDir added in v0.3.0

func WriteSkillsToDir(skillsDir string, skills []*skill.Skill) error

WriteSkillsToDir writes skills to a skills directory. Each skill is written to its own subdirectory.

Types

type Adapter

type Adapter interface {
	// Name returns the adapter name (e.g., "claude", "cursor")
	Name() string

	// Detect checks if this tool is installed on the system
	Detect() (bool, error)

	// ConfigPath returns the path to the tool's config file
	ConfigPath() string

	// SupportedResources returns the resource types this adapter supports
	SupportedResources() []ResourceType
}

Adapter is the base interface that all tool-specific adapters must implement. This interface contains only the core methods. Resource-specific operations (servers, commands, rules, skills) are defined in separate optional interfaces.

func All

func All() []Adapter

All returns all registered adapters

func Detected

func Detected() []Adapter

Detected returns all adapters for installed tools

func Get

func Get(name string) (Adapter, bool)

Get returns an adapter by name

type AgentsAdapter added in v0.3.0

type AgentsAdapter interface {
	Adapter

	// ReadAgents reads agent configurations from the tool
	ReadAgents() ([]*agent.Agent, error)

	// WriteAgents writes agent configurations to the tool
	// Creates markdown files in the tool's agents directory
	WriteAgents(agents []*agent.Agent) error
}

AgentsAdapter is an optional interface for adapters that support agents/subagents. Agents are markdown files that define custom AI personas with specific instructions, capabilities, and tool permissions.

func AsAgentsAdapter added in v0.3.0

func AsAgentsAdapter(a Adapter) (AgentsAdapter, bool)

AsAgentsAdapter returns the adapter as an AgentsAdapter if supported

type ClaudeAdapter

type ClaudeAdapter struct{}

ClaudeAdapter syncs configuration to Claude Code CLI (~/.claude/) This is the default "claude" adapter as Claude Code is the primary developer tool

func (*ClaudeAdapter) ConfigPath

func (a *ClaudeAdapter) ConfigPath() string

func (*ClaudeAdapter) Detect

func (a *ClaudeAdapter) Detect() (bool, error)

func (*ClaudeAdapter) Name

func (a *ClaudeAdapter) Name() string

func (*ClaudeAdapter) ReadAgents added in v0.3.0

func (a *ClaudeAdapter) ReadAgents() ([]*agent.Agent, error)

ReadAgents reads agents from Claude Code's agents directory

func (*ClaudeAdapter) ReadCommands

func (a *ClaudeAdapter) ReadCommands() ([]*command.Command, error)

func (*ClaudeAdapter) ReadRules

func (a *ClaudeAdapter) ReadRules() ([]*rule.Rule, error)

func (*ClaudeAdapter) ReadServers

func (a *ClaudeAdapter) ReadServers() ([]*mcp.Server, error)

func (*ClaudeAdapter) ReadSkills

func (a *ClaudeAdapter) ReadSkills() ([]*skill.Skill, error)

ReadSkills reads installed plugins as skills

func (*ClaudeAdapter) ReadWorkspaceServers

func (a *ClaudeAdapter) ReadWorkspaceServers(projectDir string) ([]*mcp.Server, error)

ReadWorkspaceServers reads MCP servers from the project's .mcp.json file

func (*ClaudeAdapter) SupportedResources

func (a *ClaudeAdapter) SupportedResources() []ResourceType

func (*ClaudeAdapter) SupportsWorkspace

func (a *ClaudeAdapter) SupportsWorkspace() bool

SupportsWorkspace returns true - Claude Code supports .mcp.json in project root

func (*ClaudeAdapter) WorkspaceConfigPath

func (a *ClaudeAdapter) WorkspaceConfigPath(projectDir string) string

WorkspaceConfigPath returns the path to .mcp.json in the project directory

func (*ClaudeAdapter) WriteAgents added in v0.3.0

func (a *ClaudeAdapter) WriteAgents(agents []*agent.Agent) error

WriteAgents writes agents to Claude Code's agents directory

func (*ClaudeAdapter) WriteCommands

func (a *ClaudeAdapter) WriteCommands(commands []*command.Command) error

func (*ClaudeAdapter) WriteRules

func (a *ClaudeAdapter) WriteRules(rules []*rule.Rule) error

func (*ClaudeAdapter) WriteServers

func (a *ClaudeAdapter) WriteServers(servers []*mcp.Server) error

func (*ClaudeAdapter) WriteSkills added in v0.3.0

func (a *ClaudeAdapter) WriteSkills(skills []*skill.Skill) error

WriteSkills writes skills to Claude Code's skills directory Note: This writes to ~/.claude/skills/, not the plugins system

func (*ClaudeAdapter) WriteWorkspaceServers

func (a *ClaudeAdapter) WriteWorkspaceServers(projectDir string, servers []*mcp.Server) error

WriteWorkspaceServers writes MCP servers to the project's .mcp.json file

type ClaudeCodePlugin

type ClaudeCodePlugin struct {
	Scope        string `json:"scope"`
	InstallPath  string `json:"installPath"`
	Version      string `json:"version"`
	InstalledAt  string `json:"installedAt"`
	LastUpdated  string `json:"lastUpdated"`
	GitCommitSha string `json:"gitCommitSha,omitempty"`
	IsLocal      bool   `json:"isLocal"`
}

ClaudeCodePlugin represents an installed plugin

type ClaudeCodePluginsFile

type ClaudeCodePluginsFile struct {
	Version int                           `json:"version"`
	Plugins map[string][]ClaudeCodePlugin `json:"plugins"`
}

ClaudeCodePluginsFile represents the installed_plugins.json structure

type ClaudeCodeSettings

type ClaudeCodeSettings struct {
	MCPServers     map[string]ClaudeServerConfig `json:"mcpServers,omitempty"`
	EnabledPlugins map[string]bool               `json:"enabledPlugins,omitempty"`
	Hooks          map[string]interface{}        `json:"hooks,omitempty"`
	// Preserve other fields
	Other map[string]interface{} `json:"-"`
}

ClaudeCodeSettings represents Claude Code's settings.json structure

type ClaudeConfig

type ClaudeConfig struct {
	MCPServers map[string]ClaudeServerConfig `json:"mcpServers,omitempty"`
}

ClaudeConfig represents Claude's configuration file structure

type ClaudeDesktopAdapter

type ClaudeDesktopAdapter struct{}

ClaudeDesktopAdapter syncs configuration to Claude Desktop (the Electron app)

func (*ClaudeDesktopAdapter) ConfigPath

func (a *ClaudeDesktopAdapter) ConfigPath() string

func (*ClaudeDesktopAdapter) Detect

func (a *ClaudeDesktopAdapter) Detect() (bool, error)

func (*ClaudeDesktopAdapter) Name

func (a *ClaudeDesktopAdapter) Name() string

func (*ClaudeDesktopAdapter) ReadServers

func (a *ClaudeDesktopAdapter) ReadServers() ([]*mcp.Server, error)

func (*ClaudeDesktopAdapter) SupportedResources

func (a *ClaudeDesktopAdapter) SupportedResources() []ResourceType

func (*ClaudeDesktopAdapter) WriteServers

func (a *ClaudeDesktopAdapter) WriteServers(servers []*mcp.Server) error

type ClaudeServerConfig

type ClaudeServerConfig struct {
	// For local (stdio) servers
	Command string   `json:"command,omitempty"`
	Args    []string `json:"args,omitempty"`

	// For remote (http/sse) servers
	Transport string `json:"transport,omitempty"` // "http" or "sse"
	URL       string `json:"url,omitempty"`       // Remote server URL

	// Common fields
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

ClaudeServerConfig represents a server in Claude's config format

type ClineAdapter

type ClineAdapter struct{}

ClineAdapter syncs configuration to Cline

func (*ClineAdapter) ConfigPath

func (a *ClineAdapter) ConfigPath() string

func (*ClineAdapter) Detect

func (a *ClineAdapter) Detect() (bool, error)

func (*ClineAdapter) Name

func (a *ClineAdapter) Name() string

func (*ClineAdapter) ReadServers

func (a *ClineAdapter) ReadServers() ([]*mcp.Server, error)

func (*ClineAdapter) SupportedResources

func (a *ClineAdapter) SupportedResources() []ResourceType

func (*ClineAdapter) WriteServers

func (a *ClineAdapter) WriteServers(servers []*mcp.Server) error

type ClineServerConfig

type ClineServerConfig struct {
	Command   string            `json:"command"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

ClineServerConfig represents a server in Cline's config format

type CodexAdapter

type CodexAdapter struct{}

CodexAdapter syncs configuration to OpenAI Codex CLI Codex uses TOML format (config.toml) as primary config

func (*CodexAdapter) ConfigPath

func (a *CodexAdapter) ConfigPath() string

func (*CodexAdapter) Detect

func (a *CodexAdapter) Detect() (bool, error)

func (*CodexAdapter) Name

func (a *CodexAdapter) Name() string

func (*CodexAdapter) ReadCommands

func (a *CodexAdapter) ReadCommands() ([]*command.Command, error)

func (*CodexAdapter) ReadRules

func (a *CodexAdapter) ReadRules() ([]*rule.Rule, error)

func (*CodexAdapter) ReadServers

func (a *CodexAdapter) ReadServers() ([]*mcp.Server, error)

func (*CodexAdapter) ReadSkills added in v0.3.0

func (a *CodexAdapter) ReadSkills() ([]*skill.Skill, error)

ReadSkills reads skills from Codex's skills directory

func (*CodexAdapter) SupportedResources

func (a *CodexAdapter) SupportedResources() []ResourceType

func (*CodexAdapter) WriteCommands

func (a *CodexAdapter) WriteCommands(commands []*command.Command) error

func (*CodexAdapter) WriteRules

func (a *CodexAdapter) WriteRules(rules []*rule.Rule) error

func (*CodexAdapter) WriteServers

func (a *CodexAdapter) WriteServers(servers []*mcp.Server) error

func (*CodexAdapter) WriteSkills added in v0.3.0

func (a *CodexAdapter) WriteSkills(skills []*skill.Skill) error

WriteSkills writes skills to Codex's skills directory

type CodexJSONConfig added in v0.3.0

type CodexJSONConfig struct {
	MCPServers map[string]CodexJSONServerConfig `json:"mcpServers,omitempty"`
}

CodexJSONConfig represents Codex's legacy JSON configuration

type CodexJSONServerConfig added in v0.3.0

type CodexJSONServerConfig struct {
	Command   string            `json:"command"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

CodexJSONServerConfig represents a server in Codex's legacy JSON format

type CodexTOMLConfig added in v0.3.0

type CodexTOMLConfig struct {
	MCPServers map[string]CodexTOMLServerConfig `toml:"mcp_servers"`
	// Preserve other sections
	Other map[string]interface{} `toml:"-"`
}

CodexTOMLConfig represents Codex's TOML configuration structure

type CodexTOMLServerConfig added in v0.3.0

type CodexTOMLServerConfig struct {
	Command     string            `toml:"command,omitempty"`
	Args        []string          `toml:"args,omitempty"`
	URL         string            `toml:"url,omitempty"`
	Env         map[string]string `toml:"env,omitempty"`
	Enabled     *bool             `toml:"enabled,omitempty"`
	Timeout     int               `toml:"startup_timeout_sec,omitempty"`
	ToolTimeout int               `toml:"tool_timeout_sec,omitempty"`
}

CodexTOMLServerConfig represents a server in Codex's TOML format

type CommandFrontmatterField added in v0.3.0

type CommandFrontmatterField struct {
	Key  string
	Dest *string
	List *[]string // For list fields like allowed-tools
}

CommandFrontmatterField represents a frontmatter field to parse

type CommandsAdapter added in v0.3.0

type CommandsAdapter interface {
	Adapter

	// ReadCommands reads command configurations from the tool
	ReadCommands() ([]*command.Command, error)

	// WriteCommands writes command configurations to the tool
	WriteCommands(commands []*command.Command) error
}

CommandsAdapter is an optional interface for adapters that support commands. Implement this interface if the tool can sync command configurations.

func AsCommandsAdapter added in v0.3.0

func AsCommandsAdapter(a Adapter) (CommandsAdapter, bool)

AsCommandsAdapter returns the adapter as a CommandsAdapter if supported

type ContinueAdapter

type ContinueAdapter struct{}

ContinueAdapter syncs configuration to Continue.dev

func (*ContinueAdapter) ConfigPath

func (a *ContinueAdapter) ConfigPath() string

func (*ContinueAdapter) Detect

func (a *ContinueAdapter) Detect() (bool, error)

func (*ContinueAdapter) Name

func (a *ContinueAdapter) Name() string

func (*ContinueAdapter) ReadRules

func (a *ContinueAdapter) ReadRules() ([]*rule.Rule, error)

func (*ContinueAdapter) ReadServers

func (a *ContinueAdapter) ReadServers() ([]*mcp.Server, error)

func (*ContinueAdapter) SupportedResources

func (a *ContinueAdapter) SupportedResources() []ResourceType

func (*ContinueAdapter) WriteRules

func (a *ContinueAdapter) WriteRules(rules []*rule.Rule) error

func (*ContinueAdapter) WriteServers

func (a *ContinueAdapter) WriteServers(servers []*mcp.Server) error

type ContinueServerConfig

type ContinueServerConfig struct {
	Command   string            `json:"command"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

ContinueServerConfig represents a server in Continue's config format

type CopilotAdapter added in v0.3.0

type CopilotAdapter struct{}

CopilotAdapter syncs configuration to GitHub Copilot CLI Copilot CLI uses ~/.config/github-copilot/ on Unix systems

func (*CopilotAdapter) ConfigPath added in v0.3.0

func (a *CopilotAdapter) ConfigPath() string

func (*CopilotAdapter) Detect added in v0.3.0

func (a *CopilotAdapter) Detect() (bool, error)

func (*CopilotAdapter) Name added in v0.3.0

func (a *CopilotAdapter) Name() string

func (*CopilotAdapter) ReadAgents added in v0.3.0

func (a *CopilotAdapter) ReadAgents() ([]*agent.Agent, error)

ReadAgents reads agents from Copilot's agents directory

func (*CopilotAdapter) ReadCommands added in v0.3.0

func (a *CopilotAdapter) ReadCommands() ([]*command.Command, error)

func (*CopilotAdapter) ReadRules added in v0.3.0

func (a *CopilotAdapter) ReadRules() ([]*rule.Rule, error)

func (*CopilotAdapter) ReadServers added in v0.3.0

func (a *CopilotAdapter) ReadServers() ([]*mcp.Server, error)

func (*CopilotAdapter) ReadSkills added in v0.3.0

func (a *CopilotAdapter) ReadSkills() ([]*skill.Skill, error)

ReadSkills reads skills from Copilot's skills directory

func (*CopilotAdapter) SupportedResources added in v0.3.0

func (a *CopilotAdapter) SupportedResources() []ResourceType

func (*CopilotAdapter) WriteAgents added in v0.3.0

func (a *CopilotAdapter) WriteAgents(agents []*agent.Agent) error

WriteAgents writes agents to Copilot's agents directory Note: GitHub Copilot expects .agent.md extension for agents

func (*CopilotAdapter) WriteCommands added in v0.3.0

func (a *CopilotAdapter) WriteCommands(commands []*command.Command) error

func (*CopilotAdapter) WriteRules added in v0.3.0

func (a *CopilotAdapter) WriteRules(rules []*rule.Rule) error

func (*CopilotAdapter) WriteServers added in v0.3.0

func (a *CopilotAdapter) WriteServers(servers []*mcp.Server) error

func (*CopilotAdapter) WriteSkills added in v0.3.0

func (a *CopilotAdapter) WriteSkills(skills []*skill.Skill) error

WriteSkills writes skills to Copilot's skills directory

type CopilotConfig added in v0.3.0

type CopilotConfig struct {
	MCPServers map[string]CopilotServerConfig `json:"mcpServers,omitempty"`
	// Preserve other fields
	Other map[string]interface{} `json:"-"`
}

CopilotConfig represents Copilot CLI's configuration structure

type CopilotServerConfig added in v0.3.0

type CopilotServerConfig struct {
	Command   string            `json:"command"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

CopilotServerConfig represents a server in Copilot's config format

type CursorAdapter

type CursorAdapter struct{}

CursorAdapter syncs configuration to Cursor

func (*CursorAdapter) ConfigPath

func (a *CursorAdapter) ConfigPath() string

func (*CursorAdapter) Detect

func (a *CursorAdapter) Detect() (bool, error)

func (*CursorAdapter) Name

func (a *CursorAdapter) Name() string

func (*CursorAdapter) ReadAgents added in v0.3.0

func (a *CursorAdapter) ReadAgents() ([]*agent.Agent, error)

ReadAgents reads agents from Cursor's agents directory

func (*CursorAdapter) ReadCommands

func (a *CursorAdapter) ReadCommands() ([]*command.Command, error)

func (*CursorAdapter) ReadRules

func (a *CursorAdapter) ReadRules() ([]*rule.Rule, error)

func (*CursorAdapter) ReadServers

func (a *CursorAdapter) ReadServers() ([]*mcp.Server, error)

func (*CursorAdapter) ReadWorkspaceServers

func (a *CursorAdapter) ReadWorkspaceServers(projectDir string) ([]*mcp.Server, error)

ReadWorkspaceServers reads MCP servers from the project's .cursor/mcp.json file

func (*CursorAdapter) SupportedResources

func (a *CursorAdapter) SupportedResources() []ResourceType

func (*CursorAdapter) SupportsWorkspace

func (a *CursorAdapter) SupportsWorkspace() bool

SupportsWorkspace returns true - Cursor supports .cursor/mcp.json in project root

func (*CursorAdapter) WorkspaceConfigPath

func (a *CursorAdapter) WorkspaceConfigPath(projectDir string) string

WorkspaceConfigPath returns the path to .cursor/mcp.json in the project directory

func (*CursorAdapter) WriteAgents added in v0.3.0

func (a *CursorAdapter) WriteAgents(agents []*agent.Agent) error

WriteAgents writes agents to Cursor's agents directory

func (*CursorAdapter) WriteCommands

func (a *CursorAdapter) WriteCommands(commands []*command.Command) error

func (*CursorAdapter) WriteRules

func (a *CursorAdapter) WriteRules(rules []*rule.Rule) error

func (*CursorAdapter) WriteServers

func (a *CursorAdapter) WriteServers(servers []*mcp.Server) error

func (*CursorAdapter) WriteWorkspaceServers

func (a *CursorAdapter) WriteWorkspaceServers(projectDir string, servers []*mcp.Server) error

WriteWorkspaceServers writes MCP servers to the project's .cursor/mcp.json file

type CursorServerConfig

type CursorServerConfig struct {
	Command   string            `json:"command"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

CursorServerConfig represents a server in Cursor's config format

type FileLock added in v0.3.0

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

FileLock represents a file-based lock for synchronization

func NewFileLock added in v0.3.0

func NewFileLock(path string) *FileLock

NewFileLock creates a new file lock for the given path. The lock file will be created at path + ".lock"

func (*FileLock) Lock added in v0.3.0

func (l *FileLock) Lock() error

Lock acquires an exclusive lock on the file. This blocks until the lock is acquired.

func (*FileLock) TryLock added in v0.3.0

func (l *FileLock) TryLock() (bool, error)

TryLock attempts to acquire an exclusive lock without blocking. Returns true if the lock was acquired, false if it's held by another process.

func (*FileLock) Unlock added in v0.3.0

func (l *FileLock) Unlock() error

Unlock releases the lock.

type GeminiAdapter

type GeminiAdapter struct{}

GeminiAdapter syncs configuration to Google Gemini CLI

func (*GeminiAdapter) ConfigPath

func (a *GeminiAdapter) ConfigPath() string

func (*GeminiAdapter) Detect

func (a *GeminiAdapter) Detect() (bool, error)

func (*GeminiAdapter) Name

func (a *GeminiAdapter) Name() string

func (*GeminiAdapter) ReadCommands

func (a *GeminiAdapter) ReadCommands() ([]*command.Command, error)

func (*GeminiAdapter) ReadRules

func (a *GeminiAdapter) ReadRules() ([]*rule.Rule, error)

func (*GeminiAdapter) ReadServers

func (a *GeminiAdapter) ReadServers() ([]*mcp.Server, error)

func (*GeminiAdapter) SupportedResources

func (a *GeminiAdapter) SupportedResources() []ResourceType

func (*GeminiAdapter) WriteCommands

func (a *GeminiAdapter) WriteCommands(commands []*command.Command) error

func (*GeminiAdapter) WriteRules

func (a *GeminiAdapter) WriteRules(rules []*rule.Rule) error

func (*GeminiAdapter) WriteServers

func (a *GeminiAdapter) WriteServers(servers []*mcp.Server) error

type GeminiConfig

type GeminiConfig struct {
	MCPServers map[string]GeminiServerConfig `json:"mcpServers,omitempty"`
	// Preserve other fields
	Other map[string]interface{} `json:"-"`
}

GeminiConfig represents Gemini's configuration

type GeminiServerConfig

type GeminiServerConfig struct {
	Command   string            `json:"command,omitempty"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	URL       string            `json:"url,omitempty"`
	Transport string            `json:"transport,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

GeminiServerConfig represents a server in Gemini's config format

type JSONConfigHelper added in v0.3.0

type JSONConfigHelper struct {
	// ConfigPath is the path to the JSON config file
	ConfigPath string
}

JSONConfigHelper provides common JSON config file operations with field preservation. Use this for adapters that use JSON config files with mcpServers section.

func NewJSONConfigHelper added in v0.3.0

func NewJSONConfigHelper(configPath string) *JSONConfigHelper

NewJSONConfigHelper creates a new helper for the given config path

func (*JSONConfigHelper) LoadRaw added in v0.3.0

func (h *JSONConfigHelper) LoadRaw() (map[string]interface{}, error)

LoadRaw loads the entire config as a raw map to preserve all fields. Returns an empty map if file doesn't exist.

func (*JSONConfigHelper) SaveRaw added in v0.3.0

func (h *JSONConfigHelper) SaveRaw(raw map[string]interface{}) error

SaveRaw saves the entire config, preserving all fields. Creates the parent directory if it doesn't exist.

type OpenCodeAdapter

type OpenCodeAdapter struct{}

OpenCodeAdapter syncs configuration to OpenCode (opencode.ai)

func (*OpenCodeAdapter) ConfigPath

func (a *OpenCodeAdapter) ConfigPath() string

func (*OpenCodeAdapter) Detect

func (a *OpenCodeAdapter) Detect() (bool, error)

func (*OpenCodeAdapter) Name

func (a *OpenCodeAdapter) Name() string

func (*OpenCodeAdapter) ReadAgents added in v0.3.0

func (a *OpenCodeAdapter) ReadAgents() ([]*agent.Agent, error)

ReadAgents reads agents from OpenCode's agent directory

func (*OpenCodeAdapter) ReadCommands

func (a *OpenCodeAdapter) ReadCommands() ([]*command.Command, error)

func (*OpenCodeAdapter) ReadRules

func (a *OpenCodeAdapter) ReadRules() ([]*rule.Rule, error)

func (*OpenCodeAdapter) ReadServers

func (a *OpenCodeAdapter) ReadServers() ([]*mcp.Server, error)

func (*OpenCodeAdapter) ReadSkills added in v0.3.0

func (a *OpenCodeAdapter) ReadSkills() ([]*skill.Skill, error)

ReadSkills reads skills from OpenCode's skill directory

func (*OpenCodeAdapter) SupportedResources

func (a *OpenCodeAdapter) SupportedResources() []ResourceType

func (*OpenCodeAdapter) WriteAgents added in v0.3.0

func (a *OpenCodeAdapter) WriteAgents(agents []*agent.Agent) error

WriteAgents writes agents to OpenCode's agent directory

func (*OpenCodeAdapter) WriteCommands

func (a *OpenCodeAdapter) WriteCommands(commands []*command.Command) error

func (*OpenCodeAdapter) WriteRules

func (a *OpenCodeAdapter) WriteRules(rules []*rule.Rule) error

func (*OpenCodeAdapter) WriteServers

func (a *OpenCodeAdapter) WriteServers(servers []*mcp.Server) error

func (*OpenCodeAdapter) WriteSkills added in v0.3.0

func (a *OpenCodeAdapter) WriteSkills(skills []*skill.Skill) error

WriteSkills writes skills to OpenCode's skill directory

type OpenCodeServerConfig

type OpenCodeServerConfig struct {
	Type    string            `json:"type"`
	Command []string          `json:"command,omitempty"`
	URL     string            `json:"url,omitempty"`
	Env     map[string]string `json:"env,omitempty"`
	Enabled bool              `json:"enabled"`
}

OpenCodeServerConfig represents a server in OpenCode's config format OpenCode uses a different format than Claude Desktop: - "type": "local" or "remote" - "command": array of strings (command + args combined) - "enabled": boolean - "url": for remote servers Note: OpenCode's schema is strict - no custom fields allowed

type ResourceType

type ResourceType string

ResourceType represents the type of resource being synced

const (
	ResourceMCP      ResourceType = "mcp"
	ResourceCommands ResourceType = "commands"
	ResourceRules    ResourceType = "rules"
	ResourceSkills   ResourceType = "skills"
	ResourceAgents   ResourceType = "agents"
)

type RulesAdapter added in v0.3.0

type RulesAdapter interface {
	Adapter

	// ReadRules reads rule configurations from the tool
	ReadRules() ([]*rule.Rule, error)

	// WriteRules writes rule configurations to the tool
	WriteRules(rules []*rule.Rule) error
}

RulesAdapter is an optional interface for adapters that support rules. Implement this interface if the tool can sync rule configurations.

func AsRulesAdapter added in v0.3.0

func AsRulesAdapter(a Adapter) (RulesAdapter, bool)

AsRulesAdapter returns the adapter as a RulesAdapter if supported

type ServerAdapter added in v0.3.0

type ServerAdapter interface {
	Adapter

	// ReadServers reads MCP server configurations from the tool
	ReadServers() ([]*mcp.Server, error)

	// WriteServers writes MCP server configurations to the tool
	WriteServers(servers []*mcp.Server) error
}

ServerAdapter is an optional interface for adapters that support MCP servers. Implement this interface if the tool can sync MCP server configurations.

func AsServerAdapter added in v0.3.0

func AsServerAdapter(a Adapter) (ServerAdapter, bool)

AsServerAdapter returns the adapter as a ServerAdapter if supported

type SkillsAdapter added in v0.3.0

type SkillsAdapter interface {
	Adapter

	// ReadSkills reads skill configurations from the tool
	ReadSkills() ([]*skill.Skill, error)

	// WriteSkills writes skill configurations to the tool
	// Note: Most tools don't support writing skills programmatically
	// This is optional and may return an error for read-only skill systems
	WriteSkills(skills []*skill.Skill) error
}

SkillsAdapter is an optional interface for adapters that support skills/plugins. Skills are directory-based configurations with SKILL.md files that define slash commands, prompts, and other tool extensions.

func AsSkillsAdapter added in v0.3.0

func AsSkillsAdapter(a Adapter) (SkillsAdapter, bool)

AsSkillsAdapter returns the adapter as a SkillsAdapter if supported

type SyncResult

type SyncResult struct {
	Tool    string
	Success bool
	Error   error
	Changes int // Number of changes made
}

SyncResult represents the result of syncing to a tool

func SyncAll

func SyncAll(servers []*mcp.Server, commands []*command.Command, rules []*rule.Rule, skills []*skill.Skill, agents []*agent.Agent) []SyncResult

SyncAll syncs configuration to all detected tools

type SyncState

type SyncState struct {
	Version int `json:"version"`
	// ManagedServers maps adapter name -> list of server names we manage
	ManagedServers map[string][]string `json:"managedServers"`
}

SyncState tracks which servers are managed by agentctl per adapter This is stored in ~/.config/agentctl/sync-state.json

func LoadState

func LoadState() (*SyncState, error)

LoadState loads the sync state from disk

func (*SyncState) ClearManagedServers

func (s *SyncState) ClearManagedServers(adapterName string)

ClearManagedServers removes all managed servers for an adapter

func (*SyncState) GetManagedServers

func (s *SyncState) GetManagedServers(adapterName string) []string

GetManagedServers returns the list of server names managed for an adapter

func (*SyncState) Save

func (s *SyncState) Save() error

Save saves the sync state to disk

func (*SyncState) SetManagedServers

func (s *SyncState) SetManagedServers(adapterName string, servers []string)

SetManagedServers sets the list of server names managed for an adapter

type WindsurfAdapter

type WindsurfAdapter struct{}

WindsurfAdapter syncs configuration to Windsurf (Codeium)

func (*WindsurfAdapter) ConfigPath

func (a *WindsurfAdapter) ConfigPath() string

func (*WindsurfAdapter) Detect

func (a *WindsurfAdapter) Detect() (bool, error)

func (*WindsurfAdapter) Name

func (a *WindsurfAdapter) Name() string

func (*WindsurfAdapter) ReadRules

func (a *WindsurfAdapter) ReadRules() ([]*rule.Rule, error)

func (*WindsurfAdapter) ReadServers

func (a *WindsurfAdapter) ReadServers() ([]*mcp.Server, error)

func (*WindsurfAdapter) SupportedResources

func (a *WindsurfAdapter) SupportedResources() []ResourceType

func (*WindsurfAdapter) WriteRules

func (a *WindsurfAdapter) WriteRules(rules []*rule.Rule) error

func (*WindsurfAdapter) WriteServers

func (a *WindsurfAdapter) WriteServers(servers []*mcp.Server) error

type WindsurfServerConfig

type WindsurfServerConfig struct {
	Command   string            `json:"command"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

WindsurfServerConfig represents a server in Windsurf's config format

type WorkspaceAdapter

type WorkspaceAdapter interface {
	Adapter

	// SupportsWorkspace returns true if this tool has workspace-level config support
	SupportsWorkspace() bool

	// WorkspaceConfigPath returns the path to the workspace config file for a given project
	WorkspaceConfigPath(projectDir string) string

	// ReadWorkspaceServers reads MCP servers from the workspace config
	ReadWorkspaceServers(projectDir string) ([]*mcp.Server, error)

	// WriteWorkspaceServers writes MCP servers to the workspace config
	WriteWorkspaceServers(projectDir string, servers []*mcp.Server) error
}

WorkspaceAdapter is an optional interface for adapters that support project-level (workspace) configurations in addition to global configs. Tools like Claude Code (.mcp.json) and Cursor (.cursor/mcp.json) support this.

func AsWorkspaceAdapter

func AsWorkspaceAdapter(a Adapter) (WorkspaceAdapter, bool)

AsWorkspaceAdapter returns the adapter as a WorkspaceAdapter if supported

type ZedAdapter

type ZedAdapter struct{}

ZedAdapter syncs configuration to Zed editor

func (*ZedAdapter) ConfigPath

func (a *ZedAdapter) ConfigPath() string

func (*ZedAdapter) Detect

func (a *ZedAdapter) Detect() (bool, error)

func (*ZedAdapter) Name

func (a *ZedAdapter) Name() string

func (*ZedAdapter) ReadCommands

func (a *ZedAdapter) ReadCommands() ([]*command.Command, error)

func (*ZedAdapter) ReadRules

func (a *ZedAdapter) ReadRules() ([]*rule.Rule, error)

func (*ZedAdapter) ReadServers

func (a *ZedAdapter) ReadServers() ([]*mcp.Server, error)

func (*ZedAdapter) SupportedResources

func (a *ZedAdapter) SupportedResources() []ResourceType

func (*ZedAdapter) WriteCommands

func (a *ZedAdapter) WriteCommands(commands []*command.Command) error

func (*ZedAdapter) WriteRules

func (a *ZedAdapter) WriteRules(rules []*rule.Rule) error

func (*ZedAdapter) WriteServers

func (a *ZedAdapter) WriteServers(servers []*mcp.Server) error

type ZedServerConfig

type ZedServerConfig struct {
	Command   string            `json:"command"`
	Args      []string          `json:"args,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	ManagedBy string            `json:"_managedBy,omitempty"`
}

ZedServerConfig represents a server in Zed's config format

Jump to

Keyboard shortcuts

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