claude_code_slash_commands 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c210edb72d63d4cdb518fb644dae19bad1f8b78fce946896832949dcf2b15a12
4
- data.tar.gz: bd4a22abcae98bb843b902eee41eeeafc9575ec9dd8d127b03e4abe5b146afc6
3
+ metadata.gz: e41a04bba52189335237582a60bbed45308a9999890086618137411cc70aa9e3
4
+ data.tar.gz: e19ede006674c49ca18748df1b65380a44b7187cf84ee1a865059acaaf4c02ed
5
5
  SHA512:
6
- metadata.gz: f994df51e9893d1a0bc8b37481470bf04846ff7ed5fac3a9ed1b9fbd0e8f7c005177a0d27dfd7a5575e7a5cd0e11a2b7c33c26204eeb86f1f3c59905d00397d5
7
- data.tar.gz: a23b39eef771857dfff527f9ff070341e625051e70940b0380b57c7f3fac9cf0964cb5337e9a06a709c35b8dcf69035dce3c7b8b52625df14cc6974830c8d3de
6
+ metadata.gz: b93db29e612a3cf40e57be2fd383cc00606c5a0c13507d8b29103712f6b8c2822c8f2962e89ab5a32ea2a0eea4534655aceba7445b8a785f3f0903a4ea114ec4
7
+ data.tar.gz: f1be4e0572e1ca77a9db4c9b1969d7a46e4e6e9be384bdbf7af399d864235dcacc19374d33a7575d8018e2327510584bc3460a385f954981070fc905768ca11a
data/CLAUDE.md ADDED
@@ -0,0 +1,57 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Commands
6
+
7
+ ### Testing and Development
8
+ - `rake test` - Run the test suite using Minitest
9
+ - `bundle exec rake test` - Run tests with bundler
10
+ - `rake standard` - Run StandardRB linter for code formatting
11
+ - `rake standard:fix` - Auto-fix StandardRB formatting issues
12
+ - `rake` - Run default task (both tests and linting)
13
+
14
+ ### Gem Development
15
+ - `bundle exec rake install` - Install gem locally for testing
16
+ - `bundle exec rake release` - Create git tag and push to RubyGems
17
+ - `bundle exec rake build` - Build the gem file
18
+ - `bin/setup` - Install dependencies after checkout
19
+ - `bin/console` - Start interactive console with gem loaded
20
+
21
+ ### CLI Usage
22
+ - `claude_code_slash_commands install` - Install commands to ~/.claude/commands from GitHub
23
+ - `claude_code_slash_commands install --local` - Install commands from local commands/ directory
24
+ - `claude_code_slash_commands help` - Show help message
25
+
26
+ ## Architecture
27
+
28
+ This is a Ruby gem that distributes slash commands for Claude Code. The main components are:
29
+
30
+ ### Core Structure
31
+ - `ClaudeCodeSlashCommands::CLI` - Command-line interface handler that processes user commands
32
+ - `ClaudeCodeSlashCommands::Installer` - Handles downloading and installing command files from GitHub to `~/.claude/commands`
33
+ - `commands/` directory - Contains the actual slash command markdown files that get distributed
34
+
35
+ ### Key Features
36
+ - **GitHub Integration**: Uses `gh` CLI to fetch command files directly from the repository
37
+ - **Smart Installation**: Compares file contents to avoid unnecessary overwrites, prompts for confirmation when files differ
38
+ - **Command Format**: Slash commands are markdown files with optional YAML frontmatter for metadata
39
+
40
+ ### Dependencies
41
+ - Requires GitHub CLI (`gh`) to be installed and configured
42
+ - Uses StandardRB for code formatting
43
+ - Minitest for testing framework
44
+ - Mocha for test mocking
45
+
46
+ ### Command File Structure
47
+ Slash commands are stored as `.md` files in the `commands/` directory with this format:
48
+ ```markdown
49
+ ---
50
+ description: Brief description of the command
51
+ allowed-tools: Bash(git status:*)
52
+ ---
53
+
54
+ Command prompt content goes here
55
+ ```
56
+
57
+ The installer fetches these files from GitHub and copies them to the user's `~/.claude/commands` directory.
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in claude_code_slash_commands.gemspec
6
+ gemspec
7
+
8
+ gem "irb"
9
+ gem "rake", "~> 13.0"
10
+
11
+ gem "minitest", "~> 5.16"
12
+ gem "mocha"
13
+
14
+ gem "standard", "~> 1.3"
data/Gemfile.lock ADDED
@@ -0,0 +1,95 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ claude_code_slash_commands (0.2.1)
5
+ base64
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.3)
11
+ base64 (0.3.0)
12
+ date (3.4.1)
13
+ erb (5.0.1)
14
+ io-console (0.8.0)
15
+ irb (1.15.2)
16
+ pp (>= 0.6.0)
17
+ rdoc (>= 4.0.0)
18
+ reline (>= 0.4.2)
19
+ json (2.12.2)
20
+ language_server-protocol (3.17.0.5)
21
+ lint_roller (1.1.0)
22
+ minitest (5.25.5)
23
+ mocha (2.7.1)
24
+ ruby2_keywords (>= 0.0.5)
25
+ parallel (1.27.0)
26
+ parser (3.3.8.0)
27
+ ast (~> 2.4.1)
28
+ racc
29
+ pp (0.6.2)
30
+ prettyprint
31
+ prettyprint (0.2.0)
32
+ prism (1.4.0)
33
+ psych (5.2.6)
34
+ date
35
+ stringio
36
+ racc (1.8.1)
37
+ rainbow (3.1.1)
38
+ rake (13.3.0)
39
+ rdoc (6.14.2)
40
+ erb
41
+ psych (>= 4.0.0)
42
+ regexp_parser (2.10.0)
43
+ reline (0.6.1)
44
+ io-console (~> 0.5)
45
+ rubocop (1.75.8)
46
+ json (~> 2.3)
47
+ language_server-protocol (~> 3.17.0.2)
48
+ lint_roller (~> 1.1.0)
49
+ parallel (~> 1.10)
50
+ parser (>= 3.3.0.2)
51
+ rainbow (>= 2.2.2, < 4.0)
52
+ regexp_parser (>= 2.9.3, < 3.0)
53
+ rubocop-ast (>= 1.44.0, < 2.0)
54
+ ruby-progressbar (~> 1.7)
55
+ unicode-display_width (>= 2.4.0, < 4.0)
56
+ rubocop-ast (1.45.1)
57
+ parser (>= 3.3.7.2)
58
+ prism (~> 1.4)
59
+ rubocop-performance (1.25.0)
60
+ lint_roller (~> 1.1)
61
+ rubocop (>= 1.75.0, < 2.0)
62
+ rubocop-ast (>= 1.38.0, < 2.0)
63
+ ruby-progressbar (1.13.0)
64
+ ruby2_keywords (0.0.5)
65
+ standard (1.50.0)
66
+ language_server-protocol (~> 3.17.0.2)
67
+ lint_roller (~> 1.0)
68
+ rubocop (~> 1.75.5)
69
+ standard-custom (~> 1.0.0)
70
+ standard-performance (~> 1.8)
71
+ standard-custom (1.0.2)
72
+ lint_roller (~> 1.0)
73
+ rubocop (~> 1.50)
74
+ standard-performance (1.8.0)
75
+ lint_roller (~> 1.1)
76
+ rubocop-performance (~> 1.25.0)
77
+ stringio (3.1.7)
78
+ unicode-display_width (3.1.4)
79
+ unicode-emoji (~> 4.0, >= 4.0.4)
80
+ unicode-emoji (4.0.4)
81
+
82
+ PLATFORMS
83
+ arm64-darwin-24
84
+ ruby
85
+
86
+ DEPENDENCIES
87
+ claude_code_slash_commands!
88
+ irb
89
+ minitest (~> 5.16)
90
+ mocha
91
+ rake (~> 13.0)
92
+ standard (~> 1.3)
93
+
94
+ BUNDLED WITH
95
+ 2.6.9
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # claude_code_slash_commands
2
2
 
3
- This gem is intended to distribute [slash commands](https://docs.anthropic.com/en/docs/claude-code/slash-commands) for [Claude Code](https://www.anthropic.com/claude-code).
3
+ This gem is for distributing Ruby-specific [custom slash commands](https://docs.anthropic.com/en/docs/claude-code/slash-commands#custom-slash-commands) for [Claude Code](https://www.anthropic.com/claude-code).
4
+
5
+ ## Prerequisites
6
+
7
+ The [GitHub CLI](https://cli.github.com) must be installed and configured.
4
8
 
5
9
  ## Installation
6
10
 
@@ -29,14 +33,32 @@ claude_code_slash_commands install
29
33
  ```
30
34
 
31
35
  This will:
32
- - Create `~/.claude/commands` directory if it doesn't exist
33
- - Copy all command files from the gem
36
+ - Create the `~/.claude/commands` directory if it doesn't exist
37
+ - Copy all command files from the `commands/` directory on GitHub to your local `~/.claude/commands` directory.
34
38
  - Ask for confirmation before overwriting existing commands
35
39
  - Skip files that are already identical
36
40
 
41
+ #### Local Installation
42
+
43
+ By default, commands will be fetched from the gem's GitHub repository. That means you'll always get the latest versions.
44
+
45
+ To install commands from the gem's `commands/` directory instead of GitHub:
46
+
47
+ ```bash
48
+ claude_code_slash_commands install --local
49
+ ```
50
+
51
+ This is useful for:
52
+ - Testing new commands during development
53
+ - Installing commands when you don't have internet access
54
+
37
55
  ### Available Commands
38
56
 
39
- - `hello_world.md` - A simple example command that demonstrates the slash command format
57
+ Check the `commands/` directory to see what is available.
58
+
59
+ ### Using the Commands
60
+
61
+ In your Claude Code session, type `/ruby--` and you will the list of available commands.
40
62
 
41
63
  ## Development
42
64
 
@@ -0,0 +1,19 @@
1
+ ---
2
+ allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*), WebFetch(domain:rubygems.org)
3
+ description: Add rubocop
4
+ ---
5
+ Add `rubocop` to this repo by following these steps:
6
+
7
+ - Create a new branch
8
+ - Check what the latest release of rubocop is using https://rubygems.org/gems/rubocop/
9
+ - Add the latest release of the rubocop gem as a development dependency
10
+ - Commit
11
+ - If there is a `Rakefile`, configure the `rubocop` task
12
+ - If there is a default task, configure `rubocop` to run as part of that
13
+ - Commit
14
+ - Run rubocop
15
+ - If there are linting errors, run rubocop with the `--autocorrect` flag and commit
16
+ - If the CLI suggests that additional errors can be fixed unsafely then run with `--autocorrect-all` and commit
17
+ - If there are remaining linting errors, run rubocop with --auto-gen-config and commit.
18
+ - If there is a CI configuration such as GitHub Actions, configure it to run rubocop as part of CI. The linting should be in a separate job from the tests.
19
+ - Commit
@@ -0,0 +1,19 @@
1
+ ---
2
+ allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*), WebFetch(domain:rubygems.org)
3
+ description: Add standard
4
+ ---
5
+ Add `standardrb` to this repo by following these steps:
6
+
7
+ - Create a new branch
8
+ - Check what the latest release of standard is using https://rubygems.org/gems/standard/
9
+ - Add the latest release of the standard gem as a development dependency
10
+ - Commit
11
+ - If there is a `Rakefile`, configure the `standard` task
12
+ - If there is a default task, configure `standard` to run as part of that
13
+ - Commit
14
+ - Run standard
15
+ - If there are linting errors, run standardrb with the `--fix` flag and commit
16
+ - If the CLI suggests that additional errors can be fixed unsafely then run with `--fix-unsafely` and commit
17
+ - If there are remaining linting errors, run standardrb with --generate-todo and commit.
18
+ - If there is a CI configuration such as GitHub Actions, configure it to run standard as part of CI. The linting should be in a separate job from the tests.
19
+ - Commit
@@ -0,0 +1,10 @@
1
+ ---
2
+ description: Configure a gem's CI pipeline using GitHub Actions
3
+ ---
4
+ The goal is to create a CI workflow file that runs the gem's tests as well as any linting or other verificiation tasks.
5
+
6
+ If no CI workflow file exists, create one, otherwise update the existing one.
7
+
8
+ Read https://www.ruby-lang.org/en/downloads/branches/ to check the latest Ruby release version.
9
+
10
+ Configure the CI matrix such that it covers the the minimum `required_ruby_version` in the `.gemspec`, as well as every minor release up to the latest Ruby version.
@@ -15,7 +15,8 @@ module ClaudeCodeSlashCommands
15
15
  def run
16
16
  case @args.first
17
17
  when "install"
18
- Installer.new.install
18
+ local = @args.include?("--local")
19
+ Installer.new(local: local).install
19
20
  when "help", "-h", "--help", nil
20
21
  show_help
21
22
  else
@@ -29,14 +30,18 @@ module ClaudeCodeSlashCommands
29
30
 
30
31
  def show_help
31
32
  puts <<~HELP
32
- Usage: claude_code_slash_commands <command>
33
+ Usage: claude_code_slash_commands <command> [options]
33
34
 
34
35
  Commands:
35
36
  install Install slash commands to ~/.claude/commands
36
37
  help Show this help message
37
38
 
39
+ Options:
40
+ --local Install from local commands/ directory instead of GitHub
41
+
38
42
  Examples:
39
43
  claude_code_slash_commands install
44
+ claude_code_slash_commands install --local
40
45
  claude_code_slash_commands help
41
46
  HELP
42
47
  end
@@ -2,25 +2,43 @@
2
2
 
3
3
  require "fileutils"
4
4
  require "pathname"
5
+ require "json"
6
+ require "open3"
7
+ require "base64"
5
8
 
6
9
  module ClaudeCodeSlashCommands
7
10
  class Installer
8
- def initialize(commands_source: nil, commands_target: nil)
11
+ def initialize(commands_source: nil, commands_target: nil, repo: nil, local: false)
9
12
  @gem_root = Pathname.new(__dir__).parent.parent
10
13
  @commands_source = commands_source || @gem_root.join("commands")
11
14
  @commands_target = commands_target || Pathname.new(Dir.home).join(".claude", "commands")
15
+ @repo = repo || "andyw8/claude_code_slash_commands"
16
+ @local = local
12
17
  end
13
18
 
14
19
  def install
15
20
  ensure_target_directory
16
21
 
17
- if command_files.empty?
18
- puts "❌ No command files found to install"
19
- return
20
- end
22
+ if @local
23
+ commands = fetch_commands_from_local
24
+ if commands.empty?
25
+ puts "❌ No command files found in local commands/ directory"
26
+ return
27
+ end
28
+
29
+ commands.each do |command_file|
30
+ install_command_from_local(command_file)
31
+ end
32
+ else
33
+ commands = fetch_commands_from_github
34
+ if commands.empty?
35
+ puts "❌ No command files found to install"
36
+ return
37
+ end
21
38
 
22
- command_files.each do |file|
23
- install_command(file)
39
+ commands.each do |command|
40
+ install_command_from_github(command)
41
+ end
24
42
  end
25
43
 
26
44
  puts "✅ Installation complete!"
@@ -35,31 +53,50 @@ module ClaudeCodeSlashCommands
35
53
  FileUtils.mkdir_p(@commands_target)
36
54
  end
37
55
 
38
- def command_files
39
- @commands_source.glob("*.md")
56
+ def fetch_commands_from_github
57
+ stdout, stderr, status = Open3.capture3("gh", "api", "repos/#{@repo}/contents/commands")
58
+
59
+ unless status.success?
60
+ raise "Failed to fetch commands from GitHub: #{stderr}"
61
+ end
62
+
63
+ contents = JSON.parse(stdout)
64
+ contents.select { |item| item["type"] == "file" && item["name"].end_with?(".md") }
40
65
  end
41
66
 
42
- def install_command(source_file)
43
- target_file = @commands_target.join(source_file.basename)
67
+ def install_command_from_github(command)
68
+ filename = command["name"]
69
+ target_file = @commands_target.join(filename)
70
+
71
+ # Fetch the content of the command file
72
+ stdout, stderr, status = Open3.capture3(
73
+ "gh",
74
+ "api",
75
+ "repos/#{@repo}/contents/" + command["path"],
76
+ "--jq",
77
+ ".content"
78
+ )
79
+
80
+ unless status.success?
81
+ raise "Failed to fetch command content for #{filename}: #{stderr}"
82
+ end
83
+
84
+ content = Base64.decode64(stdout)
44
85
 
45
86
  if target_file.exist?
46
- if files_identical?(source_file, target_file)
47
- puts "⏭️ #{source_file.basename} already exists and is identical"
87
+ if target_file.read == content
88
+ puts "⏭️ #{filename} already exists and is identical"
48
89
  return
49
90
  end
50
91
 
51
- unless confirm_overwrite(source_file.basename)
52
- puts "⏭️ Skipping #{source_file.basename}"
92
+ unless confirm_overwrite(filename)
93
+ puts "⏭️ Skipping #{filename}"
53
94
  return
54
95
  end
55
96
  end
56
97
 
57
- FileUtils.cp(source_file, target_file)
58
- puts "📄 Installed #{source_file.basename}"
59
- end
60
-
61
- def files_identical?(file1, file2)
62
- file1.read == file2.read
98
+ target_file.write(content)
99
+ puts "📄 Installed #{filename}"
63
100
  end
64
101
 
65
102
  def confirm_overwrite(filename)
@@ -67,5 +104,33 @@ module ClaudeCodeSlashCommands
67
104
  response = $stdin.gets.chomp.downcase
68
105
  response == "y" || response == "yes"
69
106
  end
107
+
108
+ def fetch_commands_from_local
109
+ return [] unless @commands_source.exist?
110
+
111
+ @commands_source.glob("*.md").select(&:file?)
112
+ end
113
+
114
+ def install_command_from_local(command_file)
115
+ filename = command_file.basename.to_s
116
+ target_file = @commands_target.join(filename)
117
+
118
+ content = command_file.read
119
+
120
+ if target_file.exist?
121
+ if target_file.read == content
122
+ puts "⏭️ #{filename} already exists and is identical"
123
+ return
124
+ end
125
+
126
+ unless confirm_overwrite(filename)
127
+ puts "⏭️ Skipping #{filename}"
128
+ return
129
+ end
130
+ end
131
+
132
+ target_file.write(content)
133
+ puts "📄 Installed #{filename}"
134
+ end
70
135
  end
71
136
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeCodeSlashCommands
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: claude_code_slash_commands
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Waite
8
8
  bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies: []
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
12
26
  email:
13
27
  - 13400+andyw8@users.noreply.github.com
14
28
  executables:
@@ -18,10 +32,15 @@ extra_rdoc_files: []
18
32
  files:
19
33
  - ".ruby-version"
20
34
  - ".standard.yml"
35
+ - CLAUDE.md
36
+ - Gemfile
37
+ - Gemfile.lock
21
38
  - LICENSE.txt
22
39
  - README.md
23
40
  - Rakefile
24
- - commands/hello_world.md
41
+ - commands/ruby--add-rubocop.md
42
+ - commands/ruby--add-standard.md
43
+ - commands/ruby--configure-gem-ci.md
25
44
  - exe/claude_code_slash_commands
26
45
  - lib/claude_code_slash_commands.rb
27
46
  - lib/claude_code_slash_commands/cli.rb
@@ -42,7 +61,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
61
  requirements:
43
62
  - - ">="
44
63
  - !ruby/object:Gem::Version
45
- version: 3.1.0
64
+ version: 3.2.0
46
65
  required_rubygems_version: !ruby/object:Gem::Requirement
47
66
  requirements:
48
67
  - - ">="
@@ -1,7 +0,0 @@
1
- ---
2
- description: A simple hello world example command
3
- ---
4
-
5
- Say hello to the world! This is an example slash command that demonstrates the basic structure of a Claude Code slash command.
6
-
7
- Respond with a friendly greeting and explain what slash commands are.