Class: Pikuri::Skill::Catalog::Bundled

Inherits:
Pikuri::Skill::Catalog show all
Defined in:
lib/pikuri/skill/catalog.rb

Overview

On-disk catalog. Constructed with a list of *search bases* (project root, home dir, …); for each base, scans .pikuri/skills, .claude/skills and .agents/skills.pikuri first (the user’s own pikuri-specific skills), .claude second (so Claude Code skills travel along for free), .agents last (the cross-harness convention PI also honors). Missing subdirs are silently skipped.

Precedence

Bases are processed left to right; within each base the subdir order above applies. The first skill seen for a given name wins; later occurrences are dropped with a warning. Callers that want “project beats global” pass the project root first.

Validation

The Agent Skills standard is enforced leniently. A missing description is the only hard failure (the skill is skipped); name/dir mismatch, oversized name/description, invalid name characters and malformed YAML all log warnings and the skill still loads with whatever could be salvaged. Files without YAML frontmatter at all are skipped silently — they’re presumably not meant as skills.

Constant Summary

Constants inherited from Pikuri::Skill::Catalog

MAX_DESCRIPTION_LENGTH, MAX_NAME_LENGTH

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Pikuri::Skill::Catalog

#empty?, #format_for_prompt

Constructor Details

#initialize(search_bases:) ⇒ Bundled

Parameters:

  • search_bases (Array<String, Pathname>)

    directories under which to look for skill subdirs. Typical values: the project root and Dir.home. Processed left to right.



155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/pikuri/skill/catalog.rb', line 155

def initialize(search_bases:)
  super()
  @roots = search_bases
           .flat_map { |base| SKILL_SUBDIRS.map { |sub| File.join(base.to_s, sub) } }
           .select { |dir| File.directory?(dir) }
           .freeze
  @skills = {}
  @roots.each { |root| scan_root(root) }
  @skills.freeze
  @list = @skills.values.freeze
  freeze
end

Instance Attribute Details

#rootsArray<String> (readonly)

Returns absolute paths of the existing skill directories this catalog covered, in scan order.

Returns:

  • (Array<String>)

    absolute paths of the existing skill directories this catalog covered, in scan order.



181
182
183
# File 'lib/pikuri/skill/catalog.rb', line 181

def roots
  @roots
end

Instance Method Details

#get(name) ⇒ Skill?

Parameters:

  • name (String)

Returns:



175
176
177
# File 'lib/pikuri/skill/catalog.rb', line 175

def get(name)
  @skills[name]
end

#listArray<Skill>

Returns:



169
170
171
# File 'lib/pikuri/skill/catalog.rb', line 169

def list
  @list
end