Class: AgentsSkillVault::Vault

Inherits:
Object
  • Object
show all
Includes:
ManifestOperations, ResourceAdder, ResourceSyncer, ResourceValidator
Defined in:
lib/agents_skill_vault/vault.rb,
lib/agents_skill_vault/vault/resource_adder.rb,
lib/agents_skill_vault/vault/resource_syncer.rb,
lib/agents_skill_vault/vault/resource_validator.rb,
lib/agents_skill_vault/vault/manifest_operations.rb

Overview

Main interface for managing a vault of GitHub resources.

A Vault stores cloned repositories and folders from GitHub in a local directory, tracking them via a manifest file. Resources can be synced, queried, and managed.

Examples:

Create a vault and add resources

vault = AgentsSkillVault::Vault.new(storage_path: "~/.skills")
vault.add("https://github.com/user/repo")
vault.add("https://github.com/user/repo/tree/main/skills/my-skill", label: "my-skill")

Query and sync resources

vault.filter_by_username("user")  # => [Resource, ...]
vault.fetch("user/repo")          # => Resource (raises if not found)
vault.sync("user/repo")           # => SyncResult

Defined Under Namespace

Modules: ManifestOperations, ResourceAdder, ResourceSyncer, ResourceValidator

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ManifestOperations

#export_manifest, #import_manifest, #redownload_all

Methods included from ResourceValidator

#cleanup_invalid_skills, #validate_all, #validate_resource

Constructor Details

#initialize(storage_path:, manifest_file: "manifest.json") ⇒ Vault

Creates a new Vault instance.

Examples:

vault = Vault.new(storage_path: "/path/to/vault")

Raises:



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/agents_skill_vault/vault.rb', line 44

def initialize(storage_path:, manifest_file: "manifest.json")
  @storage_path = File.expand_path(storage_path)
  FileUtils.mkdir_p(@storage_path)
  @manifest_path = File.join(@storage_path, manifest_file)
  @manifest = Manifest.new(path: @manifest_path)
  @manifest.save(default_manifest_data) unless File.exist?(@manifest_path)

  GitOperations.check_git_available!
  GitOperations.check_git_version!

  validate_all if File.exist?(@manifest_path) && !list_unvalidated.empty?
end

Instance Attribute Details

#manifestManifest (readonly)



32
33
34
# File 'lib/agents_skill_vault/vault.rb', line 32

def manifest
  @manifest
end

#storage_pathString (readonly)



29
30
31
# File 'lib/agents_skill_vault/vault.rb', line 29

def storage_path
  @storage_path
end

Instance Method Details

#add(url, label: nil) ⇒ Resource+

Adds a new resource from a GitHub URL.

Clones the repository or performs a sparse checkout for folders/files, validates skills if present, then adds the resource to the manifest.

For repositories, scans for all SKILL.md files and creates separate entries for each. For folders and files, validates if they contain a SKILL.md.

Examples:

Add a full repository with skills

resources = vault.add("https://github.com/user/repo")

Add a specific folder with skill

resource = vault.add("https://github.com/user/repo/tree/main/skills/my-skill")

Add a SKILL.md file

resource = vault.add("https://github.com/user/repo/blob/main/skills/my-skill/SKILL.md")

Raises:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/agents_skill_vault/vault.rb', line 80

def add(url, label: nil)
  parsed_url = UrlParser.parse(url)

  case parsed_url.type
  when :repo
    add_repository_resource(parsed_url, label: label)
  when :folder
    add_folder_resource(parsed_url, label: label)
  when :file
    add_file_resource(parsed_url, label: label)
  else
    raise Errors::InvalidUrl, "Unknown URL type: #{parsed_url.type}"
  end
end

#fetch(label) ⇒ Resource

Retrieves a resource by its label, raising an error if not found.

Examples:

resource = vault.fetch("user/repo")
puts resource.local_path

Raises:



195
196
197
198
199
200
# File 'lib/agents_skill_vault/vault.rb', line 195

def fetch(label)
  find_by_label(label) || raise(Errors::NotFound, "Resource '#{label}' not found in vault at #{storage_path}. " \
                                               "Available labels: #{list.map(&:label).join(", ").then do |s|
                                                 s.empty? ? "(none)" : s
                                               end}")
end

#filter_by_repo(repo_name) ⇒ Array<Resource>

Filters resources by repository name.

Examples:

vault.filter_by_repo("dotfiles")


127
128
129
# File 'lib/agents_skill_vault/vault.rb', line 127

def filter_by_repo(repo_name)
  list.select { |r| r.repo == repo_name }
end

#filter_by_skill_name(name) ⇒ Array<Resource>

Filters resources by skill name.



168
169
170
# File 'lib/agents_skill_vault/vault.rb', line 168

def filter_by_skill_name(name)
  list.select { |r| r.skill_name == name }
end

#filter_by_username(username) ⇒ Array<Resource>

Filters resources by GitHub username.

Examples:

vault.filter_by_username("octocat")
# => [Resource(label: "octocat/repo1"), Resource(label: "octocat/repo2")]


115
116
117
# File 'lib/agents_skill_vault/vault.rb', line 115

def filter_by_username(username)
  list.select { |r| r.username == username }
end

#find_by_label(label) ⇒ Resource?

Finds a resource by its label without raising an error.

Examples:

resource = vault.find_by_label("user/repo")
puts resource&.local_path


181
182
183
# File 'lib/agents_skill_vault/vault.rb', line 181

def find_by_label(label)
  manifest.find_resource(label)
end

#listArray<Resource>

Lists all resources in the vault.

Examples:

vault.list.each { |r| puts r.label }


102
103
104
# File 'lib/agents_skill_vault/vault.rb', line 102

def list
  manifest.resources.map { |r| Resource.from_h(r, storage_path: storage_path) }
end

#list_invalid_skillsArray<Resource>

Lists all invalid skills.



143
144
145
# File 'lib/agents_skill_vault/vault.rb', line 143

def list_invalid_skills
  list.select { |r| r.validation_status == :invalid_skill }
end

#list_non_skillsArray<Resource>

Lists all non-skill resources.



151
152
153
# File 'lib/agents_skill_vault/vault.rb', line 151

def list_non_skills
  list.select { |r| r.validation_status == :not_a_skill }
end

#list_unvalidatedArray<Resource>

Lists all unvalidated resources.



159
160
161
# File 'lib/agents_skill_vault/vault.rb', line 159

def list_unvalidated
  list.select { |r| r.validation_status == :unvalidated }
end

#list_valid_skillsArray<Resource>

Lists all valid skills.



135
136
137
# File 'lib/agents_skill_vault/vault.rb', line 135

def list_valid_skills
  list.select { |r| r.validation_status == :valid_skill }
end

#remove(label, delete_files: false) ⇒ Object

Removes a resource from vault.

Examples:

Remove from manifest only (keep files)

vault.remove("user/repo")

Remove from manifest and delete files

vault.remove("user/repo", delete_files: true)

Raises:



250
251
252
253
254
255
256
# File 'lib/agents_skill_vault/vault.rb', line 250

def remove(label, delete_files: false)
  resource = fetch(label)

  FileUtils.rm_rf(resource.local_path) if delete_files && resource.local_path

  manifest.remove_resource(label)
end

#sync(label) ⇒ SyncResult

Syncs a resource by pulling the latest changes from GitHub.

For repository-type resources, re-scans for new skills and re-validates existing ones. For folder and file-type resources, re-validates the skill if present.

Examples:

result = vault.sync("user/repo")
puts "Synced successfully" if result.success?

Raises:



215
216
217
218
# File 'lib/agents_skill_vault/vault.rb', line 215

def sync(label)
  resource = fetch(label)
  sync_resource(resource)
end

#sync_allHash{String => SyncResult}

Syncs all resources in the vault.

Examples:

results = vault.sync_all
results.each do |label, result|
  puts "#{label}: #{result.success? ? 'OK' : result.error}"
end


230
231
232
233
234
235
236
# File 'lib/agents_skill_vault/vault.rb', line 230

def sync_all
  results = {}
  list.each do |resource|
    results[resource.label] = sync_resource(resource)
  end
  results
end