Class: ZipSkillInstaller
- Inherits:
-
Object
- Object
- ZipSkillInstaller
- Defined in:
- lib/clacky/default_skills/skill-add/scripts/install_from_zip.rb
Overview
Install a skill from a remote zip archive URL. Usage: ruby install_from_zip.rb <zip_url>
The zip archive is expected to contain a skill directory at its root, e.g.:
my-skill/
SKILL.md
scripts/
Or the archive may contain multiple skill directories (each with a SKILL.md).
Constant Summary collapse
- ZIP_URL_PATTERN =
%r{^https?://.+\.zip(\?.*)?$}i
Instance Method Summary collapse
-
#initialize(zip_source, skill_name: nil, target_dir: nil) ⇒ ZipSkillInstaller
constructor
A new instance of ZipSkillInstaller.
-
#install ⇒ Object
Main installation entry point.
Constructor Details
#initialize(zip_source, skill_name: nil, target_dir: nil) ⇒ ZipSkillInstaller
Returns a new instance of ZipSkillInstaller.
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/clacky/default_skills/skill-add/scripts/install_from_zip.rb', line 22 def initialize(zip_source, skill_name: nil, target_dir: nil) @zip_source = zip_source @local_path = local_zip_path?(zip_source) # skill_name can be provided explicitly (e.g. slug from the store API). # If not provided, we try to infer it from the filename in the URL/path, e.g. # "ui-ux-pro-max-1.0.0.zip" → "ui-ux-pro-max". @skill_name = skill_name || infer_skill_name(zip_source) @target_dir = target_dir || File.join(Dir.home, '.clacky', 'skills') @installed_skills = [] @errors = [] end |
Instance Method Details
#install ⇒ Object
Main installation entry point.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/clacky/default_skills/skill-add/scripts/install_from_zip.rb', line 35 def install if @local_path # Install directly from a local zip file — no download needed. # Expand tilde in path (e.g. ~/Downloads/skill.zip) = File.(@zip_source) raise ArgumentError, "File not found: #{@zip_source}" unless File.exist?() raise ArgumentError, "Not a zip file: #{@zip_source}" unless .end_with?('.zip') Dir.mktmpdir('clacky-zip-') do |tmpdir| extract_zip(, tmpdir) extracted_dir = File.join(tmpdir, 'extracted') discover_and_install_skills(extracted_dir) end else # Install from a remote URL. unless valid_zip_url? raise ArgumentError, "Invalid zip source: #{@zip_source}\nProvide an http(s) URL ending with .zip, or an absolute path to a local zip file." end Dir.mktmpdir('clacky-zip-') do |tmpdir| zip_path = download_zip(tmpdir) extract_zip(zip_path, tmpdir) extracted_dir = File.join(tmpdir, 'extracted') discover_and_install_skills(extracted_dir) end end report_results rescue ArgumentError => e puts "❌ #{e.}" exit 1 rescue StandardError => e puts "❌ Installation failed: #{e.}" exit 1 end |