dcomm 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: 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: []