skillme 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 114461d15862bc97dd38791b09feb6920983fe95c0a5cdd87a3338f48fb5fbb8
4
+ data.tar.gz: 6d1fb4e10336c2f7ed9522041411901014fd96a0557627a47f7ae2164b26c932
5
+ SHA512:
6
+ metadata.gz: 053ec30034ed3b461a927ceac34c997d002d6443c7cc702e95e967d8d4c015b9b90c9aeea9b4439e784a067166fc7b90295c297836e1a4db83acdc545b8fe43d
7
+ data.tar.gz: a9a8ee3f27643c6628fd621c4fa7af789597dbb6b06d87cc0d741eaff02fa1089d9c131e07194d7d5e6443e4b4136165a8fe7f8f8dd871da1bf562049916a755
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alan Alves
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # skillme
2
+
3
+ Claude Code skills written in Ruby. Zero gems, zero magic.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install skillme
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ # List available skills
15
+ skillme list
16
+
17
+ # Install a skill (global — works in all projects)
18
+ skillme install spreadsheet
19
+
20
+ # Install for current project only
21
+ skillme install spreadsheet --local
22
+
23
+ # Remove a skill
24
+ skillme remove spreadsheet
25
+ ```
26
+
27
+ After installing, use `/spreadsheet` (or any skill name) directly in Claude Code.
28
+
29
+ ## Available Skills
30
+
31
+ | Skill | Description |
32
+ |-------|-------------|
33
+ | spreadsheet | Read and write Google Sheets via REST API |
34
+
35
+ ## Why Ruby
36
+
37
+ Ruby's stdlib is surprisingly powerful. `net/http`, `openssl`, `json`, `base64` — everything you need to talk to REST APIs is already there. No gem install, no bundler, no dependency hell.
38
+
39
+ These skills prove a point: you don't need Python or TypeScript to build useful AI tooling. Ruby works. And if you already have Ruby installed (you probably do), these skills just work.
40
+
41
+ ## How It Works
42
+
43
+ Skills are stored in this repository under `skills/`. The `skillme` gem is a thin CLI that fetches individual skills from GitHub and installs them to `~/.claude/skills/` (or `.claude/skills/` with `--local`).
44
+
45
+ The skills themselves use **zero gems** — pure Ruby stdlib. The gem is just the installer.
46
+
47
+ ## Creating a Skill
48
+
49
+ Each skill follows this structure:
50
+
51
+ ```
52
+ skills/
53
+ └── your-skill/
54
+ ├── SKILL.md # Instructions for Claude
55
+ └── scripts/
56
+ └── your_script.rb # Ruby scripts (stdlib only)
57
+ ```
58
+
59
+ ### Conventions
60
+
61
+ - **Ruby stdlib only** — no gems, no Gemfile, no bundler
62
+ - **Scripts are self-contained** — each script does one thing
63
+ - **SKILL.md is the interface** — Claude reads this to know how to use your skill
64
+ - **Paths use `~/.claude/skills/`** — scripts reference their installed location
65
+
66
+ ## Author
67
+
68
+ **Alan Alves** — [GitHub](https://github.com/alanalvestech) · [X](https://x.com/alanalvestech)
69
+
70
+ ## License
71
+
72
+ [MIT](LICENSE)
data/bin/skillme ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/skillme/cli'
4
+
5
+ Skillme::CLI.new.run(ARGV)
@@ -0,0 +1,176 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'fileutils'
5
+ require_relative 'version'
6
+
7
+ module Skillme
8
+ class CLI
9
+ REPO = "alanalvestech/skillme"
10
+ BRANCH = "main"
11
+ GLOBAL_DIR = File.expand_path("~/.claude/skills")
12
+ LOCAL_DIR = ".claude/skills"
13
+
14
+ def run(args)
15
+ command = args.shift
16
+
17
+ case command
18
+ when "install" then install(args)
19
+ when "remove" then remove(args)
20
+ when "list" then list
21
+ when "version" then puts "skillme v#{VERSION}"
22
+ when "help", nil then help
23
+ else
24
+ warn "Unknown command: #{command}"
25
+ help
26
+ exit 1
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def install(args)
33
+ local = args.delete("--local")
34
+ name = args.first
35
+
36
+ abort "Usage: skillme install SKILL [--local]" unless name
37
+
38
+ target = local ? LOCAL_DIR : GLOBAL_DIR
39
+ skill_dir = File.join(target, name)
40
+
41
+ if Dir.exist?(skill_dir)
42
+ warn "Skill '#{name}' already installed at #{skill_dir}"
43
+ warn "Remove it first: skillme remove #{name}#{local ? ' --local' : ''}"
44
+ exit 1
45
+ end
46
+
47
+ puts "Fetching skill '#{name}' from #{REPO}..."
48
+
49
+ files = fetch_skill_files(name)
50
+ abort "Skill '#{name}' not found in the repository." if files.empty?
51
+
52
+ FileUtils.mkdir_p(skill_dir)
53
+
54
+ files.each do |path, content|
55
+ relative = path.sub("skills/#{name}/", "")
56
+ file_path = File.join(skill_dir, relative)
57
+ FileUtils.mkdir_p(File.dirname(file_path))
58
+ File.write(file_path, content)
59
+ end
60
+
61
+ puts "Installed '#{name}' to #{skill_dir}"
62
+ puts "Use /#{name} in Claude Code to get started."
63
+ end
64
+
65
+ def remove(args)
66
+ local = args.delete("--local")
67
+ name = args.first
68
+
69
+ abort "Usage: skillme remove SKILL [--local]" unless name
70
+
71
+ target = local ? LOCAL_DIR : GLOBAL_DIR
72
+ skill_dir = File.join(target, name)
73
+
74
+ unless Dir.exist?(skill_dir)
75
+ abort "Skill '#{name}' not found at #{skill_dir}"
76
+ end
77
+
78
+ FileUtils.rm_rf(skill_dir)
79
+ puts "Removed '#{name}' from #{skill_dir}"
80
+ end
81
+
82
+ def list
83
+ puts "Available skills in #{REPO}:\n\n"
84
+
85
+ skills = fetch_skill_list
86
+ if skills.empty?
87
+ puts " (none found)"
88
+ return
89
+ end
90
+
91
+ skills.each do |skill|
92
+ puts " #{skill[:name].ljust(20)} #{skill[:description]}"
93
+ end
94
+
95
+ puts "\nInstall with: skillme install SKILL_NAME"
96
+ end
97
+
98
+ def help
99
+ puts <<~HELP
100
+ skillme v#{VERSION}
101
+ Claude Code skills written in Ruby. Zero gems, zero magic.
102
+
103
+ Commands:
104
+ install SKILL [--local] Install a skill (~/.claude/skills/ by default)
105
+ remove SKILL [--local] Remove an installed skill
106
+ list List available skills
107
+ version Show version
108
+ help Show this help
109
+ HELP
110
+ end
111
+
112
+ def fetch_skill_files(name)
113
+ tree = fetch_github_tree
114
+ prefix = "skills/#{name}/"
115
+
116
+ files = {}
117
+ tree.select { |item| item["path"].start_with?(prefix) && item["type"] == "blob" }.each do |item|
118
+ content = fetch_github_file(item["path"])
119
+ files[item["path"]] = content
120
+ end
121
+ files
122
+ end
123
+
124
+ def fetch_skill_list
125
+ tree = fetch_github_tree
126
+ skill_dirs = tree
127
+ .select { |item| item["path"].match?(%r{^skills/[^/]+$}) && item["type"] == "tree" }
128
+ .map { |item| item["path"].sub("skills/", "") }
129
+
130
+ skill_dirs.map do |name|
131
+ skill_md = tree.find { |item| item["path"] == "skills/#{name}/SKILL.md" }
132
+ description = if skill_md
133
+ content = fetch_github_file(skill_md["path"])
134
+ extract_description(content)
135
+ else
136
+ "(no description)"
137
+ end
138
+ { name: name, description: description }
139
+ end
140
+ end
141
+
142
+ def extract_description(skill_md_content)
143
+ if skill_md_content =~ /^description:\s*(.+)$/
144
+ $1.strip
145
+ else
146
+ "(no description)"
147
+ end
148
+ end
149
+
150
+ def fetch_github_tree
151
+ uri = URI("https://api.github.com/repos/#{REPO}/git/trees/#{BRANCH}?recursive=1")
152
+ response = github_get(uri)
153
+ data = JSON.parse(response.body)
154
+ data["tree"] || []
155
+ end
156
+
157
+ def fetch_github_file(path)
158
+ uri = URI("https://raw.githubusercontent.com/#{REPO}/#{BRANCH}/#{path}")
159
+ github_get(uri).body
160
+ end
161
+
162
+ def github_get(uri)
163
+ req = Net::HTTP::Get.new(uri)
164
+ req["User-Agent"] = "skillme/#{VERSION}"
165
+ req["Accept"] = "application/vnd.github.v3+json"
166
+
167
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
168
+
169
+ unless response.is_a?(Net::HTTPSuccess)
170
+ abort "GitHub API error: #{response.code} #{response.message}"
171
+ end
172
+
173
+ response
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,3 @@
1
+ module Skillme
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skillme
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alan Alves
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: A CLI to install Claude Code skills written in pure Ruby (stdlib only).
13
+ Skills are fetched from GitHub and installed to ~/.claude/skills/.
14
+ email:
15
+ - alanalvestech@gmail.com
16
+ executables:
17
+ - skillme
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE
22
+ - README.md
23
+ - bin/skillme
24
+ - lib/skillme/cli.rb
25
+ - lib/skillme/version.rb
26
+ homepage: https://github.com/alanalvestech/skillme
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ source_code_uri: https://github.com/alanalvestech/skillme
31
+ bug_tracker_uri: https://github.com/alanalvestech/skillme/issues
32
+ changelog_uri: https://github.com/alanalvestech/skillme/releases
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.6.9
48
+ specification_version: 4
49
+ summary: Claude Code skills written in Ruby. Zero gems, zero magic.
50
+ test_files: []