providers

package
v0.0.7 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2025 License: MIT Imports: 7 Imported by: 0

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

View Source
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
)

Priority constants for all providers. Lower numbers = higher priority (displayed first).

View Source
const (

	// Marker constants for managing config file updates.
	SpectrStartMarker = "<!-- spectr:START -->"
	SpectrEndMarker   = "<!-- spectr:END -->"
)

Variables

View Source
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 Count

func Count() int

Count returns the number of registered providers.

func EnsureDir

func EnsureDir(path string) error

EnsureDir creates a directory and all parent directories if they don't exist.

func FileExists

func FileExists(path string) bool

FileExists checks if a file or directory exists.

func IDs

func IDs() []string

IDs returns all registered provider IDs sorted by priority.

func PrefixedCommandPaths

func PrefixedCommandPaths(
	dir, ext string,
) (proposalPath, applyPath string)

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 Reset

func Reset()

Reset clears the global registry. Only use in tests.

func StandardCommandPaths

func StandardCommandPaths(
	dir, ext string,
) (proposalPath, applyPath string)

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

func StandardFrontmatter() map[string]string

StandardFrontmatter returns the standard frontmatter map for most providers.

func UpdateFileWithMarkers

func UpdateFileWithMarkers(
	filePath, content, startMarker, endMarker string,
) error

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) ID

func (p *BaseProvider) ID() string

ID returns the provider identifier.

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 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 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 All

func All() []Provider

All returns all registered providers sorted by priority.

func Get

func Get(id string) Provider

Get retrieves a provider by its ID. Returns nil if the provider is not found.

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 NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new empty registry.

func NewRegistryFromGlobal

func NewRegistryFromGlobal() *Registry

NewRegistryFromGlobal creates a registry populated with all globally ) registered providers.

func (*Registry) All

func (r *Registry) All() []Provider

All returns all providers in this registry sorted by priority.

func (*Registry) Count

func (r *Registry) Count() int

Count returns the number of providers in this registry.

func (*Registry) Get

func (r *Registry) Get(id string) Provider

Get retrieves a provider by its ID.

func (*Registry) IDs

func (r *Registry) IDs() []string

IDs returns all provider IDs in this registry sorted by priority.

func (*Registry) Register

func (r *Registry) Register(p Provider) error

Register adds a provider to this registry.

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.

Jump to

Keyboard shortcuts

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