Class: RubynCode::Skills::Catalog

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyn_code/skills/catalog.rb

Constant Summary collapse

SKILL_GLOB =
'**/*.md'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(skills_dirs) ⇒ Catalog

Returns a new instance of Catalog.



10
11
12
13
# File 'lib/rubyn_code/skills/catalog.rb', line 10

def initialize(skills_dirs)
  @skills_dirs = Array(skills_dirs)
  @index = nil
end

Instance Attribute Details

#skills_dirsObject (readonly)

Returns the value of attribute skills_dirs.



8
9
10
# File 'lib/rubyn_code/skills/catalog.rb', line 8

def skills_dirs
  @skills_dirs
end

Instance Method Details

#availableObject



22
23
24
25
# File 'lib/rubyn_code/skills/catalog.rb', line 22

def available
  build_index unless @index
  @index
end

#by_category(category) ⇒ Array<Hash>

Filter skills by category (subdirectory name). Skills are organized in subdirectories under each skills_dir.

Parameters:

  • category (String)

    category/directory name (e.g. “rails”, “testing”)

Returns:

  • (Array<Hash>)

    matching entries



64
65
66
67
68
69
# File 'lib/rubyn_code/skills/catalog.rb', line 64

def by_category(category)
  normalized = category.to_s.downcase
  available.select do |entry|
    path_category(entry[:path]).downcase == normalized
  end
end

#categoriesArray<String>

Return the list of unique categories derived from skill file paths.

Returns:

  • (Array<String>)

    sorted category names



74
75
76
77
78
79
# File 'lib/rubyn_code/skills/catalog.rb', line 74

def categories
  available.map { |e| path_category(e[:path]) }
           .reject(&:empty?)
           .uniq
           .sort
end

#descriptionsObject



15
16
17
18
19
20
# File 'lib/rubyn_code/skills/catalog.rb', line 15

def descriptions
  entries = available
  return '' if entries.empty?

  entries.map { |entry| "- /#{entry[:name]}: #{entry[:description]}" }.join("\n")
end

#find(name) ⇒ Object



38
39
40
41
# File 'lib/rubyn_code/skills/catalog.rb', line 38

def find(name)
  entry = available.find { |e| e[:name] == name.to_s }
  entry&.fetch(:path)
end

#listObject



34
35
36
# File 'lib/rubyn_code/skills/catalog.rb', line 34

def list
  available.map { |e| e[:name] }
end

#refresh!Object

Force the index to be rebuilt on next access. Used after installing a skill pack so newly-written files become discoverable in the same session.



30
31
32
# File 'lib/rubyn_code/skills/catalog.rb', line 30

def refresh!
  @index = nil
end

#search(term) ⇒ Array<Hash>

Search skill content — matches against names, descriptions, and tags. Returns matching entries sorted by relevance (number of field matches).

Parameters:

  • term (String)

    search term (case-insensitive)

Returns:

  • (Array<Hash>)

    matching entries with :name, :description, :path, :relevance



48
49
50
51
52
53
54
55
56
57
# File 'lib/rubyn_code/skills/catalog.rb', line 48

def search(term)
  pattern = /#{Regexp.escape(term)}/i
  matches = available.filter_map do |entry|
    relevance = compute_relevance(entry, pattern)
    next if relevance.zero?

    entry.merge(relevance: relevance)
  end
  matches.sort_by { |e| -e[:relevance] }
end