Documentation
¶
Overview ¶
Package providers implements the interface-driven provider architecture for AI CLI/IDE/Orchestrator tools.
Overview ¶
This package defines the Provider interface that all AI CLI tools (Claude Code, Gemini CLI, Cline, Cursor, etc.) must implement.
Each provider handles both its instruction file (e.g., CLAUDE.md) and slash commands (e.g., .claude/commands/) in a single implementation.
Adding a New Provider ¶
To add a new AI CLI provider, create a new file (e.g., providers/mytools.go) with:
Example:
package providers
func init() {
Register(&MyToolProvider{})
}
type MyToolProvider struct {
BaseProvider
}
func NewMyToolProvider() *MyToolProvider {
proposalPath, applyPath := StandardCommandPaths(
".mytool/commands", ".md",
)
return &MyToolProvider{
BaseProvider: BaseProvider{
id: "mytool",
name: "MyTool",
priority: 100,
// Empty if no instruction file
configFile: "MYTOOL.md",
// Empty if no slash commands
proposalPath: proposalPath,
applyPath: applyPath,
commandFormat: FormatMarkdown,
frontmatter: map[string]string{
"proposal":
"---\ndescription: Scaffold a new Spectr change.\n---",
"apply":
"---\ndescription: Implement an \n---",
},
},
}
}
The BaseProvider handles all common logic. Override Configure() only for special formats.
Index ¶
- Constants
- Variables
- func Count() int
- func EnsureDir(path string) error
- func FileExists(path string) bool
- func IDs() []string
- func PrefixedCommandPaths(dir, ext string) (proposalPath, applyPath string)
- func Register(p Provider)
- func Reset()
- func StandardCommandPaths(dir, ext string) (proposalPath, applyPath string)
- func StandardFrontmatter() map[string]string
- func UpdateFileWithMarkers(filePath, content, startMarker, endMarker string) error
- type AiderProvider
- type AntigravityProvider
- type BaseProvider
- func (p *BaseProvider) CommandFormat() CommandFormat
- func (p *BaseProvider) ConfigFile() string
- func (p *BaseProvider) Configure(projectPath, _ string, tm TemplateRenderer) error
- func (p *BaseProvider) GetApplyCommandPath() string
- func (p *BaseProvider) GetFilePaths() []string
- func (p *BaseProvider) GetProposalCommandPath() string
- func (p *BaseProvider) HasConfigFile() bool
- func (p *BaseProvider) HasSlashCommands() bool
- func (p *BaseProvider) ID() string
- func (p *BaseProvider) IsConfigured(projectPath string) bool
- func (p *BaseProvider) Name() string
- func (p *BaseProvider) Priority() int
- type ClaudeProvider
- type ClineProvider
- type CodeBuddyProvider
- type CodexProvider
- type CommandFormat
- type ContinueProvider
- type CostrictProvider
- type CrushProvider
- type CursorProvider
- type GeminiProvider
- type KilocodeProvider
- type OpencodeProvider
- type Provider
- type QoderProvider
- type QwenProvider
- type Registry
- type TabnineProvider
- type TemplateContext
- type TemplateRenderer
- type WindsurfProvider
Constants ¶
const ( PriorityClaudeCode = 1 PriorityGemini = 2 PriorityCostrict = 3 PriorityQoder = 4 PriorityCodeBuddy = 5 PriorityQwen = 6 PriorityAntigravity = 7 PriorityCline = 8 PriorityCursor = 9 PriorityCodex = 10 PriorityAider = 11 PriorityTabnine = 12 PriorityWindsurf = 13 PriorityKilocode = 14 PriorityContinue = 15 PriorityCrush = 16 PriorityOpencode = 17 )
Priority constants for all providers. Lower numbers = higher priority (displayed first).
const ( // Marker constants for managing config file updates. SpectrStartMarker = "<!-- spectr:START -->" SpectrEndMarker = "<!-- spectr:END -->" )
Variables ¶
var ( // FrontmatterProposal is the YAML frontmatter for proposal commands. FrontmatterProposal = `--- description: Scaffold a new Spectr change and validate strictly. ---` // FrontmatterApply is the YAML frontmatter for apply commands. FrontmatterApply = `--- description: Implement an approved Spectr change and keep tasks in sync. ---` )
default frontmatter templates for slash commands.
Functions ¶
func FileExists ¶
FileExists checks if a file or directory exists.
func PrefixedCommandPaths ¶
PrefixedCommandPaths returns command paths using a flat prefix pattern. Uses flat structure: {dir}/spectr-{command}{ext} Example: ".agent/workflows", ".md" -> ".agent/workflows/spectr-proposal.md" Returns proposalPath, applyPath.
func Register ¶
func Register(p Provider)
Register adds a provider to the global registry. This is typically called from init() in each provider file. Panics if a provider with the same ID is already registered.
func StandardCommandPaths ¶
StandardCommandPaths returns the standard command paths for a given directory and extension. Uses subdirectory structure: {dir}/spectr/{command}{ext} Example: ".claude/commands", ".md" -> ".claude/commands/spectr/proposal.md" Returns proposalPath, applyPath.
func StandardFrontmatter ¶
StandardFrontmatter returns the standard frontmatter map for most providers.
func UpdateFileWithMarkers ¶
UpdateFileWithMarkers updates content between markers in a file, or creates the file with markers if it doesn't exist.
Types ¶
type AiderProvider ¶
type AiderProvider struct {
BaseProvider
}
AiderProvider implements the Provider interface for Aider. Aider uses .aider/commands/ for slash commands (no config file).
func NewAiderProvider ¶
func NewAiderProvider() *AiderProvider
NewAiderProvider creates a new Aider provider.
type AntigravityProvider ¶
type AntigravityProvider struct {
BaseProvider
}
AntigravityProvider implements the Provider interface for Antigravity.
Antigravity uses AGENTS.md and .agent/workflows/ for slash commands.
func NewAntigravityProvider ¶
func NewAntigravityProvider() *AntigravityProvider
NewAntigravityProvider creates a new Antigravity provider.
type BaseProvider ¶
type BaseProvider struct {
// contains filtered or unexported fields
}
BaseProvider provides a default implementation of the Provider interface. Embed this in your provider struct for common functionality.
func (*BaseProvider) CommandFormat ¶
func (p *BaseProvider) CommandFormat() CommandFormat
CommandFormat returns the command file format.
func (*BaseProvider) ConfigFile ¶
func (p *BaseProvider) ConfigFile() string
ConfigFile returns the instruction file path.
func (*BaseProvider) Configure ¶
func (p *BaseProvider) Configure( projectPath, _ string, tm TemplateRenderer, ) error
Configure applies all configuration for the provider.
func (*BaseProvider) GetApplyCommandPath ¶
func (p *BaseProvider) GetApplyCommandPath() string
GetApplyCommandPath returns the relative path for the apply command.
func (*BaseProvider) GetFilePaths ¶
func (p *BaseProvider) GetFilePaths() []string
GetFilePaths returns the file paths that this provider creates/updates.
func (*BaseProvider) GetProposalCommandPath ¶
func (p *BaseProvider) GetProposalCommandPath() string
GetProposalCommandPath returns the relative path for the proposal command.
func (*BaseProvider) HasConfigFile ¶
func (p *BaseProvider) HasConfigFile() bool
HasConfigFile returns true if this provider has an instruction file.
func (*BaseProvider) HasSlashCommands ¶
func (p *BaseProvider) HasSlashCommands() bool
HasSlashCommands returns true if this provider has slash commands.
func (*BaseProvider) IsConfigured ¶
func (p *BaseProvider) IsConfigured( projectPath string, ) bool
IsConfigured checks if the provider is fully configured.
func (*BaseProvider) Name ¶
func (p *BaseProvider) Name() string
Name returns the human-readable name.
func (*BaseProvider) Priority ¶
func (p *BaseProvider) Priority() int
Priority returns the display order.
type ClaudeProvider ¶
type ClaudeProvider struct {
BaseProvider
}
ClaudeProvider implements the Provider interface for Claude Code. Claude Code uses CLAUDE.md and .claude/commands/ for slash commands.
func NewClaudeProvider ¶
func NewClaudeProvider() *ClaudeProvider
NewClaudeProvider creates a new Claude Code provider.
type ClineProvider ¶
type ClineProvider struct {
BaseProvider
}
ClineProvider implements the Provider interface for Cline. Cline uses CLINE.md and .clinerules/commands/ for slash commands.
func NewClineProvider ¶
func NewClineProvider() *ClineProvider
NewClineProvider creates a new Cline provider.
type CodeBuddyProvider ¶
type CodeBuddyProvider struct {
BaseProvider
}
CodeBuddyProvider implements the Provider interface for CodeBuddy. CodeBuddy uses CODEBUDDY.md and .codebuddy/commands/ for slash commands.
func NewCodeBuddyProvider ¶
func NewCodeBuddyProvider() *CodeBuddyProvider
NewCodeBuddyProvider creates a new CodeBuddy provider.
type CodexProvider ¶
type CodexProvider struct {
BaseProvider
}
CodexProvider implements the Provider interface for Codex CLI. Codex uses AGENTS.md and global ~/.codex/prompts/spectr/ for commands.
func NewCodexProvider ¶
func NewCodexProvider() *CodexProvider
NewCodexProvider creates a new Codex CLI provider.
type CommandFormat ¶
type CommandFormat int
CommandFormat specifies the format for slash command files.
const ( // FormatMarkdown uses markdown files with // YAML frontmatter (Claude, Cline, etc.) FormatMarkdown CommandFormat = iota // FormatTOML uses TOML files (Gemini CLI) FormatTOML )
type ContinueProvider ¶
type ContinueProvider struct {
BaseProvider
}
ContinueProvider implements the Provider interface for Continue. Continue uses .continue/commands/ for slash commands (no config file).
func NewContinueProvider ¶
func NewContinueProvider() *ContinueProvider
NewContinueProvider creates a new Continue provider.
type CostrictProvider ¶
type CostrictProvider struct {
BaseProvider
}
CostrictProvider implements the Provider interface for CoStrict. CoStrict uses COSTRICT.md and .costrict/commands/ for slash commands.
func NewCostrictProvider ¶
func NewCostrictProvider() *CostrictProvider
NewCostrictProvider creates a new CoStrict provider.
type CrushProvider ¶ added in v0.0.8
type CrushProvider struct {
BaseProvider
}
CrushProvider implements the Provider interface for Crush. Crush uses CRUSH.md for instructions and .crush/commands/ for slash commands.
func NewCrushProvider ¶ added in v0.0.8
func NewCrushProvider() *CrushProvider
NewCrushProvider creates a new Crush provider.
type CursorProvider ¶
type CursorProvider struct {
BaseProvider
}
CursorProvider implements the Provider interface for Cursor. Cursor uses .cursorrules/commands/ for slash commands (no config file).
func NewCursorProvider ¶
func NewCursorProvider() *CursorProvider
NewCursorProvider creates a new Cursor provider.
type GeminiProvider ¶
type GeminiProvider struct {
BaseProvider
}
GeminiProvider implements the Provider interface for Gemini CLI. Gemini uses ~/.gemini/commands/ for TOML-based slash commands (no instruction file).
func NewGeminiProvider ¶
func NewGeminiProvider() *GeminiProvider
NewGeminiProvider creates a new Gemini CLI provider.
func (*GeminiProvider) Configure ¶
func (p *GeminiProvider) Configure( projectPath, _ string, tm TemplateRenderer, ) error
Configure overrides BaseProvider.Configure to generate TOML files instead of markdown.
type KilocodeProvider ¶
type KilocodeProvider struct {
BaseProvider
}
KilocodeProvider implements the Provider interface for Kilocode. Kilocode uses .kilocode/commands/ for slash commands (no config file).
func NewKilocodeProvider ¶
func NewKilocodeProvider() *KilocodeProvider
NewKilocodeProvider creates a new Kilocode provider.
type OpencodeProvider ¶ added in v0.0.8
type OpencodeProvider struct {
BaseProvider
}
OpencodeProvider implements the Provider interface for OpenCode. OpenCode uses .opencode/command/spectr/ for slash commands. It has no instruction file as it uses JSON configuration.
func NewOpencodeProvider ¶ added in v0.0.8
func NewOpencodeProvider() *OpencodeProvider
NewOpencodeProvider creates a new OpenCode provider.
type Provider ¶
type Provider interface {
// ID returns the unique provider identifier (kebab-case).
// Example: "claude-code", "gemini", "cline"
ID() string
// Name returns the human-readable provider name for display.
// Example: "Claude Code", "Gemini CLI", "Cline"
Name() string
// Priority returns the display order (lower = higher priority).
// Claude Code should be 1, other major tools 2-10, etc.
Priority() int
// ConfigFile returns the instruction file path (e.g., "CLAUDE.md").
// Returns empty string if the provider has no instruction file.
ConfigFile() string
// GetProposalCommandPath returns the relative path for the
// proposal command.
// Example: ".claude/commands/spectr/proposal.md"
// Returns empty string if the provider has no proposal command.
GetProposalCommandPath() string
// GetApplyCommandPath returns the relative path for the apply command.
// Example: ".claude/commands/spectr/apply.md"
// Returns empty string if the provider has no apply command.
GetApplyCommandPath() string
// CommandFormat returns Markdown or TOML for slash command files.
CommandFormat() CommandFormat
// Configure applies all configuration (instruction file + slash commands).
// projectPath is the root project directory.
// spectrDir is the path to the spectr/ directory.
Configure(
projectPath, spectrDir string,
tm TemplateRenderer,
) error
// IsConfigured checks if the provider is fully configured.
// Returns true if all expected files exist.
IsConfigured(projectPath string) bool
// GetFilePaths returns the file paths that this provider creates/updates.
GetFilePaths() []string
// HasConfigFile returns true if this provider creates an instruction file.
HasConfigFile() bool
// HasSlashCommands returns true if this provider creates slash commands.
HasSlashCommands() bool
}
Provider represents an AI CLI tool (Claude Code, Gemini, Cline, etc.). Each provider handles both its instruction file AND slash commands.
func WithConfigFile ¶
func WithConfigFile() []Provider
WithConfigFile returns all providers that have an instruction file, sorted by priority.
func WithSlashCommands ¶
func WithSlashCommands() []Provider
WithSlashCommands returns all providers that have slash commands, sorted by priority.
type QoderProvider ¶
type QoderProvider struct {
BaseProvider
}
QoderProvider implements the Provider interface for Qoder. Qoder uses QODER.md and .qoder/commands/ for slash commands.
func NewQoderProvider ¶
func NewQoderProvider() *QoderProvider
NewQoderProvider creates a new Qoder provider.
type QwenProvider ¶
type QwenProvider struct {
BaseProvider
}
QwenProvider implements the Provider interface for Qwen Code. Qwen uses QWEN.md and .qwen/commands/ for slash commands.
func NewQwenProvider ¶
func NewQwenProvider() *QwenProvider
NewQwenProvider creates a new Qwen Code provider.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry provides an instance-based registry for cases where global state is not desired (e.g., testing).
func NewRegistryFromGlobal ¶
func NewRegistryFromGlobal() *Registry
NewRegistryFromGlobal creates a registry populated with all globally ) registered providers.
type TabnineProvider ¶
type TabnineProvider struct {
BaseProvider
}
TabnineProvider implements the Provider interface for Tabnine. Tabnine uses .tabnine/commands/ for slash commands (no config file).
func NewTabnineProvider ¶
func NewTabnineProvider() *TabnineProvider
NewTabnineProvider creates a new Tabnine provider.
type TemplateContext ¶
type TemplateContext struct {
// BaseDir is the base directory for spectr files (default: "spectr")
BaseDir string
// SpecsDir is the directory for spec files (default: "spectr/specs")
SpecsDir string
// ChangesDir is the directory for change proposals (default: "spectr/changes")
ChangesDir string
// ProjectFile is the path to the project configuration file (default: "spectr/project.md")
ProjectFile string
// AgentsFile is the path to the agents file (default: "spectr/AGENTS.md")
AgentsFile string
}
TemplateContext holds path-related template variables for dynamic directory names. This struct is defined in the providers package to avoid import cycles.
func DefaultTemplateContext ¶
func DefaultTemplateContext() TemplateContext
DefaultTemplateContext returns a TemplateContext with default values.
type TemplateRenderer ¶
type TemplateRenderer interface {
// RenderAgents renders the AGENTS.md template content.
RenderAgents(
ctx TemplateContext,
) (string, error)
// RenderInstructionPointer renders a short pointer template that directs
// AI assistants to read spectr/AGENTS.md for full instructions.
RenderInstructionPointer(
ctx TemplateContext,
) (string, error)
// RenderSlashCommand renders a slash command template (proposal or apply).
RenderSlashCommand(
command string,
ctx TemplateContext,
) (string, error)
}
TemplateRenderer provides template rendering capabilities.
This interface allows providers to render templates without depending on the full TemplateManager.
type WindsurfProvider ¶
type WindsurfProvider struct {
BaseProvider
}
WindsurfProvider implements the Provider interface for Windsurf. Windsurf uses .windsurf/commands/ for slash commands (no config file).
func NewWindsurfProvider ¶
func NewWindsurfProvider() *WindsurfProvider
NewWindsurfProvider creates a new Windsurf provider.