dcomm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: afe381b99e90819d8530a275dd4de7fdf3a3704f2f8d4732bdd86ac6c9610336
4
+ data.tar.gz: 248bbe289da6a683b4ff3ccbe336ef81b35ce5c866664cabe370c4f579d5f927
5
+ SHA512:
6
+ metadata.gz: 642d3e6f7dddde8be673de3768df61b92ff7021edf87791c38b1e1afc2fd1b8b364305b9a765d1121ced5ca536bc40015c5952636797b0d512ab18f8904089b3
7
+ data.tar.gz: 9f1a031b657346e840b1580f41056bd6c577deeb35f0eb7591641a913cb4124cefc5b4318cc844e13acd2dc09b031ef462f5d70e8d4b593cca9c3b07cbb29930
data/exe/dcomm ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'dry/cli'
6
+ require 'dcomm/cli'
7
+
8
+ cli = Dry::CLI.new(DComm::CLI)
9
+
10
+ begin
11
+ cli.call
12
+ rescue => e # rubocop:disable Style/RescueStandardError
13
+ warn e.message
14
+ exit(1)
15
+ end
16
+
17
+ # ex: filetype=ruby
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'dcomm/cli/command'
5
+
6
+ module DComm
7
+ module CLI
8
+ class Apply < Command
9
+ desc 'Bulk overwrite one or more global application commands'
10
+
11
+ argument :app_id, required: true, desc: 'Discord application ID'
12
+ argument(
13
+ :commands_file,
14
+ required: true,
15
+ desc: 'YAML file containing a collection of command objects',
16
+ )
17
+
18
+ def call(app_id:, commands_file:)
19
+ commands = YAML.safe_load_file(File.expand_path(commands_file))
20
+ response = discord.apply_global_app_cmds(app_id:, commands:)
21
+ renderer.call(response)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/cli/command'
4
+ require 'dcomm/discord_api'
5
+ require 'dcomm/renderer'
6
+
7
+ module DComm
8
+ module CLI
9
+ class Command < Dry::CLI::Command
10
+ attr_reader :discord, :renderer
11
+
12
+ def initialize(discord: nil, renderer: nil) # rubocop:disable Lint/MissingSuper
13
+ require 'dcomm/config'
14
+
15
+ @discord = discord || DiscordAPI.new(
16
+ auth_header: "Bot #{DComm.config.discord_bot_token}",
17
+ )
18
+
19
+ @renderer = renderer || Renderer.new
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'dcomm/cli/command'
5
+
6
+ module DComm
7
+ module CLI
8
+ class Create < Command
9
+ desc 'Create a global application command'
10
+
11
+ argument :app_id, required: true, desc: 'Discord application ID'
12
+ argument(
13
+ :command_file,
14
+ required: true,
15
+ desc: 'YAML file containing a single command object',
16
+ )
17
+
18
+ def call(app_id:, command_file:)
19
+ command = YAML.safe_load_file(File.expand_path(command_file))
20
+ response = discord.create_global_app_cmd(app_id:, command:)
21
+ renderer.call(response)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ class Delete < Command
8
+ desc 'Delete a global application command'
9
+
10
+ argument :app_id, required: true, desc: 'Discord application ID'
11
+ argument :command_id, required: true, desc: 'Discord application command ID'
12
+
13
+ def call(app_id:, command_id:)
14
+ response = discord.delete_global_app_cmd(app_id:, command_id:)
15
+ renderer.call(response)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ class Edit < Command
8
+ desc 'Edit a global application command'
9
+
10
+ def call
11
+ puts 'edit command'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'dcomm/cli/command'
5
+
6
+ module DComm
7
+ module CLI
8
+ module Guild
9
+ class Apply < Command
10
+ desc 'Bulk overwrite one or more guild application commands'
11
+
12
+ argument :app_id, required: true, desc: 'Discord application ID'
13
+ argument :guild_id, required: true, desc: 'Discord guild ID'
14
+ argument(
15
+ :commands_file,
16
+ required: true,
17
+ desc: 'YAML file containing a collection of command objects',
18
+ )
19
+
20
+ def call(app_id:, guild_id:, commands_file:)
21
+ commands = YAML.safe_load_file(File.expand_path(commands_file))
22
+ response = discord.apply_guild_app_cmds(app_id:, guild_id:, commands:)
23
+ renderer.call(response)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'dcomm/cli/command'
5
+
6
+ module DComm
7
+ module CLI
8
+ module Guild
9
+ class Create < Command
10
+ desc 'Create a guild application command'
11
+
12
+ argument :app_id, required: true, desc: 'Discord application ID'
13
+ argument :guild_id, required: true, desc: 'Discord guild ID'
14
+ argument(
15
+ :command_file,
16
+ required: true,
17
+ desc: 'YAML file containing a single command object',
18
+ )
19
+
20
+ def call(app_id:, guild_id:, command_file:)
21
+ command = YAML.safe_load_file(File.expand_path(command_file))
22
+ response = discord.create_guild_app_cmd(app_id:, guild_id:, command:)
23
+ renderer.call(response)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ module Guild
8
+ class Delete < Command
9
+ desc 'Delete a guild application command'
10
+
11
+ argument :app_id, required: true, desc: 'Discord application ID'
12
+ argument :guild_id, required: true, desc: 'Discord guild ID'
13
+ argument :command_id, required: true, desc: 'Discord application command ID'
14
+
15
+ def call(app_id:, guild_id:, command_id:)
16
+ response = discord.delete_guild_app_cmd(app_id:, guild_id:, command_id:)
17
+ renderer.call(response)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ module Guild
8
+ class Edit < Command
9
+ desc 'Edit a guild application command'
10
+
11
+ def call
12
+ puts 'guild edit command'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ module Guild
8
+ class List < Command
9
+ desc 'List guild application commands'
10
+
11
+ argument :app_id, required: true, desc: 'Discord application ID'
12
+ argument :guild_id, required: true, desc: 'Discord guild ID'
13
+
14
+ def call(app_id:, guild_id:)
15
+ response = discord.list_guild_app_cmds(app_id:, guild_id:)
16
+ renderer.call(response)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ module Guild
8
+ class Show < Command
9
+ desc 'View details of a guild application command'
10
+
11
+ argument :app_id, required: true, desc: 'Discord application ID'
12
+ argument :guild_id, required: true, desc: 'Discord guild ID'
13
+ argument :command_id, required: true, desc: 'Discord application command ID'
14
+
15
+ def call(app_id:, guild_id:, command_id:)
16
+ response = discord.show_guild_app_cmd(app_id:, guild_id:, command_id:)
17
+ renderer.call(response)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'dcomm/cli/command'
5
+
6
+ module DComm
7
+ module CLI
8
+ module Guild
9
+ class Update < Command
10
+ desc 'Update a guild application command'
11
+
12
+ argument :app_id, required: true, desc: 'Discord application ID'
13
+ argument :guild_id, required: true, desc: 'Discord guild ID'
14
+ argument :command_id, required: true, desc: 'Discord application command ID'
15
+ argument(
16
+ :command_file,
17
+ required: true,
18
+ desc: 'YAML file containing a single command object',
19
+ )
20
+
21
+ def call(app_id:, guild_id:, command_id:, command_file:)
22
+ command = YAML.safe_load_file(File.expand_path(command_file))
23
+ response = discord.edit_guild_app_cmd(
24
+ app_id:,
25
+ guild_id:,
26
+ command_id:,
27
+ command:,
28
+ )
29
+ renderer.call(response)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ class List < Command
8
+ desc 'List global application commands'
9
+
10
+ argument :app_id, required: true, desc: 'Discord application ID'
11
+
12
+ def call(app_id:)
13
+ response = discord.list_global_app_cmds(app_id:)
14
+ renderer.call(response)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dcomm/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ class Show < Command
8
+ desc 'View details of a global application command'
9
+
10
+ argument :app_id, required: true, desc: 'Discord application ID'
11
+ argument :command_id, required: true, desc: 'Discord application command ID'
12
+
13
+ def call(app_id:, command_id:)
14
+ response = discord.show_global_app_cmd(app_id:, command_id:)
15
+ renderer.call(response)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'dcomm/cli/command'
5
+
6
+ module DComm
7
+ module CLI
8
+ class Update < Command
9
+ desc 'Update a global application command'
10
+
11
+ argument :app_id, required: true, desc: 'Discord application ID'
12
+ argument :command_id, required: true, desc: 'Discord application command ID'
13
+ argument(
14
+ :command_file,
15
+ required: true,
16
+ desc: 'YAML file containing a single command object',
17
+ )
18
+
19
+ def call(app_id:, command_id:, command_file:)
20
+ command = YAML.safe_load_file(File.expand_path(command_file))
21
+ response = discord.edit_global_app_cmd(app_id:, command_id:, command:)
22
+ renderer.call(response)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/cli/command'
4
+
5
+ module DComm
6
+ module CLI
7
+ class Version < Dry::CLI::Command
8
+ desc 'DComm version info'
9
+
10
+ def call
11
+ puts "DComm version #{DComm.version}"
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/dcomm/cli.rb ADDED
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/cli'
4
+ require 'dcomm/cli/apply'
5
+ require 'dcomm/cli/create'
6
+ require 'dcomm/cli/delete'
7
+ require 'dcomm/cli/edit'
8
+ require 'dcomm/cli/list'
9
+ require 'dcomm/cli/show'
10
+ require 'dcomm/cli/update'
11
+ require 'dcomm/cli/version'
12
+ require 'dcomm/cli/guild/apply'
13
+ require 'dcomm/cli/guild/create'
14
+ require 'dcomm/cli/guild/delete'
15
+ require 'dcomm/cli/guild/edit'
16
+ require 'dcomm/cli/guild/list'
17
+ require 'dcomm/cli/guild/show'
18
+ require 'dcomm/cli/guild/update'
19
+
20
+ module DComm
21
+ module CLI
22
+ extend Dry::CLI::Registry
23
+
24
+ register('apply', Apply, aliases: %w[bulk-overwrite])
25
+ register('create', Create)
26
+ register('delete', Delete, aliases: %w[remove rm])
27
+
28
+ # TODO: this is a fancier command where we open the command in $EDITOR for
29
+ # the user to make changes, and then the update is submitted upon quitting.
30
+ #
31
+ # register('edit', Edit)
32
+
33
+ register('list', List, aliases: %w[ls])
34
+ register('show', Show, aliases: %w[info describe])
35
+ register('update', Update)
36
+ register('version', Version, aliases: %w[--version])
37
+
38
+ register('guild') do |prefix|
39
+ prefix.register('apply', Guild::Apply, aliases: %w[bulk-overwrite])
40
+ prefix.register('create', Guild::Create)
41
+ prefix.register('delete', Guild::Delete, aliases: %w[remove rm])
42
+
43
+ # TODO: this is a fancier command where we open the command in $EDITOR for
44
+ # the user to make changes, and then the update is submitted upon quitting.
45
+ #
46
+ # prefix.register('edit', Guild::Edit)
47
+
48
+ prefix.register('list', Guild::List, aliases: %w[ls])
49
+ prefix.register('show', Guild::Show, aliases: %w[info describe])
50
+ prefix.register('update', Guild::Update)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'dry/configurable'
5
+
6
+ module DComm
7
+ extend Dry::Configurable
8
+
9
+ CONFIG_HOME = ENV.fetch(
10
+ 'XDG_CONFIG_HOME',
11
+ File.expand_path(File.join(Dir.home, '.config')),
12
+ ).freeze
13
+
14
+ setting :discord_bot_token
15
+
16
+ configure do |config|
17
+ if (token = ENV.fetch('DISCORD_BOT_TOKEN', nil))
18
+ config.discord_bot_token = token
19
+ break
20
+ end
21
+
22
+ path = File.join(CONFIG_HOME, 'dcomm', 'config.yml')
23
+ raise "Error: config file #{path} does not exist" unless File.exist?(path)
24
+
25
+ yaml = YAML.safe_load_file(path) || {}
26
+ unless yaml.fetch('discord_bot_token', nil)
27
+ raise "Error: config file does not define 'discord_bot_token' field"
28
+ end
29
+
30
+ config.discord_bot_token = yaml['discord_bot_token']
31
+ end
32
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ # NOTE: this will probably be its own library eventually, but for now a class
4
+ # works just fine.
5
+
6
+ require 'http'
7
+ require 'json'
8
+
9
+ module DComm
10
+ class DiscordAPI
11
+ attr_reader :auth_header, :base_uri
12
+
13
+ def initialize(auth_header:, base_uri: 'https://discord.com/api/v10')
14
+ @auth_header = auth_header
15
+ @base_uri = base_uri
16
+ end
17
+
18
+ def apply_global_app_cmds(app_id:, commands:)
19
+ put("/applications/#{app_id}/commands", body: commands)
20
+ end
21
+
22
+ def apply_guild_app_cmds(app_id:, guild_id:, commands:)
23
+ put("/applications/#{app_id}/guilds/#{guild_id}/commands", body: commands)
24
+ end
25
+
26
+ def create_global_app_cmd(app_id:, command:)
27
+ post("/applications/#{app_id}/commands", body: command)
28
+ end
29
+
30
+ def create_guild_app_cmd(app_id:, guild_id:, command:)
31
+ post("/applications/#{app_id}/guilds/#{guild_id}/commands", body: command)
32
+ end
33
+
34
+ def delete_global_app_cmd(app_id:, command_id:)
35
+ delete("/applications/#{app_id}/commands/#{command_id}")
36
+ end
37
+
38
+ def delete_guild_app_cmd(app_id:, guild_id:, command_id:)
39
+ delete("/applications/#{app_id}/guilds/#{guild_id}/commands/#{command_id}")
40
+ end
41
+
42
+ def list_global_app_cmds(app_id:)
43
+ get("/applications/#{app_id}/commands")
44
+ end
45
+
46
+ def list_guild_app_cmds(app_id:, guild_id:)
47
+ get("/applications/#{app_id}/guilds/#{guild_id}/commands")
48
+ end
49
+
50
+ def show_global_app_cmd(app_id:, command_id:)
51
+ get("/applications/#{app_id}/commands/#{command_id}")
52
+ end
53
+
54
+ def show_guild_app_cmd(app_id:, guild_id:, command_id:)
55
+ get("/applications/#{app_id}/guilds/#{guild_id}/commands/#{command_id}")
56
+ end
57
+
58
+ def edit_global_app_cmd(app_id:, command_id:, command:)
59
+ patch("/applications/#{app_id}/commands/#{command_id}", body: command)
60
+ end
61
+
62
+ def edit_guild_app_cmd(app_id:, guild_id:, command_id:, command:)
63
+ patch(
64
+ "/applications/#{app_id}/guilds/#{guild_id}/commands/#{command_id}",
65
+ body: command,
66
+ )
67
+ end
68
+
69
+ private
70
+
71
+ def client
72
+ HTTP.auth(auth_header).headers(content_type: 'application/json')
73
+ end
74
+
75
+ def request_uri(path)
76
+ req = base_uri
77
+ req += '/' unless path.start_with?('/')
78
+ req += path
79
+
80
+ req
81
+ end
82
+
83
+ def get(path)
84
+ reqstr = request_uri(path)
85
+ client.get(reqstr).parse
86
+ end
87
+
88
+ # discord responds to application command deletes with `204 No Content`,
89
+ # meaning there is no body to `#parse` upon return.
90
+ #
91
+ # TODO: devise a more elegant solution
92
+ #
93
+ # ref:
94
+ # - https://discord.com/developers/docs/interactions/application-commands#delete-global-application-command
95
+ # - https://discord.com/developers/docs/interactions/application-commands#delete-guild-application-command
96
+ def delete(path)
97
+ reqstr = request_uri(path)
98
+ response = client.delete(reqstr)
99
+
100
+ return { 'message' => 'success' } if response.status.success?
101
+
102
+ raise 'something went wrong', response
103
+ end
104
+
105
+ def post(path, body:)
106
+ reqstr = request_uri(path)
107
+ client.post(reqstr, body: body.to_json).parse
108
+ end
109
+
110
+ def put(path, body:)
111
+ reqstr = request_uri(path)
112
+ client.put(reqstr, body: body.to_json).parse
113
+ end
114
+
115
+ def patch(path, body:)
116
+ reqstr = request_uri(path)
117
+ client.patch(reqstr, body: body.to_json).parse
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module DComm
6
+ class Renderer
7
+ def call(obj)
8
+ puts obj.to_yaml
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DComm
4
+ def self.version
5
+ @version ||= Gem::Version.new('0.1.0')
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dcomm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Price
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-11-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-cli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-configurable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: http
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.1'
55
+ description:
56
+ email:
57
+ - komidore64@gmail.com
58
+ executables:
59
+ - dcomm
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - exe/dcomm
64
+ - lib/dcomm/cli.rb
65
+ - lib/dcomm/cli/apply.rb
66
+ - lib/dcomm/cli/command.rb
67
+ - lib/dcomm/cli/create.rb
68
+ - lib/dcomm/cli/delete.rb
69
+ - lib/dcomm/cli/edit.rb
70
+ - lib/dcomm/cli/guild/apply.rb
71
+ - lib/dcomm/cli/guild/create.rb
72
+ - lib/dcomm/cli/guild/delete.rb
73
+ - lib/dcomm/cli/guild/edit.rb
74
+ - lib/dcomm/cli/guild/list.rb
75
+ - lib/dcomm/cli/guild/show.rb
76
+ - lib/dcomm/cli/guild/update.rb
77
+ - lib/dcomm/cli/list.rb
78
+ - lib/dcomm/cli/show.rb
79
+ - lib/dcomm/cli/update.rb
80
+ - lib/dcomm/cli/version.rb
81
+ - lib/dcomm/config.rb
82
+ - lib/dcomm/discord_api.rb
83
+ - lib/dcomm/renderer.rb
84
+ - lib/dcomm/version.rb
85
+ homepage:
86
+ licenses:
87
+ - AGPL-3.0-only
88
+ metadata:
89
+ rubygems_mfa_required: 'true'
90
+ bug_tracker_uri: https://todo.sr.ht/~komidore64/dcomm
91
+ homepage_uri: https://sr.ht/~komidore64/dlobby.site
92
+ mailing_list_uri: https://lists.sr.ht/~komidore64/public-inbox
93
+ source_code_uri: https://git.sr.ht/~komidore64/dcomm
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '3.2'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 3.4.21
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Manage your Discord application commands from the command line.
113
+ test_files: []