cm-cli 0.1.0 → 0.1.1
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 +4 -4
- data/README.md +1 -0
- data/bin/cm +2 -2
- data/lib/cm/cli.rb +91 -111
- data/lib/cm/version.rb +2 -3
- data/lib/cm.rb +2 -10
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 28b63899a27804857ab01317dfe7bce64c9b24dd19016a5b93c90a7916a2fb11
|
|
4
|
+
data.tar.gz: 201618a5735f84668404313b3213451dbdcf01aea4e80bd0d68929497057ca6c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b68cc3b6ee826a90495ed244430af96a676daf4db1d074d8db0865cb3725e26c41570957d83a030f257f70b590f6ed83fc9d5dbb993364e1dfbc04efb211d2f8
|
|
7
|
+
data.tar.gz: f8c2943a997d057ae0e349faaf147c955f7714271dfcc480be64586eb80f353f14a8c65fe110addb4259cf4e58d4dd6a780a0ab1302d5b0f7931e8fc939fa81f
|
data/README.md
CHANGED
data/bin/cm
CHANGED
data/lib/cm/cli.rb
CHANGED
|
@@ -1,79 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
4
|
-
require "
|
|
3
|
+
require "thor"
|
|
4
|
+
require "fileutils"
|
|
5
5
|
require "open-uri"
|
|
6
6
|
require "yaml"
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
program :description, "CLI tool for pulling Claude Skill and MCP resources"
|
|
8
|
+
class CmCLI < Thor
|
|
9
|
+
package_name "cm"
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
version "0.1.1"
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
def skills_dir
|
|
18
|
-
File.expand_path("~/.claude/skills")
|
|
19
|
-
end
|
|
13
|
+
default_command :pull
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def config_file
|
|
26
|
-
File.expand_path("~/.claude/config.yaml")
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def github_api_url(path)
|
|
30
|
-
"https://api.github.com/repos#{path}"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def fetch_github_files(owner, repo, path = "")
|
|
34
|
-
url = github_api_url("/#{owner}/#{repo}/contents/#{path}")
|
|
35
|
-
headers = { "Accept" => "application/vnd.github.v3+json", "User-Agent" => "cm-cli" }
|
|
36
|
-
|
|
37
|
-
response = URI.open(url, headers: headers)
|
|
38
|
-
JSON.parse(response.read)
|
|
39
|
-
rescue => e
|
|
40
|
-
puts error "Failed to fetch from GitHub: #{e.message}"
|
|
41
|
-
[]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def download_file(url, local_path)
|
|
45
|
-
FileUtils.mkdir_p(File.dirname(local_path))
|
|
46
|
-
URI.open(url, "rb") { |read| File.open(local_path, "wb") { |write| write.write(read.read) } }
|
|
47
|
-
rescue => e
|
|
48
|
-
puts error "Failed to download #{url}: #{e.message}"
|
|
49
|
-
false
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def info(msg)
|
|
53
|
-
puts "\e[32m[INFO]\e[0m #{msg}"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def success(msg)
|
|
57
|
-
puts "\e[32m[SUCCESS]\e[0m #{msg}"
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def error(msg)
|
|
61
|
-
puts "\e[31m[ERROR]\e[0m #{msg}"
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def warn(msg)
|
|
65
|
-
puts "\e[33m[WARN]\e[0m #{msg}"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def ensure_dir(dir)
|
|
69
|
-
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
desc "pull", "Pull Claude resources (skills and MCP)"
|
|
74
|
-
long_desc: "Pull all Claude skills and MCP configurations from configured repositories"
|
|
75
|
-
command :pull do |c|
|
|
76
|
-
c.action do |args, options|
|
|
15
|
+
desc "pull", "Pull Claude resources (skills and MCP)"
|
|
16
|
+
long_desc "Pull all Claude skills and MCP configurations from configured repositories"
|
|
17
|
+
def pull
|
|
77
18
|
ensure_dir(skills_dir)
|
|
78
19
|
ensure_dir(mcp_dir)
|
|
79
20
|
|
|
@@ -81,9 +22,7 @@ command :pull do |c|
|
|
|
81
22
|
info "Starting to pull Claude resources..."
|
|
82
23
|
puts "#{'=' * 50}\n"
|
|
83
24
|
|
|
84
|
-
# Default repositories
|
|
85
25
|
repositories = [
|
|
86
|
-
# Format: { "owner/repo" => { skills_path: "path", mcp_path: "path" } }
|
|
87
26
|
{ repo: "claude-dev/skills", path: "", type: "skills" },
|
|
88
27
|
{ repo: "anthropics/claude-code", path: "mcp", type: "mcp" }
|
|
89
28
|
]
|
|
@@ -130,12 +69,10 @@ command :pull do |c|
|
|
|
130
69
|
puts " MCP configs pulled: #{pulled_mcp}"
|
|
131
70
|
puts "#{'=' * 50}\n"
|
|
132
71
|
|
|
133
|
-
# Update config if it exists
|
|
134
72
|
if File.file?(config_file)
|
|
135
73
|
puts "\nChecking config file..."
|
|
136
74
|
config = YAML.load_file(config_file) rescue {}
|
|
137
75
|
|
|
138
|
-
# Ensure skills and mcp paths are configured
|
|
139
76
|
config["skills"] ||= []
|
|
140
77
|
config["mcp"] ||= {}
|
|
141
78
|
|
|
@@ -147,19 +84,16 @@ command :pull do |c|
|
|
|
147
84
|
info "Config updated: #{config_file}"
|
|
148
85
|
end
|
|
149
86
|
end
|
|
150
|
-
end
|
|
151
87
|
|
|
152
|
-
desc "
|
|
153
|
-
long_desc
|
|
154
|
-
|
|
155
|
-
c.action do |args, options|
|
|
88
|
+
desc "skills", "Pull only Claude skills"
|
|
89
|
+
long_desc "Pull skills from configured repositories into ~/.claude/skills"
|
|
90
|
+
def skills
|
|
156
91
|
ensure_dir(skills_dir)
|
|
157
92
|
|
|
158
93
|
puts "\n#{'=' * 50}"
|
|
159
94
|
info "Pulling Claude skills..."
|
|
160
95
|
puts "#{'=' * 50}\n"
|
|
161
96
|
|
|
162
|
-
# Default skill repositories
|
|
163
97
|
skill_repos = [
|
|
164
98
|
{ owner: "claude-dev", repo: "skills" },
|
|
165
99
|
{ owner: "anthropics", repo: "claude-code", path: "skills" }
|
|
@@ -183,7 +117,7 @@ command :skills do |c|
|
|
|
183
117
|
local_path = File.join(skills_dir, file["name"])
|
|
184
118
|
|
|
185
119
|
if download_file(file["download_url"], local_path)
|
|
186
|
-
puts "
|
|
120
|
+
puts " #{file['name']}"
|
|
187
121
|
pulled += 1
|
|
188
122
|
end
|
|
189
123
|
end
|
|
@@ -196,19 +130,16 @@ command :skills do |c|
|
|
|
196
130
|
success "Skills pull completed: #{pulled} files"
|
|
197
131
|
puts "#{'=' * 50}\n"
|
|
198
132
|
end
|
|
199
|
-
end
|
|
200
133
|
|
|
201
|
-
desc "
|
|
202
|
-
long_desc
|
|
203
|
-
|
|
204
|
-
c.action do |args, options|
|
|
134
|
+
desc "mcp", "Pull only MCP configurations"
|
|
135
|
+
long_desc "Pull MCP server configurations into ~/.claude/mcp"
|
|
136
|
+
def mcp
|
|
205
137
|
ensure_dir(mcp_dir)
|
|
206
138
|
|
|
207
139
|
puts "\n#{'=' * 50}"
|
|
208
140
|
info "Pulling MCP configurations..."
|
|
209
141
|
puts "#{'=' * 50}\n"
|
|
210
142
|
|
|
211
|
-
# Default MCP repositories
|
|
212
143
|
mcp_repos = [
|
|
213
144
|
{ owner: "anthropics", repo: "claude-code", path: "mcp" }
|
|
214
145
|
]
|
|
@@ -231,7 +162,7 @@ command :mcp do |c|
|
|
|
231
162
|
local_path = File.join(mcp_dir, file["name"])
|
|
232
163
|
|
|
233
164
|
if download_file(file["download_url"], local_path)
|
|
234
|
-
puts "
|
|
165
|
+
puts " #{file['name']}"
|
|
235
166
|
pulled += 1
|
|
236
167
|
end
|
|
237
168
|
end
|
|
@@ -244,16 +175,13 @@ command :mcp do |c|
|
|
|
244
175
|
success "MCP pull completed: #{pulled} files"
|
|
245
176
|
puts "#{'=' * 50}\n"
|
|
246
177
|
end
|
|
247
|
-
end
|
|
248
178
|
|
|
249
|
-
desc "list", "List pulled resources"
|
|
250
|
-
|
|
251
|
-
c.action do |args, options|
|
|
179
|
+
desc "list", "List pulled resources"
|
|
180
|
+
def list
|
|
252
181
|
puts "\n#{'=' * 50}"
|
|
253
182
|
puts "Pulled Claude Resources"
|
|
254
183
|
puts "#{'=' * 50}\n"
|
|
255
184
|
|
|
256
|
-
# List skills
|
|
257
185
|
if File.directory?(skills_dir)
|
|
258
186
|
puts "\nSkills (#{skills_dir}):"
|
|
259
187
|
skills = Dir.glob(File.join(skills_dir, "*.{md,rb,py}"))
|
|
@@ -264,7 +192,6 @@ command :list do |c|
|
|
|
264
192
|
end
|
|
265
193
|
end
|
|
266
194
|
|
|
267
|
-
# List MCP
|
|
268
195
|
if File.directory?(mcp_dir)
|
|
269
196
|
puts "\nMCP Configs (#{mcp_dir}):"
|
|
270
197
|
mcp_files = Dir.glob(File.join(mcp_dir, "*.json"))
|
|
@@ -277,28 +204,81 @@ command :list do |c|
|
|
|
277
204
|
|
|
278
205
|
puts "\n#{'=' * 50}\n"
|
|
279
206
|
end
|
|
280
|
-
end
|
|
281
207
|
|
|
282
|
-
desc "config", "Show
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
208
|
+
desc "config", "Show configuration"
|
|
209
|
+
def config
|
|
210
|
+
puts "\n#{'=' * 50}"
|
|
211
|
+
puts "CM CLI Configuration"
|
|
212
|
+
puts "#{'=' * 50}\n"
|
|
213
|
+
puts "Skills directory: #{skills_dir}"
|
|
214
|
+
puts "MCP directory: #{mcp_dir}"
|
|
215
|
+
puts "Config file: #{config_file}"
|
|
216
|
+
puts
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
no_commands do
|
|
220
|
+
def self.version
|
|
221
|
+
puts "cm-cli version 0.1.0"
|
|
295
222
|
end
|
|
296
223
|
end
|
|
297
|
-
end
|
|
298
224
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
225
|
+
# Handle version flag at top level
|
|
226
|
+
if ARGV.include?("--version") || ARGV.include?("-v")
|
|
227
|
+
puts "cm-cli version 0.1.0"
|
|
228
|
+
exit 0
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
private
|
|
232
|
+
|
|
233
|
+
def skills_dir
|
|
234
|
+
File.expand_path("~/.claude/skills")
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def mcp_dir
|
|
238
|
+
File.expand_path("~/.claude/mcp")
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def config_file
|
|
242
|
+
File.expand_path("~/.claude/config.yaml")
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def github_api_url(path)
|
|
246
|
+
"https://api.github.com/repos#{path}"
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def fetch_github_files(owner, repo, path = "")
|
|
250
|
+
url = github_api_url("/#{owner}/#{repo}/contents/#{path}")
|
|
251
|
+
headers = { "Accept" => "application/vnd.github.v3+json", "User-Agent" => "cm-cli" }
|
|
252
|
+
response = URI.open(url, headers: headers)
|
|
253
|
+
JSON.parse(response.read)
|
|
254
|
+
rescue => e
|
|
255
|
+
error "Failed to fetch from GitHub: #{e.message}"
|
|
256
|
+
[]
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def download_file(url, local_path)
|
|
260
|
+
FileUtils.mkdir_p(File.dirname(local_path))
|
|
261
|
+
URI.open(url, "rb") { |read| File.open(local_path, "wb") { |write| write.write(read.read) } }
|
|
262
|
+
rescue => e
|
|
263
|
+
error "Failed to download #{url}: #{e.message}"
|
|
264
|
+
false
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def info(msg)
|
|
268
|
+
puts "\e[32m[INFO]\e[0m #{msg}"
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def success(msg)
|
|
272
|
+
puts "\e[32m[SUCCESS]\e[0m #{msg}"
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def error(msg)
|
|
276
|
+
puts "\e[31m[ERROR]\e[0m #{msg}"
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def ensure_dir(dir)
|
|
280
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
303
281
|
end
|
|
304
282
|
end
|
|
283
|
+
|
|
284
|
+
CmCLI.start(ARGV)
|
data/lib/cm/version.rb
CHANGED
data/lib/cm.rb
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
module Cm
|
|
7
|
-
class Error < StandardError; end
|
|
8
|
-
|
|
9
|
-
def self.start
|
|
10
|
-
CLI.start(ARGV)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
3
|
+
# CLI entry point using Thor for Ruby 2.7 compatibility
|
|
4
|
+
# All logic is in lib/cm/cli.rb
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cm-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- FullTrust
|
|
@@ -11,19 +11,19 @@ cert_chain: []
|
|
|
11
11
|
date: 2026-03-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: thor
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '1.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '1.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -84,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
84
84
|
requirements:
|
|
85
85
|
- - ">="
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
|
-
version:
|
|
87
|
+
version: 2.7.0
|
|
88
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
89
|
requirements:
|
|
90
90
|
- - ">="
|