playbooks

package
v1.0.53 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// SentinelBegin marks the start of the specledger-managed section.
	SentinelBegin = "# >>> specledger-generated"
	// SentinelEnd marks the end of the specledger-managed section.
	SentinelEnd = "# <<< specledger-generated"
	// SentinelComment is the warning comment inside the sentinel block.
	SentinelComment = "# Auto-managed by specledger - do not edit this section"
)

Variables

View Source
var TemplatesFS = embedded.TemplatesFS

Functions

func AbsPath

func AbsPath(relPath string) string

func ApplyToProject

func ApplyToProject(projectPath, playbookName string, force bool) (string, string, []string, error)

ApplyToProject applies playbooks to a project. This is the main entry point for playbook copying during project creation. If playbookName is empty, it uses the default playbook (currently "specledger"). If force is true, existing files will be overwritten. Returns the playbook name, version, and structure.

func ApplyToProjectWithAgentTarget added in v1.0.53

func ApplyToProjectWithAgentTarget(projectPath, playbookName string, force bool, agentTargetDir string) (string, string, []string, error)

ApplyToProjectWithAgentTarget applies playbooks to a project with a custom agent target directory. agentTargetDir specifies where to copy commands and skills (e.g., ".agents"). If empty, defaults to ".claude".

func CacheDir

func CacheDir() (string, error)

CacheDir returns the directory for caching remote playbooks. Future implementation will use this for storing downloaded playbooks.

func CachedPlaybookPath

func CachedPlaybookPath(playbookName, version string) (string, error)

CachedPlaybookPath returns the path where a cached playbook would be stored. Future implementation will use this for storing downloaded playbook archives.

func CleanupAgentSymlinks(projectPath string) error

CleanupAgentSymlinks removes existing agent symlinks/directories for all known agents. This is called when --force is used to reset the agent configuration.

func ClearCache

func ClearCache() error

ClearCache removes all cached playbooks. Future implementation for cache management.

func CreateAgentSharedDir added in v1.0.53

func CreateAgentSharedDir(projectDir string, force bool) error

func Exists

func Exists(path string) bool

func FormatJSON

func FormatJSON(playbooks []Playbook) string

FormatJSON formats playbooks as JSON for display.

func FormatTable

func FormatTable(playbooks []Playbook) string

FormatTable formats playbooks as a table for display.

func IsExecutableFile added in v1.0.16

func IsExecutableFile(filename string, content []byte) bool

IsExecutableFile determines if a file should have execute permissions. Returns true if the file has a .sh extension or starts with a shebang (#!).

func LinkAgentToShared added in v1.0.53

func LinkAgentToShared(projectDir string, agentNames []string, force bool) error

func MergeSentinelSection added in v1.0.47

func MergeSentinelSection(existing, managed string) string

MergeSentinelSection merges managed content into an existing file using sentinel markers. It handles four states:

  1. Empty existing content: returns the sentinel block
  2. No sentinels found: appends the sentinel block
  3. Valid sentinels (begin < end): replaces the sentinel section
  4. Malformed sentinel (begin without end): replaces from begin to EOF

The function is idempotent — calling it twice with the same inputs produces the same output.

func PlaybooksDir

func PlaybooksDir() (string, error)

func ReadFile

func ReadFile(path string) ([]byte, error)

func Stat

func Stat(path string) (fs.FileInfo, error)

func WalkPlaybooks

func WalkPlaybooks(fn func(path string, d fs.DirEntry, err error) error) error

Types

type CopyError

type CopyError struct {
	// Path is the file path where the error occurred
	Path string

	// Err is the underlying error
	Err error

	// IsWarning indicates if this is a non-fatal warning
	IsWarning bool
}

CopyError represents an error that occurred during copying with context.

func (*CopyError) Error

func (e *CopyError) Error() string

Error implements the error interface.

func (*CopyError) Unwrap

func (e *CopyError) Unwrap() error

Unwrap returns the underlying error for errors.Is/As.

type CopyOptions

type CopyOptions struct {
	// DryRun if true, shows what would be copied without actually copying
	DryRun bool

	// Overwrite if true, overwrites existing files in the destination
	// Default is false (skip existing files)
	Overwrite bool

	// SkipExisting if true, skips existing files (default behavior)
	// Ignored if Overwrite is true
	SkipExisting bool

	// Verbose if true, prints each file being copied
	Verbose bool

	// Framework filters templates by framework type (optional)
	// If set, only templates matching this framework are copied
	Framework string

	// AgentTargetDir specifies where to copy commands and skills (e.g., ".agents")
	// If empty, defaults to ".claude"
	// When multi-agent mode is enabled, this should be set to ".agents"
	AgentTargetDir string
}

CopyOptions controls the behavior of playbook copying operations.

type CopyResult

type CopyResult struct {
	// FilesCopied is the count of files successfully copied
	FilesCopied int

	// FilesSkipped is the count of files skipped (already existed)
	FilesSkipped int

	// FilesMerged is the count of files merged (sentinel-based)
	FilesMerged int

	// Errors is a list of errors encountered during copying
	Errors []CopyError

	// Duration is how long the copy operation took
	Duration time.Duration
}

CopyResult contains the results of a playbook copy operation.

func CopyPlaybooks

func CopyPlaybooks(srcDir, destDir string, playbook Playbook, opts CopyOptions) (*CopyResult, error)

CopyPlaybooks copies a playbook to the destination directory from the embedded filesystem. It copies files based on: 1. Structure items (files/directories copied to project root) 2. Commands (copied to .agents/commands/ or .claude/commands/ depending on AgentTargetDir) 3. Skills (copied to .agents/skills/ or .claude/skills/ depending on AgentTargetDir)

type EmbeddedSource

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

EmbeddedSource implements PlaybookSource for playbooks stored in the embedded filesystem.

func NewEmbeddedSource

func NewEmbeddedSource() (*EmbeddedSource, error)

NewEmbeddedSource creates a new EmbeddedSource.

func (*EmbeddedSource) Copy

func (s *EmbeddedSource) Copy(name string, destDir string, opts CopyOptions) (*CopyResult, error)

Copy copies the specified playbook to the destination directory.

func (*EmbeddedSource) Exists

func (s *EmbeddedSource) Exists(name string) bool

Exists checks if a playbook with the given name exists.

func (*EmbeddedSource) GetDefaultPlaybook

func (s *EmbeddedSource) GetDefaultPlaybook() (*Playbook, error)

GetDefaultPlaybook returns the first available playbook. For now, there's only one playbook (specledger).

func (*EmbeddedSource) GetPlaybook

func (s *EmbeddedSource) GetPlaybook(name string) (*Playbook, error)

GetPlaybook retrieves a playbook by name. Returns the playbook with the matching name, or an error if not found.

func (*EmbeddedSource) List

func (s *EmbeddedSource) List() ([]Playbook, error)

List returns all available playbooks from the embedded source.

func (*EmbeddedSource) ValidatePlaybooks

func (s *EmbeddedSource) ValidatePlaybooks() error

ValidatePlaybooks checks that the templates directory exists and contains required files.

type Playbook

type Playbook struct {
	// Name is the unique identifier for this playbook (e.g., "specledger")
	Name string `yaml:"name"`

	// Description explains what this playbook provides to users
	Description string `yaml:"description"`

	// Framework is the SDD framework type (optional, for future use)
	Framework string `yaml:"framework,omitempty"`

	// Version is the playbook version (semantic versioning recommended)
	Version string `yaml:"version"`

	// Path is the relative path within the templates folder
	Path string `yaml:"path"`

	// Patterns are glob patterns for files to include (optional, defaults to all files)
	// If empty, all files in Path are included.
	Patterns []string `yaml:"patterns,omitempty"`

	// Structure describes the folder structure that this playbook creates
	// These are files/directories copied to the project root
	Structure []string `yaml:"structure,omitempty"`

	// Protected lists files that should not be overwritten during template updates
	// These are user-specific files that should be preserved
	Protected []string `yaml:"protected,omitempty"`

	// Mergeable lists files that should be merged (sentinel-based) instead of copied
	Mergeable []string `yaml:"mergeable,omitempty"`

	// PostScript is the path to a script to run after copying (e.g., "init.sh")
	// The script is executed from the embedded FS, not copied to the target
	PostScript string `yaml:"post_script,omitempty"`

	// Commands are AI commands to copy to .claude/commands/
	Commands []PlaybookItem `yaml:"commands,omitempty"`

	// Skills are AI skills to copy to .claude/skills/
	Skills []PlaybookItem `yaml:"skills,omitempty"`
}

Playbook represents a single playbook that can be applied to a project.

func ListPlaybooks

func ListPlaybooks() ([]Playbook, error)

ListPlaybooks returns all available playbooks formatted for display.

type PlaybookItem added in v1.0.41

type PlaybookItem struct {
	// Name is the identifier for this item
	Name string `yaml:"name"`

	// Path is the relative path within the playbook
	Path string `yaml:"path"`

	// Description explains what this item provides
	Description string `yaml:"description,omitempty"`
}

PlaybookItem represents a command or skill in the playbook.

type PlaybookManifest

type PlaybookManifest struct {
	// Version is the manifest format version
	Version string

	// Playbooks is the list of available playbooks
	Playbooks []Playbook
}

PlaybookManifest represents the manifest file that lists available playbooks.

func LoadManifest

func LoadManifest(templatesDir string) (*PlaybookManifest, error)

LoadManifest loads the playbook manifest from the embedded templates directory.

func ParseManifest

func ParseManifest(data []byte) (*PlaybookManifest, error)

ParseManifest parses the manifest YAML data.

type PlaybookSource

type PlaybookSource interface {
	// List returns all available playbooks from this source.
	List() ([]Playbook, error)

	// Copy copies the specified playbook to the destination directory.
	// The name parameter must match a playbook name from List().
	// Options control the copy behavior (overwrite, skip, etc.).
	Copy(name string, destDir string, opts CopyOptions) (*CopyResult, error)

	// Exists checks if a playbook with the given name exists in this source.
	Exists(name string) bool
}

PlaybookSource represents a source of playbooks (embedded or remote).

type RemoteSource

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

RemoteSource implements PlaybookSource for playbooks fetched from remote URLs. This is a stub for future implementation - the architecture supports it but the actual functionality is not yet implemented.

Future implementation will support: - Git repositories (git@github.com:org/playbook.git) - HTTPS URLs to playbook archives - Playbook caching at ~/.github.com/specledger/specledger/playbook-cache/ - Authentication for private repositories

func NewRemoteSource

func NewRemoteSource(baseURL string) (*RemoteSource, error)

NewRemoteSource creates a new RemoteSource for fetching playbooks from a remote URL. Future implementation will support various URL formats.

func (*RemoteSource) Copy

func (s *RemoteSource) Copy(name string, destDir string, opts CopyOptions) (*CopyResult, error)

Copy copies the specified playbook from the remote source to the destination directory. Future implementation will: 1. Fetch playbook archive or clone git repository 2. Extract/copy to destination directory 3. Handle caching, versioning, and updates

func (*RemoteSource) Exists

func (s *RemoteSource) Exists(name string) bool

Exists checks if a playbook with the given name exists in the remote source. Future implementation will check the remote manifest.

func (*RemoteSource) List

func (s *RemoteSource) List() ([]Playbook, error)

List returns all available playbooks from the remote source. Future implementation will: 1. Fetch manifest from remote URL 2. Parse and return playbook list 3. Handle authentication and errors

func (*RemoteSource) RefreshCache

func (s *RemoteSource) RefreshCache() error

RefreshCache updates the local cache of remote playbooks. Future implementation for when caching is added.

Jump to

Keyboard shortcuts

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