Class: BundlerSkills::Linker

Inherits:
Object
  • Object
show all
Defined in:
lib/bundler_skills/linker.rb

Overview

Creates idempotent absolute symlinks for discovered skills into a single output directory, and prunes stale ones we previously created.

Pure filesystem operations — no Bundler dependency, so it is fully unit testable against a tmpdir. One Linker instance == one output directory (e.g. .claude/skills or .agents/skills).

Defined Under Namespace

Classes: Result

Constant Summary collapse

STALE_GLOB =
"#{DiscoveredSkill::LINK_PREFIX}*#{DiscoveredSkill::BOUNDARY}*"

Instance Method Summary collapse

Constructor Details

#initialize(skills_dir:, config: Config.new(Config::DEFAULTS), logger: nil) ⇒ Linker

Returns a new instance of Linker.



32
33
34
35
36
# File 'lib/bundler_skills/linker.rb', line 32

def initialize(skills_dir:, config: Config.new(Config::DEFAULTS), logger: nil)
  @skills_dir = skills_dir
  @config = config
  @logger = logger
end

Instance Method Details

#clean_allArray<String>

Remove every gem- symlink we own (for ‘bundle skills clean`).

Returns:

  • (Array<String>)

    removed link names



58
59
60
61
62
63
64
65
66
67
# File 'lib/bundler_skills/linker.rb', line 58

def clean_all
  removed = []
  Dir.glob(File.join(@skills_dir, STALE_GLOB)).each do |path|
    next unless File.symlink?(path)

    remove(path)
    removed << File.basename(path)
  end
  removed
end

Parameters:

  • skills (Array<DiscoveredSkill>)
  • prune_scope (Symbol, Array<String>, nil) (defaults to: :all)

    which stale links to prune: :all (default) -> every gem- link we own (full sync)

    prefix, …

    -> only links whose basename starts with one of the

    given prefixes, e.g. "gem-<name>--" (single-gem sync)
    

    nil -> prune nothing Pruning still honors @config.cleanup? — when cleanup is off nothing is pruned.

Returns:



46
47
48
49
50
51
52
53
54
# File 'lib/bundler_skills/linker.rb', line 46

def link(skills, prune_scope: :all)
  result = Result.new
  link_names = skills.map(&:link_name)

  ensure_dir
  skills.each { |skill| link_one(skill, result) }
  prune_stale(link_names, result, prune_scope) if @config.cleanup? && prune_scope
  result
end