Documentation
¶
Index ¶
- Constants
- Variables
- func AddInstruction(configPath, path string) error
- func AddMCPServer(configPath, name string, entry map[string]any) error
- func ConfigFilePath(dir string) string
- func MCPServerEntryFromBootstrap(cfg *bootstrap.MCPServerConfig) map[string]any
- func RemoveInstruction(configPath, path string) error
- func RemoveMCPServer(configPath, name string) error
- func WriteOpenCodeConfig(path string, config *OpenCodeConfig) error
- type AgentHandler
- type CommandHandler
- type Handler
- type MCPHandler
- type OpenCodeConfig
- type RuleHandler
- type SkillHandler
Constants ¶
const ( // GlobalConfigDir is the OpenCode global config directory, relative to home. GlobalConfigDir = ".config/opencode" // ProjectConfigDir is the OpenCode project-scoped config directory. ProjectConfigDir = ".opencode" // ConfigFile is the OpenCode config filename (lives at the root of // either GlobalConfigDir or the project). OpenCode also accepts a // JSONC variant — use ConfigFilePath to pick whichever exists on // disk rather than joining this constant directly. ConfigFile = "opencode.json" // ConfigFileJSONC is the JSONC variant OpenCode also accepts. ConfigFileJSONC = "opencode.jsonc" )
Configuration directories for OpenCode.
const ( DirSkills = "skills" DirCommands = "commands" DirAgents = "agent" DirRules = "rules" DirMCPServers = "mcp-servers" )
Asset subdirectory names under an OpenCode config directory.
const ( DefaultSkillPromptFile = "SKILL.md" DefaultCommandPromptFile = "COMMAND.md" DefaultAgentPromptFile = "AGENT.md" DefaultRulePromptFile = "RULE.md" )
Default prompt filenames.
Variables ¶
var SkillOps = dirasset.NewOperations(DirSkills, &asset.TypeSkill)
SkillOps provides directory-based operations for OpenCode skills. OpenCode discovers skills natively from <config>/skills/<name>/SKILL.md.
Functions ¶
func AddInstruction ¶
AddInstruction appends path to opencode.json's `instructions` array if it isn't already present. If the path is already registered, the config file is left untouched (no $schema injection, no key reordering) so repeated no-op installs don't churn the user's file.
func AddMCPServer ¶
AddMCPServer adds or updates an entry in opencode.json under the mcp key.
func ConfigFilePath ¶
ConfigFilePath returns the opencode config path to read or write under dir. If only opencode.jsonc exists (a supported OpenCode variant), that path is returned so sx doesn't silently create a second opencode.json next to the user's existing config. Otherwise it returns the .json path — which is also the path used when neither file exists yet.
func MCPServerEntryFromBootstrap ¶
func MCPServerEntryFromBootstrap(cfg *bootstrap.MCPServerConfig) map[string]any
MCPServerEntryFromBootstrap renders a bootstrap.MCPServerConfig into the JSON shape OpenCode expects under the `mcp.<name>` key. Bootstrap MCPs are always local processes (bootstrap doesn't model remote URLs).
func RemoveInstruction ¶
RemoveInstruction removes path from opencode.json's `instructions` array. If the config file doesn't exist or the path isn't registered, this is a no-op and the file is left untouched.
func RemoveMCPServer ¶
RemoveMCPServer removes the named entry from opencode.json. If the config file doesn't exist or the entry isn't there, this is a no-op and the file is left untouched — so a stray uninstall doesn't materialize a config or rewrite an existing one just to inject $schema / reorder keys.
func WriteOpenCodeConfig ¶
func WriteOpenCodeConfig(path string, config *OpenCodeConfig) error
WriteOpenCodeConfig writes opencode.json, preserving unknown fields and adding the $schema reference if it isn't already present. Top-level keys are written in a stable order — $schema first, then instructions, then mcp, then any remaining preserved keys sorted alphabetically — so repeated installs/uninstalls don't churn the file's git diff.
Types ¶
type AgentHandler ¶
type AgentHandler struct {
// contains filtered or unexported fields
}
AgentHandler installs OpenCode agents as markdown files. OpenCode loads agents from <config>/agent/<name>.md (and also from the plural `agents/` directory, but agent/ is canonical per the built-in customize-opencode skill).
func NewAgentHandler ¶
func NewAgentHandler(meta *metadata.Metadata) *AgentHandler
NewAgentHandler creates a new OpenCode agent handler.
func (*AgentHandler) Install ¶
Install writes the agent markdown file to <targetBase>/agent/<name>.md.
func (*AgentHandler) Remove ¶
func (h *AgentHandler) Remove(ctx context.Context, targetBase string) error
Remove deletes the agent markdown file from <targetBase>/agent/.
func (*AgentHandler) VerifyInstalled ¶
func (h *AgentHandler) VerifyInstalled(targetBase string) (bool, string)
VerifyInstalled returns whether the agent markdown file exists.
type CommandHandler ¶
type CommandHandler struct {
// contains filtered or unexported fields
}
CommandHandler installs custom slash commands into OpenCode. OpenCode loads commands as markdown files from <config>/commands/<name>.md.
func NewCommandHandler ¶
func NewCommandHandler(meta *metadata.Metadata) *CommandHandler
NewCommandHandler creates a new OpenCode command handler.
func (*CommandHandler) Install ¶
Install writes the command markdown file to <targetBase>/commands/<name>.md.
func (*CommandHandler) Remove ¶
func (h *CommandHandler) Remove(ctx context.Context, targetBase string) error
Remove deletes the command markdown file from <targetBase>/commands/.
func (*CommandHandler) VerifyInstalled ¶
func (h *CommandHandler) VerifyInstalled(targetBase string) (bool, string)
VerifyInstalled returns whether the command markdown file exists.
type Handler ¶
type Handler interface {
Install(ctx context.Context, zipData []byte, targetBase string) error
Remove(ctx context.Context, targetBase string) error
VerifyInstalled(targetBase string) (bool, string)
}
Handler is the interface implemented by all OpenCode asset handlers.
func NewHandler ¶
NewHandler returns the appropriate handler for the given asset type. The rule handler is constructed with an empty register path here because this constructor is used by verify, which only checks file presence. Use NewRuleHandler directly with a register path for install/remove.
type MCPHandler ¶
type MCPHandler struct {
// contains filtered or unexported fields
}
MCPHandler installs MCP server entries into OpenCode's opencode.json. Packaged servers extract files into <targetBase>/mcp-servers/<name>/ and register an absolute-path command; config-only servers only modify the JSON config.
func NewMCPHandler ¶
func NewMCPHandler(meta *metadata.Metadata) *MCPHandler
NewMCPHandler creates a new MCP handler.
func (*MCPHandler) Install ¶
Install registers the MCP server in opencode.json, extracting files first for packaged servers.
func (*MCPHandler) Remove ¶
func (h *MCPHandler) Remove(ctx context.Context, targetBase string) error
Remove removes the MCP entry from opencode.json and cleans up any extracted packaged-server files.
func (*MCPHandler) VerifyInstalled ¶
func (h *MCPHandler) VerifyInstalled(targetBase string) (bool, string)
VerifyInstalled reports whether the MCP server is registered (and, for packaged servers, whether the extracted directory is on disk).
type OpenCodeConfig ¶
OpenCodeConfig is a minimal view of opencode.json that we care about. Unknown top-level fields are preserved in Other so writes don't drop them. WriteOpenCodeConfig also injects a `$schema` reference if the config doesn't already have one, so newly-materialized files are valid against the OpenCode JSON schema out of the box.
func ReadOpenCodeConfig ¶
func ReadOpenCodeConfig(path string) (*OpenCodeConfig, error)
ReadOpenCodeConfig reads opencode.json (or returns an empty config if the file doesn't exist yet). Supports JSONC. If the file is present but the top-level `mcp` or `instructions` keys carry the wrong JSON type (e.g. a string where an object/array is expected), this returns a typed error rather than silently dropping the value — otherwise the next WriteOpenCodeConfig would clobber the user's data without warning. A JSON null at either key is treated as absent (the JSON convention).
type RuleHandler ¶
type RuleHandler struct {
// contains filtered or unexported fields
}
RuleHandler installs rules into OpenCode. OpenCode reads rule files through the top-level `instructions` array in opencode.json, so a rule install both materializes the markdown content at <config>/rules/<name>.md and registers that path in opencode.json. Repo-scoped installs register a path relative to the project root; global installs register an absolute path under ~/.config/opencode.
func NewRuleHandler ¶
func NewRuleHandler(meta *metadata.Metadata, registerPath string) *RuleHandler
NewRuleHandler creates a new OpenCode rule handler. registerPath is the string that should be written into opencode.json's `instructions` array; pass the absolute path for global installs or a path relative to the config file's directory for project installs.
func (*RuleHandler) Install ¶
Install writes the rule markdown to <targetBase>/rules/<name>.md and adds the configured registerPath to opencode.json's instructions array.
func (*RuleHandler) Remove ¶
func (h *RuleHandler) Remove(ctx context.Context, targetBase string) error
Remove deletes the rule file and unregisters its instructions entry.
func (*RuleHandler) VerifyInstalled ¶
func (h *RuleHandler) VerifyInstalled(targetBase string) (bool, string)
VerifyInstalled returns whether the rule file exists on disk. We don't also check the instructions registration because the verify caller may not know the exact register path the original install used (absolute vs. relative depends on scope at install time), but the file's presence under <config>/rules/<name>.md is a stable signal owned by sx.
type SkillHandler ¶
type SkillHandler struct {
// contains filtered or unexported fields
}
SkillHandler installs skills into an OpenCode config directory.
func NewSkillHandler ¶
func NewSkillHandler(meta *metadata.Metadata) *SkillHandler
NewSkillHandler creates a new OpenCode skill handler.
func (*SkillHandler) Remove ¶
func (h *SkillHandler) Remove(ctx context.Context, targetBase string) error
Remove deletes the skill directory.
func (*SkillHandler) VerifyInstalled ¶
func (h *SkillHandler) VerifyInstalled(targetBase string) (bool, string)
VerifyInstalled checks if the skill is installed with the expected version.