Class: Riffer::Skills::FilesystemBackend

Inherits:
Backend
  • Object
show all
Defined in:
lib/riffer/skills/filesystem_backend.rb

Overview

Built-in backend that reads skills from the filesystem.

Scans configured directories for immediate child directories containing SKILL.md files. Directory names must match the skill name field.

backend = Riffer::Skills::FilesystemBackend.new(".skills", "~/.riffer/skills")
backend.list_skills  # => [Riffer::Skills::Frontmatter, ...]
backend.read_skill("code-review")  # => "Full skill instructions..."

Constant Summary

Constants inherited from Backend

Backend::SKILL_FILENAME

Instance Method Summary collapse

Constructor Details

#initialize(*paths) ⇒ FilesystemBackend

Creates a new FilesystemBackend.

paths

one or more directory paths to scan for skills.

– : (*String) -> void



20
21
22
23
# File 'lib/riffer/skills/filesystem_backend.rb', line 20

def initialize(*paths)
  @paths = paths.flatten.map { |p| File.expand_path(p) }
  @skills_cache = nil #: Hash[String, String]?
end

Instance Method Details

#list_skillsObject

Returns frontmatter for all discovered skills.

Scans each configured path for immediate child directories containing SKILL.md. When multiple paths contain a skill with the same name, first-path-wins.

– : () -> Array



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/riffer/skills/filesystem_backend.rb', line 33

def list_skills
  @skills_cache = {}
  frontmatters = []

  @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 @skills_cache.key?(frontmatter.name)

      frontmatters << frontmatter
      @skills_cache[frontmatter.name] = dir
    end
  end

  frontmatters
end

#read_skill(name) ⇒ Object

Returns the full SKILL.md body (without frontmatter) for a skill.

name

the skill name to read.

Raises Riffer::ArgumentError if skill not found.

– : (String) -> String



66
67
68
69
70
71
72
73
# File 'lib/riffer/skills/filesystem_backend.rb', line 66

def read_skill(name)
  list_skills unless @skills_cache
  dir = @skills_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