providers

package
v0.0.9 Latest Latest
Warning

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

Go to latest
Published: Jan 1, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package providers implements the composable initializer 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 returns a list of initializers that handle specific aspects of configuration (directories, instruction files, slash commands).

Adding a New Provider

To add a new AI CLI provider:

1. Create a new file (e.g., providers/mytool.go) with a type implementing Provider: //nolint:lll

package providers

import (
	"context"
	"github.com/connerohnesorge/spectr/internal/domain"
)

type MyToolProvider struct{}

func (p *MyToolProvider) Initializers(ctx context.Context, tm TemplateManager) []Initializer { //nolint:lll
	return []Initializer{
		NewDirectoryInitializer(".mytool/commands/spectr"),
		NewConfigFileInitializer("MYTOOL.md", tm.InstructionPointer()),
		NewSlashCommandsInitializer(".mytool/commands/spectr", map[domain.SlashCommand]domain.TemplateRef{ //nolint:lll
			domain.SlashProposal: tm.SlashCommand(domain.SlashProposal),
			domain.SlashApply:    tm.SlashCommand(domain.SlashApply),
		}),
	}
}

2. Register the provider in RegisterAllProviders() in registry.go:

{ID: "mytool", Name: "MyTool", Priority: 100, Provider: &MyToolProvider{}}

The initializers handle all common logic - no boilerplate needed!

Index

Constants

View Source
const (
	PriorityClaudeCode  = 1
	PriorityGemini      = 2
	PriorityCostrict    = 3
	PriorityQoder       = 4
	PriorityQwen        = 5
	PriorityAntigravity = 6
	PriorityCline       = 7
	PriorityCursor      = 8
	PriorityCodex       = 9
	PriorityAider       = 10
	PriorityWindsurf    = 11
	PriorityKilocode    = 12
	PriorityContinue    = 13
	PriorityCrush       = 14
	PriorityOpencode    = 15
)

Priority constants for built-in providers (lower = higher priority).

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 RegisterAllProviders added in v0.0.9

func RegisterAllProviders() error

RegisterAllProviders registers all built-in providers. This should be called once at application startup. Returns an error if any registration fails.

func RegisterProvider added in v0.0.9

func RegisterProvider(reg Registration) error

RegisterProvider registers a provider with its metadata. Returns an error if: - ID is empty - Provider is nil - A provider with the same ID is already registered

func Reset

func Reset()

Reset clears all registered providers. This is primarily for testing purposes.

Types

type AgentSkillsInitializer added in v0.0.9

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

AgentSkillsInitializer copies an embedded skill directory to a target path. This initializer handles copying entire skill directories from embedded templates to the project filesystem, preserving directory structure and file permissions (e.g., executable scripts).

Skills follow the AgentSkills specification (https://agentskills.io) and must contain at minimum a SKILL.md file.

func NewAgentSkillsInitializer added in v0.0.9

func NewAgentSkillsInitializer(
	skillName, targetDir string,
	tm TemplateManager,
) *AgentSkillsInitializer

NewAgentSkillsInitializer creates an AgentSkillsInitializer for the given skill name and target directory.

Parameters:

  • skillName: Name of the embedded skill directory (e.g., "spectr-accept-wo-spectr-bin")
  • targetDir: Target directory path relative to project root (e.g., ".claude/skills/spectr-accept-wo-spectr-bin")
  • tm: TemplateManager providing access to embedded skill files via SkillFS

Example:

init := NewAgentSkillsInitializer(
	"spectr-accept-wo-spectr-bin",
	".claude/skills/spectr-accept-wo-spectr-bin",
	tm,
)

func (*AgentSkillsInitializer) Init added in v0.0.9

func (a *AgentSkillsInitializer) Init(
	ctx context.Context,
	projectFs, homeFs afero.Fs,
	cfg *Config,
	tm TemplateManager,
) (InitResult, error)

Init recursively copies all files from the embedded skill directory to the target directory in the project filesystem.

Behavior:

  • Creates target directory if it doesn't exist
  • Recursively copies all files and subdirectories
  • Preserves directory structure (e.g., scripts/accept.sh)
  • Preserves file permissions (executable scripts remain executable)
  • Overwrites existing files (idempotent operation)
  • Returns error if skill not found in embedded templates

The initializer uses TemplateManager.SkillFS() to access the embedded skill filesystem rooted at the skill directory.

func (*AgentSkillsInitializer) IsSetup added in v0.0.9

func (a *AgentSkillsInitializer) IsSetup(
	projectFs, _ afero.Fs,
	_ *Config,
) bool

IsSetup returns true if the SKILL.md file exists in the target directory. This indicates that the skill has been initialized at least once.

The check is simple - we only verify SKILL.md exists, not the complete skill structure. This matches the pattern used by other initializers (e.g., DirectoryInitializer checks directory existence).

type AiderProvider

type AiderProvider struct{}

AiderProvider implements the Provider interface for Aider. Aider uses .aider/commands/spectr/ for slash commands (no config file).

func (*AiderProvider) Initializers added in v0.0.9

func (*AiderProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Aider.

type AntigravityProvider

type AntigravityProvider struct{}

AntigravityProvider implements the Provider interface for Antigravity. Antigravity uses AGENTS.md and .agent/workflows/ for prefixed slash commands (spectr-proposal.md, spectr-apply.md).

func (*AntigravityProvider) Initializers added in v0.0.9

Initializers returns the list of initializers for Antigravity.

type ClaudeProvider

type ClaudeProvider struct{}

ClaudeProvider implements the Provider interface for Claude Code. Claude Code uses CLAUDE.md and .claude/commands/spectr/ for slash commands.

func (*ClaudeProvider) Initializers added in v0.0.9

func (*ClaudeProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Claude Code.

type ClineProvider

type ClineProvider struct{}

ClineProvider implements the Provider interface for Cline. Cline uses CLINE.md and .clinerules/commands/spectr/ for slash commands.

func (*ClineProvider) Initializers added in v0.0.9

func (*ClineProvider) Initializers(_ context.Context, tm TemplateManager) []Initializer

Initializers returns the list of initializers for Cline.

type CodexProvider

type CodexProvider struct{}

CodexProvider implements the Provider interface for Codex CLI. Codex uses AGENTS.md and global ~/.codex/prompts/ for prefixed slash commands (spectr-proposal.md, spectr-apply.md).

func (*CodexProvider) Initializers added in v0.0.9

func (*CodexProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Codex CLI. //nolint:lll // Function signature defined by Provider interface

type Config added in v0.0.9

type Config struct {
	// SpectrDir is the base directory for spectr files,
	// relative to the project root.
	// Example: "spectr"
	// Must not be empty, absolute, or contain path traversal.
	SpectrDir string
}

Config holds configuration for provider initialization. All paths are derived from SpectrDir to ensure consistency.

func (*Config) AgentsFile added in v0.0.9

func (c *Config) AgentsFile() string

AgentsFile returns the path to the agents file. Derived from SpectrDir: {SpectrDir}/AGENTS.md

func (*Config) ChangesDir added in v0.0.9

func (c *Config) ChangesDir() string

ChangesDir returns the directory for change proposals. Derived from SpectrDir: {SpectrDir}/changes

func (*Config) ProjectFile added in v0.0.9

func (c *Config) ProjectFile() string

ProjectFile returns the path to the project configuration file. Derived from SpectrDir: {SpectrDir}/project.md

func (*Config) SpecsDir added in v0.0.9

func (c *Config) SpecsDir() string

SpecsDir returns the directory for spec files. Derived from SpectrDir: {SpectrDir}/specs

func (*Config) Validate added in v0.0.9

func (c *Config) Validate() error

Validate checks Config fields for basic correctness. Returns an error if any validation rule fails.

type ConfigFileInitializer added in v0.0.9

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

ConfigFileInitializer creates or updates instruction files with marker-based content. //nolint:lll Uses <!-- spectr:start --> and <!-- spectr:end --> markers (case-insensitive read, lowercase write). //nolint:lll

func (*ConfigFileInitializer) Init added in v0.0.9

func (c *ConfigFileInitializer) Init(
	ctx context.Context,
	projectFs, homeFs afero.Fs,
	cfg *Config,
	tm TemplateManager,
) (InitResult, error)

If file exists, updates content between markers (case-insensitive marker search).

func (*ConfigFileInitializer) IsSetup added in v0.0.9

func (c *ConfigFileInitializer) IsSetup(projectFs, _ afero.Fs, _ *Config) bool

IsSetup checks if the instruction file exists in the project filesystem.

type ContinueProvider

type ContinueProvider struct{}

ContinueProvider implements the Provider interface for Continue. Continue uses .continue/commands/spectr/ for slash commands (no config file).

func (*ContinueProvider) Initializers added in v0.0.9

func (*ContinueProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Continue.

type CostrictProvider

type CostrictProvider struct{}

CostrictProvider implements the Provider interface for CoStrict. CoStrict uses COSTRICT.md and .costrict/commands/spectr/ for slash commands.

func (*CostrictProvider) Initializers added in v0.0.9

func (*CostrictProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for CoStrict.

type CrushProvider added in v0.0.8

type CrushProvider struct{}

CrushProvider implements the Provider interface for Crush. Crush uses CRUSH.md and .crush/commands/spectr/ for slash commands.

func (*CrushProvider) Initializers added in v0.0.9

func (*CrushProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Crush.

type CursorProvider

type CursorProvider struct{}

CursorProvider implements the Provider interface for Cursor. Cursor uses .cursorrules/commands/spectr/ for slash commands (no config file).

func (*CursorProvider) Initializers added in v0.0.9

func (*CursorProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Cursor. //nolint:lll // Function signature defined by Provider interface

type DirectoryInitializer added in v0.0.9

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

DirectoryInitializer creates directories in the project filesystem. Multiple paths can be created in a single initializer. Uses MkdirAll semantics - creates parent directories if needed, succeeds silently if directory exists. //nolint:lll

func (*DirectoryInitializer) Init added in v0.0.9

func (d *DirectoryInitializer) Init(
	ctx context.Context,
	projectFs, homeFs afero.Fs,
	cfg *Config,
	tm TemplateManager,
) (InitResult, error)

Init creates directories in the project filesystem. Returns created directories in InitResult (silent success if directory already exists).

func (*DirectoryInitializer) IsSetup added in v0.0.9

func (d *DirectoryInitializer) IsSetup(
	projectFs, _ afero.Fs,
	_ *Config,
) bool

IsSetup checks if all directories exist in the project filesystem.

type ExecutionResult added in v0.0.9

type ExecutionResult struct {
	// CreatedFiles is the list of all files created
	// across all initializers.
	CreatedFiles []string

	// UpdatedFiles is the list of all files updated
	// across all initializers.
	UpdatedFiles []string
}

ExecutionResult aggregates results from all initializers. This is the final result returned after running all initializers.

Note: Error is returned separately from the executor function, not stored in this struct. This allows partial results to be returned even when an error occurs (fail-fast behavior).

type GeminiProvider

type GeminiProvider struct{}

GeminiProvider implements the Provider interface for Gemini CLI. Gemini uses .gemini/commands/spectr/ for TOML-based slash commands (no instruction file). //nolint:lll

func (*GeminiProvider) Initializers added in v0.0.9

func (*GeminiProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Gemini CLI.

type HomeDirectoryInitializer added in v0.0.9

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

HomeDirectoryInitializer creates directories in the home filesystem. Multiple paths can be created in a single initializer. Uses MkdirAll semantics - creates parent directories if needed, succeeds silently if directory exists. //nolint:lll

func (*HomeDirectoryInitializer) Init added in v0.0.9

func (h *HomeDirectoryInitializer) Init(
	ctx context.Context,
	projectFs, homeFs afero.Fs,
	cfg *Config,
	tm TemplateManager,
) (InitResult, error)

Init creates directories in the home filesystem. Returns created directories in InitResult (silent success if directory already exists).

func (*HomeDirectoryInitializer) IsSetup added in v0.0.9

func (h *HomeDirectoryInitializer) IsSetup(
	_, homeFs afero.Fs,
	_ *Config,
) bool

IsSetup checks if all directories exist in the home filesystem.

type HomePrefixedSlashCommandsInitializer added in v0.0.9

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

HomePrefixedSlashCommandsInitializer creates Markdown slash command files with custom prefix in home filesystem. Used by providers like Codex that need custom file naming in home directory. Output: {dir}/{prefix}{command}.md (e.g., ~/.codex/prompts/spectr-proposal.md)

func (*HomePrefixedSlashCommandsInitializer) Init added in v0.0.9

Init creates prefixed slash command files in the home filesystem. Always overwrites existing files (idempotent).

func (*HomePrefixedSlashCommandsInitializer) IsSetup added in v0.0.9

func (h *HomePrefixedSlashCommandsInitializer) IsSetup(
	_, homeFs afero.Fs,
	_ *Config,
) bool

IsSetup checks if all prefixed slash command files exist in the home filesystem.

type HomeSlashCommandsInitializer added in v0.0.9

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

HomeSlashCommandsInitializer creates Markdown slash command files in the home filesystem. Uses early binding - templates are resolved at construction time. Always overwrites existing files (idempotent behavior).

func (*HomeSlashCommandsInitializer) Init added in v0.0.9

Init creates slash command files in the home filesystem. Always overwrites existing files (idempotent).

func (*HomeSlashCommandsInitializer) IsSetup added in v0.0.9

func (h *HomeSlashCommandsInitializer) IsSetup(_, homeFs afero.Fs, _ *Config) bool

IsSetup checks if all slash command files exist in the home filesystem.

type InitResult added in v0.0.9

type InitResult struct {
	// CreatedFiles is the list of files that were newly created.
	// Paths should be relative to the filesystem root (projectFs or homeFs).
	CreatedFiles []string

	// UpdatedFiles is the list of files that already existed and were modified.
	// Paths should be relative to the filesystem root (projectFs or homeFs).
	UpdatedFiles []string
}

InitResult contains the files created or modified by an initializer. This provides explicit change tracking for each initialization step.

type Initializer added in v0.0.9

type Initializer interface {
	// Init creates or updates files for this initializer.
	// Returns InitResult with created/updated file paths and error if initialization fails.
	//
	// Parameters:
	//   - ctx: Context for cancellation and timeout
	//   - projectFs: Filesystem rooted at project directory (for .claude/, CLAUDE.md, etc.)
	//   - homeFs: Filesystem rooted at user home directory (for ~/.codex/, etc.)
	//   - cfg: Configuration with SpectrDir and derived paths
	//   - tm: TemplateManager for rendering templates
	//
	// The initializer decides which filesystem to use based on its type
	// (e.g., DirectoryInitializer uses projectFs, HomeDirectoryInitializer uses homeFs).
	Init(
		ctx context.Context,
		projectFs, homeFs afero.Fs,
		cfg *Config,
		tm TemplateManager,
	) (InitResult, error)

	// IsSetup returns true if this initializer's artifacts already exist.
	//
	// Parameters:
	//   - projectFs: Filesystem rooted at project directory
	//   - homeFs: Filesystem rooted at user home directory
	//   - cfg: Configuration with SpectrDir and derived paths
	//
	// The initializer checks the appropriate filesystem based on its type.
	//
	// PURPOSE: Used by the setup wizard to show which providers are already configured.
	// NOT used to skip initializers during execution - Init() always runs (idempotent).
	IsSetup(projectFs, homeFs afero.Fs, cfg *Config) bool
}

Initializer represents a unit of initialization work that creates or updates files. Each initializer is responsible for a specific aspect of provider configuration (e.g., creating directories, updating config files, creating slash commands).

Initializers must be idempotent - they can be run multiple times safely.

func NewConfigFileInitializer added in v0.0.9

func NewConfigFileInitializer(path string, template domain.TemplateRef) Initializer

NewConfigFileInitializer creates an initializer for instruction files. Path is relative to the project filesystem root. Template is rendered with TemplateContext and inserted between markers. Example: NewConfigFileInitializer("CLAUDE.md", tm.InstructionPointer())

func NewDirectoryInitializer added in v0.0.9

func NewDirectoryInitializer(paths ...string) Initializer

NewDirectoryInitializer creates an initializer for project directories. Paths are relative to the project filesystem root. Example: NewDirectoryInitializer(".claude/commands/spectr")

func NewHomeDirectoryInitializer added in v0.0.9

func NewHomeDirectoryInitializer(paths ...string) Initializer

NewHomeDirectoryInitializer creates an initializer for home directories. Paths are relative to the home filesystem root (~/). Example: NewHomeDirectoryInitializer(".codex/prompts")

func NewHomePrefixedSlashCommandsInitializer added in v0.0.9

func NewHomePrefixedSlashCommandsInitializer(
	dir, prefix string,
	commands map[domain.SlashCommand]domain.TemplateRef,
) Initializer

NewHomePrefixedSlashCommandsInitializer creates an initializer for prefixed Markdown slash commands in home filesystem. Example: NewHomePrefixedSlashCommandsInitializer(".codex/prompts", "spectr-", map[domain.SlashCommand]domain.TemplateRef{...}) //nolint:lll

func NewHomeSlashCommandsInitializer added in v0.0.9

func NewHomeSlashCommandsInitializer(
	dir string,
	commands map[domain.SlashCommand]domain.TemplateRef,
) Initializer

NewHomeSlashCommandsInitializer creates an initializer for Markdown slash commands in home filesystem. //nolint:lll Example: NewHomeSlashCommandsInitializer(".config/mytool/commands", map[domain.SlashCommand]domain.TemplateRef{...}) //nolint:lll

func NewPrefixedSlashCommandsInitializer added in v0.0.9

func NewPrefixedSlashCommandsInitializer(
	dir, prefix string,
	commands map[domain.SlashCommand]domain.TemplateRef,
) Initializer

NewPrefixedSlashCommandsInitializer creates an initializer for prefixed Markdown slash commands in project filesystem. Example: NewPrefixedSlashCommandsInitializer(".agent/workflows", "spectr-", map[domain.SlashCommand]domain.TemplateRef{...})

func NewSlashCommandsInitializer added in v0.0.9

func NewSlashCommandsInitializer(
	dir string,
	commands map[domain.SlashCommand]domain.TemplateRef,
) Initializer

NewSlashCommandsInitializer creates an initializer for Markdown slash commands in project filesystem. //nolint:lll

Example: NewSlashCommandsInitializer(".claude/commands/spectr", map[domain.SlashCommand]domain.TemplateRef{ //nolint:lll
    domain.SlashProposal: tm.SlashCommand(domain.SlashProposal),
    domain.SlashApply: tm.SlashCommand(domain.SlashApply),
})

func NewTOMLSlashCommandsInitializer added in v0.0.9

func NewTOMLSlashCommandsInitializer(
	dir string,
	commands map[domain.SlashCommand]domain.TemplateRef,
) Initializer

NewTOMLSlashCommandsInitializer creates an initializer for TOML slash commands in project filesystem.

Example: NewTOMLSlashCommandsInitializer(".gemini/commands/spectr", map[domain.SlashCommand]domain.TemplateRef{
    domain.SlashProposal: tm.TOMLSlashCommand(domain.SlashProposal),
    domain.SlashApply: tm.TOMLSlashCommand(domain.SlashApply),
})

type KilocodeProvider

type KilocodeProvider struct{}

KilocodeProvider implements the Provider interface for Kilocode. Kilocode uses .kilocode/commands/spectr/ for slash commands (no config file).

func (*KilocodeProvider) Initializers added in v0.0.9

Initializers returns the list of initializers for Kilocode.

type OpencodeProvider added in v0.0.8

type OpencodeProvider struct{}

OpencodeProvider implements the Provider interface for OpenCode. OpenCode uses .opencode/commands/spectr/ for slash commands (no config file).

func (*OpencodeProvider) Initializers added in v0.0.9

func (*OpencodeProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for OpenCode.

type PrefixedSlashCommandsInitializer added in v0.0.9

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

PrefixedSlashCommandsInitializer creates Markdown slash command files with custom prefix in project filesystem. Used by providers like Antigravity that need custom file naming. Output: {dir}/{prefix}{command}.md (e.g., .agent/workflows/spectr-proposal.md)

func (*PrefixedSlashCommandsInitializer) Init added in v0.0.9

Init creates prefixed slash command files in the project filesystem. Always overwrites existing files (idempotent).

func (*PrefixedSlashCommandsInitializer) IsSetup added in v0.0.9

func (p *PrefixedSlashCommandsInitializer) IsSetup(projectFs, _ afero.Fs, _ *Config) bool

IsSetup checks if all prefixed slash command files exist in the project filesystem.

type Provider

type Provider interface {
	// Initializers returns the list of initializers for this provider.
	//
	// Parameters:
	//   - ctx: Context for cancellation and timeout
	//   - tm: TemplateManager for type-safe template access
	//
	// The TemplateManager provides type-safe accessors like:
	//   - tm.InstructionPointer() - for CLAUDE.md, CLINE.md, etc.
	//   - tm.Agents() - for AGENTS.md
	//   - tm.SlashCommand(domain.SlashProposal) - for Markdown
	//   - tm.TOMLSlashCommand(domain.SlashProposal) - for TOML (Gemini)
	//
	// Example:
	//	func (p *ClaudeProvider) Initializers(
	//		ctx context.Context,
	//		tm TemplateManager,
	//	) []Initializer {
	//		return []Initializer{
	//			NewDirectoryInitializer(".claude/commands/spectr"),
	//			NewConfigFileInitializer(
	//				"CLAUDE.md",
	//				tm.InstructionPointer(),
	//			),
	//			NewSlashCommandsInitializer(
	//				".claude/commands/spectr",
	//				map[domain.SlashCommand]domain.TemplateRef{
	//					domain.SlashProposal: tm.SlashCommand(
	//						domain.SlashProposal,
	//					),
	//					domain.SlashApply: tm.SlashCommand(
	//						domain.SlashApply,
	//					),
	//				},
	//			),
	//		}
	//	}
	Initializers(ctx context.Context, tm TemplateManager) []Initializer
}

Provider represents an AI CLI tool (Claude Code, Gemini, Cline, etc.). Each provider returns a list of initializers that configure the tool.

Provider metadata (ID, Name, Priority) is specified at registration time via the Registration struct, not as methods on this interface.

type QoderProvider

type QoderProvider struct{}

QoderProvider implements the Provider interface for Qoder. Qoder uses QODER.md and .qoder/commands/spectr/ for slash commands.

func (*QoderProvider) Initializers added in v0.0.9

func (*QoderProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Qoder.

type QwenProvider

type QwenProvider struct{}

QwenProvider implements the Provider interface for Qwen Code. Qwen Code uses QWEN.md and .qwen/commands/spectr/ for slash commands.

func (*QwenProvider) Initializers added in v0.0.9

func (*QwenProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Qwen Code.

type Registration added in v0.0.9

type Registration struct {
	// ID is the unique provider identifier (kebab-case).
	// Examples: "claude-code", "gemini", "cline"
	// Must be unique across all registered providers.
	ID string

	// Name is the human-readable provider name for display.
	// Examples: "Claude Code", "Gemini CLI", "Cline"
	// Used in UI elements like the setup wizard.
	Name string

	// Priority determines the display order (lower = higher priority).
	// Claude Code should be 1, other major tools 2-10, etc.
	// Used to sort providers in lists and determine which provider wins
	// during initializer deduplication (higher priority = kept first).
	Priority int

	// Provider is the implementation that returns initializers.
	// Must not be nil.
	Provider Provider
}

Registration contains provider metadata and implementation. This struct is used during provider registration to associate a provider implementation with its identifying information.

func Get

func Get(id string) (Registration, bool)

Get retrieves a provider registration by ID. Returns the Registration and true if found, or an empty Registration and false if not found.

func RegisteredProviders added in v0.0.9

func RegisteredProviders() []Registration

RegisteredProviders returns all registered providers sorted by Priority (lower first).

type SlashCommandsInitializer added in v0.0.9

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

SlashCommandsInitializer creates Markdown slash command files in the project filesystem. //nolint:lll Uses early binding - templates are resolved at construction time. Always overwrites existing files (idempotent behavior).

func (*SlashCommandsInitializer) Init added in v0.0.9

func (s *SlashCommandsInitializer) Init(
	_ context.Context,
	projectFs, _ afero.Fs,
	cfg *Config,
	_ TemplateManager,
) (InitResult, error)

Always overwrites existing files (idempotent).

func (*SlashCommandsInitializer) IsSetup added in v0.0.9

func (s *SlashCommandsInitializer) IsSetup(projectFs, _ afero.Fs, _ *Config) bool

IsSetup checks if all slash command files exist in the project filesystem.

type TOMLSlashCommandsInitializer added in v0.0.9

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

TOMLSlashCommandsInitializer creates TOML slash command files in the project filesystem. Used by Gemini provider for TOML format. Uses early binding - templates are resolved at construction time. Always overwrites existing files (idempotent behavior). //nolint:lll

func (*TOMLSlashCommandsInitializer) Init added in v0.0.9

func (t *TOMLSlashCommandsInitializer) Init(
	_ context.Context,
	projectFs, _ afero.Fs,
	cfg *Config,
	_ TemplateManager,
) (InitResult, error)

Init creates TOML slash command files in the project filesystem. Always overwrites existing files (idempotent).

func (*TOMLSlashCommandsInitializer) IsSetup added in v0.0.9

func (t *TOMLSlashCommandsInitializer) IsSetup(projectFs, _ afero.Fs, _ *Config) bool

IsSetup checks if all TOML slash command files exist in the project filesystem.

type TemplateManager added in v0.0.9

type TemplateManager interface {
	// InstructionPointer returns the template for instruction pointer files
	// (CLAUDE.md, CLINE.md, etc.)
	InstructionPointer() domain.TemplateRef

	// Agents returns the template for the AGENTS.md file
	Agents() domain.TemplateRef

	// SlashCommand returns the template for a Markdown slash command
	SlashCommand(cmd domain.SlashCommand) domain.TemplateRef

	// TOMLSlashCommand returns the template for a TOML slash command
	TOMLSlashCommand(cmd domain.SlashCommand) domain.TemplateRef

	// SkillFS returns an fs.FS rooted at the skill directory for the given
	// skill name. Returns an error if the skill does not exist.
	// The filesystem contains all files under templates/skills/<skillName>/
	// with paths relative to the skill root (e.g., SKILL.md, scripts/accept.sh).
	SkillFS(skillName string) (fs.FS, error)
}

TemplateManager is defined in internal/initialize/templates.go. We define it as an interface here to avoid import cycles. The actual implementation is passed from the executor.

type WindsurfProvider

type WindsurfProvider struct{}

WindsurfProvider implements the Provider interface for Windsurf. Windsurf uses .windsurf/commands/spectr/ for slash commands (no config file).

func (*WindsurfProvider) Initializers added in v0.0.9

func (*WindsurfProvider) Initializers(
	_ context.Context,
	tm TemplateManager,
) []Initializer

Initializers returns the list of initializers for Windsurf.

Jump to

Keyboard shortcuts

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