ruby_llm-skills 0.4.0.pre1 → 0.5.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Plugin marketplaces from the command line:
4
+ #
5
+ # rake skills:marketplaces:add[EveryInc/compound-writing] # record a marketplace
6
+ # rake skills:marketplaces:add[typesafe-ai/skills,v0.5.7] # pinned to a tag or commit
7
+ # rake skills:marketplaces:list # what is recorded and installed
8
+ # rake skills:marketplaces:plugins[compound-writing] # the plugins a marketplace lists
9
+ # rake skills:marketplaces:install[compound-writing] # every supported plugin
10
+ # rake skills:marketplaces:install[compound-writing,cw-draft] # selected plugins (space separated)
11
+ # rake skills:marketplaces:install # reproduce the lockfile
12
+ # rake skills:marketplaces:update # move unpinned marketplaces forward
13
+ # rake skills:marketplaces:remove[compound-writing]
14
+ #
15
+ # Under Rails the tasks load the environment first, so the root and lockfile
16
+ # resolve against Rails.root.
17
+ namespace :skills do
18
+ namespace :marketplaces do
19
+ prerequisites = Rake::Task.task_defined?(:environment) ? [:environment] : []
20
+
21
+ registry = -> { RubyLLM::Skills.marketplaces }
22
+
23
+ report = lambda do |result|
24
+ result.installed.each { |key| puts " + #{key}" }
25
+ result.updated.each { |key| puts " ~ #{key}" }
26
+ result.unchanged.each { |key| puts " = #{key}" }
27
+ result.skipped.each { |key, reason| puts " - #{key}: #{reason}" }
28
+ result.errors.each { |key, message| puts " ! #{key}: #{message}" }
29
+ abort("#{result.errors.size} plugin(s) failed") unless result.success?
30
+ end
31
+
32
+ desc "Add a marketplace (owner/repo, owner/repo@ref, repository URL, hosted marketplace.json URL, or directory)"
33
+ task :add, [:locator, :ref] => prerequisites do |_, args|
34
+ abort("Usage: rake skills:marketplaces:add[locator,ref]") unless args[:locator]
35
+
36
+ record = registry.call.add(args[:locator], ref: args[:ref])
37
+ puts "Added #{record.name} from #{record.source} at #{record.commit[0, 12]}"
38
+ puts "Install with: rake skills:marketplaces:install[#{record.name}]"
39
+ end
40
+
41
+ desc "List the recorded marketplaces and their installed plugins"
42
+ task list: prerequisites do
43
+ records = registry.call.list
44
+ if records.empty?
45
+ puts "No marketplaces in #{registry.call.lockfile_path}"
46
+ next
47
+ end
48
+
49
+ records.each do |record|
50
+ pin = record.pinned? ? " (pinned)" : ""
51
+ puts "#{record.name} #{record.source} @#{record.commit.to_s[0, 12]}#{pin}"
52
+ record.plugins.each_value do |plugin|
53
+ puts " #{plugin.name} #{plugin.version} skills: #{plugin.skills.join(", ")}"
54
+ end
55
+ end
56
+ end
57
+
58
+ desc "List the plugins a marketplace offers"
59
+ task :plugins, [:name] => prerequisites do |_, args|
60
+ abort("Usage: rake skills:marketplaces:plugins[marketplace]") unless args[:name]
61
+
62
+ record = registry.call.fetch(args[:name])
63
+ registry.call.plugins(record.name).each do |entry|
64
+ state = if record.plugins.key?(entry.name)
65
+ "installed"
66
+ elsif entry.supported?
67
+ "available"
68
+ else
69
+ "unsupported (#{entry.source.reason})"
70
+ end
71
+ puts "#{entry.name} #{entry.version || "-"} #{state}"
72
+ puts " #{entry.description}" if entry.description
73
+ end
74
+ end
75
+
76
+ desc "Install a marketplace's plugins (all, or the space separated names), or reproduce the lockfile"
77
+ task :install, [:name, :plugins] => prerequisites do |_, args|
78
+ only = args[:plugins]&.split
79
+ report.call(registry.call.install(args[:name], only: only))
80
+ end
81
+
82
+ desc "Update every marketplace (or one) to its ref's current head"
83
+ task :update, [:name] => prerequisites do |_, args|
84
+ report.call(registry.call.update(args[:name]))
85
+ end
86
+
87
+ desc "Remove a marketplace and its installed plugins"
88
+ task :remove, [:name] => prerequisites do |_, args|
89
+ abort("Usage: rake skills:marketplaces:remove[marketplace]") unless args[:name]
90
+
91
+ record = registry.call.remove(args[:name])
92
+ puts "Removed #{record.name}"
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Loads the gem's Rake tasks outside Rails (the Railtie loads them under Rails):
4
+ #
5
+ # # Rakefile
6
+ # require "ruby_llm/skills/tasks"
7
+ #
8
+ require "ruby_llm/skills"
9
+
10
+ load File.expand_path("tasks/skills.rake", __dir__)
11
+ load File.expand_path("tasks/marketplaces.rake", __dir__)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyLLM
4
4
  module Skills
5
- VERSION = "0.4.0.pre1"
5
+ VERSION = "0.5.0.pre1"
6
6
  end
7
7
  end
@@ -11,6 +11,7 @@ require_relative "skills/loader"
11
11
  require_relative "skills/filesystem_loader"
12
12
  require_relative "skills/chat_extensions"
13
13
  require_relative "skills/agent_extensions"
14
+ require_relative "skills/marketplace"
14
15
 
15
16
  # Load Rails integration when Rails is available
16
17
  require_relative "skills/railtie" if defined?(Rails::Railtie)
@@ -73,6 +74,28 @@ module RubyLLM
73
74
  require_relative "skills/composite_loader"
74
75
  CompositeLoader.new(loaders)
75
76
  end
77
+
78
+ # The plugin marketplaces recorded in a lockfile and installed under a root.
79
+ #
80
+ # @param root [String] where plugins are installed (default: vendor/skills)
81
+ # @param lockfile [String] the lockfile (default: skills.lock.json)
82
+ # @return [Marketplace::Registry]
83
+ # @example
84
+ # marketplaces = RubyLLM::Skills.marketplaces
85
+ # marketplaces.add("EveryInc/compound-writing")
86
+ # marketplaces.install("compound-writing")
87
+ def marketplaces(root: Marketplace.root, lockfile: Marketplace.lockfile)
88
+ Marketplace::Registry.new(root: root, lockfile: lockfile)
89
+ end
90
+
91
+ # Load the skills of every installed marketplace plugin.
92
+ #
93
+ # @return [Loader] loader over the installed plugins' skills
94
+ # @example
95
+ # chat.with_skills("app/skills", RubyLLM::Skills.from_marketplaces)
96
+ def from_marketplaces(root: Marketplace.root, lockfile: Marketplace.lockfile)
97
+ marketplaces(root: root, lockfile: lockfile).loader
98
+ end
76
99
  end
77
100
 
78
101
  self.default_path = "app/skills"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_llm-skills
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.pre1
4
+ version: 0.5.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kieran Klaassen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-10 00:00:00.000000000 Z
11
+ date: 2026-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_llm
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.0.rc2
19
+ version: 2.0.0.rc3
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '3'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 2.0.0.rc2
29
+ version: 2.0.0.rc3
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '3'
@@ -53,11 +53,25 @@ files:
53
53
  - lib/ruby_llm/skills/error.rb
54
54
  - lib/ruby_llm/skills/filesystem_loader.rb
55
55
  - lib/ruby_llm/skills/loader.rb
56
+ - lib/ruby_llm/skills/marketplace.rb
57
+ - lib/ruby_llm/skills/marketplace/bundle.rb
58
+ - lib/ruby_llm/skills/marketplace/config.rb
59
+ - lib/ruby_llm/skills/marketplace/fetcher.rb
60
+ - lib/ruby_llm/skills/marketplace/github_repo.rb
61
+ - lib/ruby_llm/skills/marketplace/gitlab_repo.rb
62
+ - lib/ruby_llm/skills/marketplace/http.rb
63
+ - lib/ruby_llm/skills/marketplace/locator.rb
64
+ - lib/ruby_llm/skills/marketplace/lockfile.rb
65
+ - lib/ruby_llm/skills/marketplace/manifest.rb
66
+ - lib/ruby_llm/skills/marketplace/registry.rb
67
+ - lib/ruby_llm/skills/marketplace/tarball.rb
56
68
  - lib/ruby_llm/skills/parser.rb
57
69
  - lib/ruby_llm/skills/railtie.rb
58
70
  - lib/ruby_llm/skills/skill.rb
59
71
  - lib/ruby_llm/skills/skill_tool.rb
60
72
  - lib/ruby_llm/skills/source_detection.rb
73
+ - lib/ruby_llm/skills/tasks.rb
74
+ - lib/ruby_llm/skills/tasks/marketplaces.rake
61
75
  - lib/ruby_llm/skills/tasks/skills.rake
62
76
  - lib/ruby_llm/skills/validator.rb
63
77
  - lib/ruby_llm/skills/version.rb
@@ -84,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
98
  - !ruby/object:Gem::Version
85
99
  version: 1.3.1
86
100
  requirements: []
87
- rubygems_version: 3.4.10
101
+ rubygems_version: 3.4.20
88
102
  signing_key:
89
103
  specification_version: 4
90
104
  summary: Agent Skills extension for RubyLLM