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; directory names must match the skill name.

Constant Summary

Constants inherited from Backend

Backend::SKILL_FILENAME

Instance Method Summary collapse

Constructor Details

#initialize(*paths) ⇒ FilesystemBackend

– : (*String) -> void



13
14
15
16
# 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

Instance Method Details

#list_skillsObject

Returns frontmatter for all discovered skills; on a name collision across paths, first-path-wins. – : () -> Array



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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

#read_skill(name) ⇒ Object

Returns the full SKILL.md body (without frontmatter) for a skill. Raises Riffer::ArgumentError if the skill is not found. – : (String) -> String



52
53
54
55
56
57
58
59
60
# 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