No release in over 3 years
AgentsSkillVault provides a simple interface to clone, sync, and manage AI agent skills stored in GitHub repositories, supporting full repos, folders, and individual files.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 2.0

Runtime

 Project Readme

AgentsSkillVault

A Ruby gem for managing a local vault of GitHub resources that contains Agent Skill specifications. Clone entire repositories or specific folders, keep them synced, and query them by username or repository name.

Currently works only with Github. Future plans will include to support any Git based repository.

Overview

AgentsSkillVault helps you maintain a local collection of GitHub resources (repositories, folders, or files) with:

  • Easy addition - Add resources via GitHub URL
  • Sparse checkout - Clone only the folders you need, not entire repos
  • Sync management - Pull latest changes with one command
  • Querying - Filter resources by username or repository name
  • Manifest tracking - All resources tracked in a JSON manifest for portability

Currently this has been tested on MacOS. I would assume it works on Linux. Probably it does not work on Window.

Installation

Add this line to your application's Gemfile:

gem "agents_skill_vault"

And then execute:

bundle install

Or install it yourself:

gem install agents_skill_vault

Requirements:

  • Ruby 3.4+
  • Git 2.25.0+ (for sparse checkout support)

Quick Start

require "agents_skill_vault"

# Create a vault in a directory
vault = AgentsSkillVault::Vault.new(storage_path: "~/.my_vault")

# Let's assume we have this Github Repo

# that has this organisation
# .
# ├── LICENSE
#└── skills
#    ├── commit-message
#    │   └── SKILL.md
#    ├── improving-testing
#    │   └── SKILL.md
#    └── pr-description
#        └── SKILL.md

# Add a full repository
vault.add("https://github.com/lucianghinda/agentic-skills")

# But you can also add a specific skill
# Add a specific folder and even add a custom label
vault.add(
  "https://github.com/nateberkopec/dotfiles/tree/main/files/home/.claude/skills/readme-writer",
  label: "readme-writer"
)

# List all resources
vault.list.each do |resource|
  puts "#{resource.label} -> #{resource.local_path}"
end

# This will output

# lucianghinda/agentic-skills/commit-message -> /Users/lucian/.my_vault/lucianghinda/agentic-skills
# lucianghinda/agentic-skills/improving-testing -> /Users/lucian/.my_vault/lucianghinda/agentic-skills
# lucianghinda/agentic-skills/pr-description -> /Users/lucian/.my_vault/lucianghinda/agentic-skills
# readme-writer -> /Users/Lucian/.my_vault/nateberkopec/dotfiles/files/home/.claude/skills/readme-writer

# Sync a specific resource
result = vault.sync("rails/rails")
puts "Synced!" if result.success?

# Sync all resources
vault.sync_all

API Reference

Vault

The main interface for managing resources.

Creating a Vault

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

Adding Resources

# Add a repository (auto-generates label: "username/repo")
vault.add("https://github.com/user/repo")

# Add with custom label
vault.add("https://github.com/user/repo", label: "my-custom-label")

# Add a specific folder (uses sparse checkout)
vault.add("https://github.com/user/repo/tree/main/lib/skills")

# Add a specific file
vault.add("https://github.com/user/repo/blob/main/config.yml")

Querying Resources

# List all resources
resources = vault.list

# Find by label (returns nil if not found)
resource = vault.find_by_label("user/repo")

# Fetch by label (raises Errors::NotFound if not found)
resource = vault.fetch("user/repo")

# Filter by GitHub username
vault.filter_by_username("octocat")  # => [Resource, ...]

# Filter by repository name
vault.filter_by_repo("dotfiles")  # => [Resource, ...]

Syncing Resources

# Sync a single resource
result = vault.sync("user/repo")
if result.success?
  puts "Changes: #{result.changes?}"
else
  puts "Error: #{result.error}"
end

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

Removing Resources

# Remove from manifest only (keep files on disk)
vault.remove("user/repo")

# Remove from manifest AND delete files
vault.remove("user/repo", delete_files: true)

Backup and Restore

# Export manifest for backup
vault.export_manifest("/backups/manifest.json")

# Import manifest (merges with existing resources)
vault.import_manifest("/shared/manifest.json")

# Re-download all resources from scratch
vault.redownload_all

Resource

Represents a tracked GitHub resource.

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

resource.label          # => "user/repo"
resource.url            # => "https://github.com/user/repo"
resource.username       # => "user"
resource.repo           # => "repo"
resource.type           # => :repo, :folder, or :file
resource.branch         # => "main"
resource.local_path     # => "/vault/user/repo"
resource.relative_path  # => nil (or path within repo for folders/files)
resource.added_at       # => Time
resource.synced_at      # => Time

SyncResult

Returned by sync operations.

result = vault.sync("user/repo")

result.success?  # => true/false
result.changes?  # => true/false (did the sync pull new changes?)
result.error     # => nil or error message string

Error Handling

begin
  vault.add("invalid-url")
rescue AgentsSkillVault::Errors::InvalidUrl => e
  puts "Bad URL: #{e.message}"
end

begin
  vault.fetch("nonexistent")
rescue AgentsSkillVault::Errors::NotFound => e
  puts "Not found: #{e.message}"
end

begin
  vault.add("https://github.com/user/repo")
  vault.add("https://github.com/other/thing", label: "user/repo")
rescue AgentsSkillVault::Errors::DuplicateLabel => e
  puts "Duplicate: #{e.message}"
end

Common Use Cases

Managing Claude Code Skills

vault = AgentsSkillVault::Vault.new(storage_path: "~/.claude/skill_vault")

# Add skills from various sources
vault.add("https://github.com/anthropics/claude-code/tree/main/skills/web-search")
vault.add("https://github.com/user/my-skills/tree/main/coding-assistant", label: "coding")

# Keep everything up to date
vault.sync_all

Sharing Resource Collections

# On machine A: Export your vault configuration
vault.export_manifest("~/Dropbox/vault-manifest.json")

# On machine B: Import and download
new_vault = AgentsSkillVault::Vault.new(storage_path: "~/.vault")
new_vault.import_manifest("~/Dropbox/vault-manifest.json")
new_vault.redownload_all

Selective Repository Checkout

# Instead of cloning a huge monorepo, just get the folder you need
vault.add(
  "https://github.com/big-org/monorepo/tree/main/packages/useful-lib",
  label: "useful-lib"
)

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests.

bundle exec rake test

You can also run bin/console for an interactive prompt.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/lucianghinda/agents_skill_vault.

License

The gem is available as open source under the terms of the Apache 2.0 License.