Documentation
¶
Index ¶
- Constants
- func AllClientIDs() []string
- func DetectAssetType(path string, content []byte) *asset.Type
- func DetectClientFromContent(path string, content []byte) (Client, *RuleCapabilities)
- func DetectClientFromPath(path string) (Client, *RuleCapabilities)
- func HasAnyErrors(results map[string]InstallResponse) bool
- func IsImportableFile(path string) bool
- func IsInstructionFile(path string) bool
- func IsRuleFile(path string) bool
- func IsValidClientID(id string) bool
- func Register(client Client)
- type AssetBundle
- type AssetResult
- type BaseClient
- type Client
- type InstallOptions
- type InstallRequest
- type InstallResponse
- type InstallScope
- type InstalledAsset
- type InstalledSkill
- type Orchestrator
- type ParsedRule
- type Registry
- func (r *Registry) DetectAssetType(path string, content []byte) *asset.Type
- func (r *Registry) DetectClientFromContent(path string, content []byte) (Client, *RuleCapabilities)
- func (r *Registry) DetectClientFromPath(path string) (Client, *RuleCapabilities)
- func (r *Registry) DetectInstalled() []Client
- func (r *Registry) FilterByAssetType(assetType asset.Type) []Client
- func (r *Registry) Get(id string) (Client, error)
- func (r *Registry) GetAll() []Client
- func (r *Registry) GetInstructionFiles() []string
- func (r *Registry) GetRulesDirectories() []string
- func (r *Registry) IsImportableFile(path string) bool
- func (r *Registry) IsInstructionFile(path string) bool
- func (r *Registry) IsRuleContent(path string, content []byte) bool
- func (r *Registry) IsRuleFile(path string) bool
- func (r *Registry) ParseRuleFile(path string, content []byte) (*ParsedRule, error)
- func (r *Registry) Register(client Client)
- type ResultStatus
- type RuleCapabilities
- type ScopeType
- type SkillContent
- type UninstallOptions
- type UninstallRequest
- type UninstallResponse
- type VerifyResult
Constants ¶
const ( ClientIDClaudeCode = "claude-code" ClientIDCursor = "cursor" )
ClientID constants for supported AI coding clients
Variables ¶
This section is empty.
Functions ¶
func AllClientIDs ¶ added in v0.5.4
func AllClientIDs() []string
AllClientIDs returns all known client IDs
func DetectAssetType ¶ added in v0.9.0
DetectAssetType uses the global registry
func DetectClientFromContent ¶ added in v0.9.0
func DetectClientFromContent(path string, content []byte) (Client, *RuleCapabilities)
DetectClientFromContent uses the global registry
func DetectClientFromPath ¶ added in v0.9.0
func DetectClientFromPath(path string) (Client, *RuleCapabilities)
DetectClientFromPath uses the global registry
func HasAnyErrors ¶
func HasAnyErrors(results map[string]InstallResponse) bool
HasAnyErrors checks if any client installation failed
func IsImportableFile ¶ added in v0.9.0
IsImportableFile uses the global registry
func IsInstructionFile ¶ added in v0.9.0
IsInstructionFile uses the global registry
func IsRuleFile ¶ added in v0.9.0
IsRuleFile uses the global registry
func IsValidClientID ¶ added in v0.5.4
IsValidClientID checks if the given ID is a known client ID
Types ¶
type AssetBundle ¶
AssetBundle contains asset + metadata + zip data
type AssetResult ¶
type AssetResult struct {
AssetName string
Status ResultStatus
Message string
Error error
}
AssetResult represents the result of installing/uninstalling one asset
type BaseClient ¶
type BaseClient struct {
// contains filtered or unexported fields
}
BaseClient provides default implementations for common functionality
func NewBaseClient ¶
func NewBaseClient(id, displayName string, supportedTypes []asset.Type) BaseClient
NewBaseClient creates a new base client with capabilities
func (*BaseClient) DisplayName ¶
func (b *BaseClient) DisplayName() string
func (*BaseClient) ID ¶
func (b *BaseClient) ID() string
func (*BaseClient) RuleCapabilities ¶ added in v0.9.0
func (b *BaseClient) RuleCapabilities() *RuleCapabilities
RuleCapabilities returns nil by default - clients override this if they support rules
func (*BaseClient) SupportsAssetType ¶
func (b *BaseClient) SupportsAssetType(assetType asset.Type) bool
type Client ¶
type Client interface {
// Identity
ID() string // Machine name: "claude-code", "cursor", "cline"
DisplayName() string // Human name: "Claude Code", "Cursor", "Cline"
// Detection
IsInstalled() bool // Check if this client is installed/configured
GetVersion() string // Get client version (empty if not available)
// Capabilities - what asset types this client supports
SupportsAssetType(assetType asset.Type) bool
// Installation - client has FULL control over installation mechanism
// Receives all assets to install at once (batch)
InstallAssets(ctx context.Context, req InstallRequest) (InstallResponse, error)
// Uninstallation - remove assets
UninstallAssets(ctx context.Context, req UninstallRequest) (UninstallResponse, error)
// Asset operations - for MCP server support
// ListAssets returns all installed assets for a given scope
ListAssets(ctx context.Context, scope *InstallScope) ([]InstalledSkill, error)
// ReadSkill reads the content of a specific skill by name
ReadSkill(ctx context.Context, name string, scope *InstallScope) (*SkillContent, error)
// EnsureAssetSupport ensures asset infrastructure is set up for the current context.
// This is called after installation to ensure rules files, MCP servers, etc. are configured.
// For Cursor, this creates local .cursor/rules/skills.md with skills from all applicable scopes.
// Clients that don't need post-install setup can return nil.
EnsureAssetSupport(ctx context.Context, scope *InstallScope) error
// GetBootstrapOptions returns bootstrap options provided by this client.
// These are options for hooks, MCP servers, or other infrastructure the client provides.
GetBootstrapOptions(ctx context.Context) []bootstrap.Option
// InstallBootstrap installs client infrastructure (hooks, MCP servers, etc.).
// This sets up hooks for auto-update/usage tracking and registers the sx MCP server.
// Called during installation to ensure all client infrastructure is in place.
// The opts parameter contains only the enabled bootstrap options to install.
// Clients that don't need bootstrap can return nil.
InstallBootstrap(ctx context.Context, opts []bootstrap.Option) error
// UninstallBootstrap removes client infrastructure installed by InstallBootstrap.
// This removes hooks and unregisters the sx MCP server.
// Called during full uninstall (--all flag) to clean up system infrastructure.
// The opts parameter contains only the bootstrap options to uninstall.
// Clients that don't need bootstrap can return nil.
UninstallBootstrap(ctx context.Context, opts []bootstrap.Option) error
// ShouldInstall checks if installation should proceed in hook mode.
// Returns true to proceed, false to skip.
// Called before any installation work begins.
// For clients like Cursor that fire hooks on every prompt, this enables
// tracking conversation IDs to only run install once per conversation.
ShouldInstall(ctx context.Context) (bool, error)
// VerifyAssets checks if assets are actually installed (not just tracked).
// Used by --repair mode to detect discrepancies between tracker and filesystem.
// Each client implements verification according to its own installation structure.
VerifyAssets(ctx context.Context, assets []*lockfile.Asset, scope *InstallScope) []VerifyResult
// ScanInstalledAssets scans for all installed assets of supported types.
// Used during init to detect existing assets that could be imported into the vault.
ScanInstalledAssets(ctx context.Context, scope *InstallScope) ([]InstalledAsset, error)
// GetAssetPath returns the filesystem path to an installed asset.
// Used during import to pass the asset directory to the add command.
// Returns an error for asset types that don't have a simple directory structure.
GetAssetPath(ctx context.Context, name string, assetType asset.Type, scope *InstallScope) (string, error)
// RuleCapabilities returns this client's capabilities for handling rules.
// Returns nil if the client doesn't support rules.
RuleCapabilities() *RuleCapabilities
}
Client represents an AI coding client that can have assets installed
type InstallOptions ¶
type InstallOptions struct {
Force bool // Force reinstall even if already installed
DryRun bool // Don't actually install, just validate
Verbose bool // Verbose output
}
InstallOptions contains optional installation settings
type InstallRequest ¶
type InstallRequest struct {
Assets []*AssetBundle // All assets to install (batch)
Scope *InstallScope // Where to install (global/repo/path)
Options InstallOptions // Additional options
}
InstallRequest contains everything needed for installation
type InstallResponse ¶
type InstallResponse struct {
Results []AssetResult
}
InstallResponse contains results per asset
type InstallScope ¶
type InstallScope struct {
Type ScopeType // Global, Repository, Path
RepoRoot string // Repository root (if applicable)
RepoURL string // Repository URL (if applicable)
Path string // Specific path within repo (if applicable)
}
InstallScope defines where assets should be installed
type InstalledAsset ¶ added in v0.5.4
type InstalledAsset struct {
Name string // Asset name
Description string // Asset description from metadata
Version string // Asset version
Type asset.Type // Asset type (skill, command, agent, etc.)
}
InstalledAsset represents any asset that has been installed in a client
type InstalledSkill ¶
type InstalledSkill struct {
Name string // Skill name
Description string // Skill description from metadata
Version string // Skill version
}
InstalledSkill represents a skill that has been installed
type Orchestrator ¶
type Orchestrator struct {
// contains filtered or unexported fields
}
Orchestrator coordinates installation across multiple clients
func NewOrchestrator ¶
func NewOrchestrator(registry *Registry) *Orchestrator
NewOrchestrator creates a new installation orchestrator
func (*Orchestrator) InstallToAll ¶
func (o *Orchestrator) InstallToAll(ctx context.Context, assets []*AssetBundle, scope *InstallScope, options InstallOptions) map[string]InstallResponse
InstallToAll installs assets to all detected clients concurrently
func (*Orchestrator) InstallToClients ¶
func (o *Orchestrator) InstallToClients(ctx context.Context, assets []*AssetBundle, scope *InstallScope, options InstallOptions, targetClients []Client) map[string]InstallResponse
InstallToClients installs assets to specific clients concurrently
type ParsedRule ¶ added in v0.9.0
type ParsedRule struct {
// Globs are the file patterns this rule applies to.
// This is the canonical format - clients may call this "paths", "globs", or "applyTo".
Globs []string
// Description is a short description of the rule.
Description string
// ClientFields contains client-specific fields that don't have a canonical equivalent.
// For example, Cursor's "alwaysApply" field.
ClientFields map[string]any
// ClientName is the name of the client that parsed this rule.
// Empty if no client was detected.
ClientName string
// Content is the clean markdown content without frontmatter.
Content string
}
ParsedRule is the canonical format returned by all client rule parsers. When a rule file is parsed, the client-specific frontmatter is converted to this common format, which can then be transformed back to client-specific format during installation.
func ParseRuleFile ¶ added in v0.9.0
func ParseRuleFile(path string, content []byte) (*ParsedRule, error)
ParseRuleFile uses the global registry
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds all registered clients
func (*Registry) DetectAssetType ¶ added in v0.9.0
DetectAssetType asks clients to determine the asset type for a path. If no client claims it, falls back to generic path/content detection.
func (*Registry) DetectClientFromContent ¶ added in v0.9.0
func (r *Registry) DetectClientFromContent(path string, content []byte) (Client, *RuleCapabilities)
DetectClientFromContent asks each client if it recognizes this content. Returns the client and its capabilities, or nil if no client matches.
func (*Registry) DetectClientFromPath ¶ added in v0.9.0
func (r *Registry) DetectClientFromPath(path string) (Client, *RuleCapabilities)
DetectClientFromPath asks each client if it owns this path. Returns the client and its capabilities, or nil if no client matches.
func (*Registry) DetectInstalled ¶
DetectInstalled returns all clients detected as installed
func (*Registry) FilterByAssetType ¶
FilterByAssetType returns clients that support the given asset type
func (*Registry) GetInstructionFiles ¶ added in v0.9.0
GetInstructionFiles returns all instruction files from all clients.
func (*Registry) GetRulesDirectories ¶ added in v0.9.0
GetRulesDirectories returns all registered rules directories.
func (*Registry) IsImportableFile ¶ added in v0.9.0
IsImportableFile checks if path can be imported as rules. This includes both rule files (e.g., .claude/rules/my-rule.md) and instruction files (e.g., CLAUDE.md).
func (*Registry) IsInstructionFile ¶ added in v0.9.0
IsInstructionFile checks if path matches any client's instruction files. Instruction files are files like CLAUDE.md or AGENTS.md that can contain multiple rule sections.
func (*Registry) IsRuleContent ¶ added in v0.9.0
IsRuleContent checks if any client recognizes this content as a rule.
func (*Registry) IsRuleFile ¶ added in v0.9.0
IsRuleFile checks if any client recognizes this path as a rule file.
func (*Registry) ParseRuleFile ¶ added in v0.9.0
func (r *Registry) ParseRuleFile(path string, content []byte) (*ParsedRule, error)
ParseRuleFile finds the right client and parses the content. If no client is detected, returns the raw content as a ParsedRule.
type ResultStatus ¶
type ResultStatus string
const ( StatusSuccess ResultStatus = "success" StatusFailed ResultStatus = "failed" StatusSkipped ResultStatus = "skipped" )
type RuleCapabilities ¶ added in v0.9.0
type RuleCapabilities struct {
// ClientName is the identifier for this client (e.g., "claude-code", "cursor")
ClientName string
// RulesDirectory is where rules are stored (e.g., ".claude/rules", ".cursor/rules")
RulesDirectory string
// FileExtension is the file extension for rules (e.g., ".md", ".mdc")
FileExtension string
// InstructionFiles are files that can be parsed for rule sections (e.g., "CLAUDE.md", "AGENTS.md")
InstructionFiles []string
// MatchesPath checks if a path belongs to this client's rules
MatchesPath func(path string) bool
// MatchesContent checks if content appears to belong to this client
MatchesContent func(path string, content []byte) bool
// ParseRuleFile parses a rule file and returns the canonical format
ParseRuleFile func(content []byte) (*ParsedRule, error)
// GenerateRuleFile creates a complete rule file for this client
GenerateRuleFile func(cfg *metadata.RuleConfig, body string) []byte
// DetectAssetType determines what type of asset this file is.
// Returns nil if the client doesn't recognize the file.
// content may be nil if the file hasn't been read yet.
DetectAssetType func(path string, content []byte) *asset.Type
}
RuleCapabilities defines what a client supports for rules. Each client registers its capabilities to enable detection, parsing, and generation.
type SkillContent ¶
type SkillContent struct {
Name string // Skill name
Description string // Skill description from metadata
Version string // Skill version from metadata
Content string // Contents of SKILL.md (or configured prompt file)
BaseDir string // Directory where skill is installed (for resolving @ file references)
}
SkillContent contains the full content of a skill for MCP responses
type UninstallOptions ¶
type UninstallRequest ¶
type UninstallRequest struct {
Assets []asset.Asset
Scope *InstallScope
Options UninstallOptions
}
UninstallRequest contains assets to uninstall
type UninstallResponse ¶
type UninstallResponse struct {
Results []AssetResult
}
UninstallResponse contains results per asset
type VerifyResult ¶
type VerifyResult struct {
Asset *lockfile.Asset // The asset that was verified
Installed bool // Whether the asset is actually installed correctly
Message string // Details about what was found or missing
}
VerifyResult represents the result of verifying a single asset's installation