class Riffer::Skills::FilesystemBackend
Built-in backend that reads skills from the filesystem. Scans configured directories for immediate child directories containing SKILL.md; directory names must match the skill name.
Public Class Methods
Source
# File lib/riffer/skills/filesystem_backend.rb, line 13 def initialize(*paths) @paths = paths.flatten.map { |p| File.expand_path(p) } @skills_cache = nil #: Hash[String, String]? end
Public Instance Methods
Source
# File lib/riffer/skills/filesystem_backend.rb, line 22 def list_skills cache = {} #: Hash[String, String] @skills_cache = cache frontmatters = [] #: Array[Riffer::Skills::Frontmatter] @paths.each do |path| next unless File.directory?(path) Dir.children(path).sort.each do |dirname| dir = File.join(path, dirname) skill_file = File.join(dir, SKILL_FILENAME) next unless File.directory?(dir) && File.file?(skill_file) frontmatter = Riffer::Skills::Frontmatter.parse_frontmatter(File.read(skill_file)) validate_dirname_matches_name!(dirname, frontmatter.name) next if cache.key?(frontmatter.name) frontmatters << frontmatter cache[frontmatter.name] = dir end end frontmatters end
Returns frontmatter for all discovered skills; on a name collision across paths, first-path-wins.
Source
# File lib/riffer/skills/filesystem_backend.rb, line 52 def read_skill(name) list_skills unless @skills_cache cache = @skills_cache #: Hash[String, String] dir = cache[name] raise Riffer::ArgumentError, "Skill not found: '#{name}'" unless dir _, body = Riffer::Skills::Frontmatter.parse(File.read(File.join(dir, SKILL_FILENAME))) body end
Returns the full SKILL.md body (without frontmatter) for a skill. Raises Riffer::ArgumentError if the skill is not found.