Class: Rubino::CLI::SkillsCommand
- Inherits:
-
Thor
- Object
- Thor
- Rubino::CLI::SkillsCommand
- Defined in:
- lib/rubino/cli/skills_command.rb
Overview
Subcommands for managing skills (#188). ‘list` mirrors the in-chat /skills disclosure (enabled/disabled markers), `show` prints a skill’s SKILL.md body (trust review before enabling), and ‘enable`/`disable` run the SAME registry-validated StateRepository write the HTTP API toggle and the in-chat `/skills enable|disable` use (Skills::Toggle) —no new logic, just the missing terminal surface.
‘install`/`update`/`remove` (#4) manage skills fetched from git repos (Skills::Installer): any repo shipping the registry’s ‘<name>/SKILL.md` layout is a source — no marketplace, nothing vendored in the gem.
Constant Summary collapse
- DOCUMENTS_SOURCE =
The ‘–documents` shorthand (#4): Anthropic’s four document skills.
"anthropics/skills"- DOCUMENT_SKILLS =
%w[pdf docx pptx xlsx].freeze
Class Method Summary collapse
Instance Method Summary collapse
- #disable(name) ⇒ Object
- #enable(name) ⇒ Object
- #install(source = nil) ⇒ Object
- #list ⇒ Object
- #remove(name) ⇒ Object
- #show(name) ⇒ Object
- #update(*names) ⇒ Object
Class Method Details
.exit_on_failure? ⇒ Boolean
25 26 27 |
# File 'lib/rubino/cli/skills_command.rb', line 25 def self.exit_on_failure? true end |
Instance Method Details
#disable(name) ⇒ Object
65 66 67 |
# File 'lib/rubino/cli/skills_command.rb', line 65 def disable(name) toggle(name, enabled: false) end |
#enable(name) ⇒ Object
60 61 62 |
# File 'lib/rubino/cli/skills_command.rb', line 60 def enable(name) toggle(name, enabled: true) end |
#install(source = nil) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/rubino/cli/skills_command.rb', line 76 def install(source = nil) wanted = Array([:skill]) if [:documents] source ||= DOCUMENTS_SOURCE wanted = DOCUMENT_SKILLS.dup if wanted.empty? end if source.nil? Rubino.ui.error("missing source — pass owner/repo, a git URL, or --documents") return end installer = Skills::Installer.new fetched = installer.fetch(source) do |checkout, sha| found = installer.discover(checkout) if found.empty? Rubino.ui.warning("no skills found in #{source} (expected <name>/SKILL.md directories)") elsif [:list] discovered_table(found) else install_selected(installer, found, wanted, checkout: checkout, source: source, commit: sha) end true end Rubino.ui.error("could not fetch #{source} — check the source name/URL and your network") if fetched.nil? end |
#list ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/rubino/cli/skills_command.rb', line 30 def list Rubino.ensure_database_ready! registry = Skills::Registry.trusted skills = registry.all if skills.empty? Rubino.ui.info("No skills found.") Rubino.ui.info("Add .md files to .rubino/skills/ to create skills.") return end sources = Skills::Installer.new.sources rows = skills.map do |skill| [skill.name, skill_status(skill.name, registry), provenance(skill.name, sources), skill.description.to_s] end Rubino.ui.table(headers: %w[Name Status Source Description], rows: rows) end |
#remove(name) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/rubino/cli/skills_command.rb', line 121 def remove(name) installer = Skills::Installer.new if installer.remove(name) Rubino.ui.success("Removed skill: #{name}") return end Rubino.ui.error("#{name} wasn't installed via `rubino skills install` (no provenance entry)") dir = File.join(installer.skills_dir, name) Rubino.ui.info("It exists at #{dir} — delete the directory manually.") if File.directory?(dir) end |
#show(name) ⇒ Object
49 50 51 52 53 54 55 56 57 |
# File 'lib/rubino/cli/skills_command.rb', line 49 def show(name) skill = Skills::Registry.trusted.find(name) if skill.nil? Rubino.ui.error("unknown skill: #{name}") return end Rubino.ui.info(skill.content) end |
#update(*names) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/rubino/cli/skills_command.rb', line 103 def update(*names) installer = Skills::Installer.new if installer.sources.empty? Rubino.ui.info("No skills installed via `rubino skills install` yet.") return end installer.update(names).each do |name, status| case status when :updated then Rubino.ui.success("Updated skill: #{name}") when :up_to_date then Rubino.ui.info("#{name} is up to date.") when :unknown then Rubino.ui.error("unknown skill: #{name} (not installed via `rubino skills install`)") else Rubino.ui.error("could not update #{name} — fetch failed or the skill left its source") end end end |