Module: Brainiac::Plugins::Discord

Defined in:
lib/brainiac/plugins/discord.rb,
lib/brainiac/plugins/discord/api.rb,
lib/brainiac/plugins/discord/cli.rb,
lib/brainiac/plugins/discord/config.rb,
lib/brainiac/plugins/discord/gateway.rb,
lib/brainiac/plugins/discord/message.rb,
lib/brainiac/plugins/discord/prompts.rb,
lib/brainiac/plugins/discord/version.rb,
lib/brainiac/plugins/discord/delivery.rb,
lib/brainiac/plugins/discord/metadata.rb,
lib/brainiac/plugins/discord/reactions.rb

Defined Under Namespace

Modules: Api, Cli, Config, Delivery, Gateway, Message, Prompts, Reactions

Constant Summary collapse

VERSION =
"0.0.4"

Class Method Summary collapse

Class Method Details

.cli(args) ⇒ Object

Plugin CLI entry point — called by brainiac core's plugin delegation.



264
265
266
# File 'lib/brainiac/plugins/discord/cli.rb', line 264

def self.cli(args)
  Cli.run(args)
end

.completionsObject

Subcommand names for bash completion.



269
270
271
# File 'lib/brainiac/plugins/discord/cli.rb', line 269

def self.completions
  %w[setup config default map owner token status]
end

.configured?Boolean

Returns true if Discord has at least one bot token configured.

Returns:

  • (Boolean)


12
13
14
15
16
17
18
19
20
# File 'lib/brainiac/plugins/discord/metadata.rb', line 12

def self.configured?
  registry_file = File.join(ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac")), "agents.json")
  return false unless File.exist?(registry_file)

  registry = JSON.parse(File.read(registry_file))
  registry.any? { |_k, v| v.is_a?(Hash) && v.dig("env", "DISCORD_BOT_TOKEN") }
rescue StandardError
  false
end

.help_textObject

Help text shown in brainiac help when the plugin is installed.



23
24
25
# File 'lib/brainiac/plugins/discord/metadata.rb', line 23

def self.help_text
  "    brainiac discord <command>    Manage Discord bots (config, token, status, map)"
end

.on_agent_created(agent_key, entry) ⇒ Object

Called by brainiac CLI after agent create — prompts for Discord user ID.



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/brainiac/plugins/discord/cli.rb', line 274

def self.on_agent_created(agent_key, entry)
  return unless $stdin.tty?

  display_name = entry["display_name"] || agent_key.capitalize
  puts ""
  puts "  [Discord] Configure Discord for #{display_name}?"
  print "  Discord user ID (or blank to skip): "
  user_id = $stdin.gets&.chomp
  return if user_id.nil? || user_id.empty?

  config_file = File.join(ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac")), "discord.json")
  config = File.exist?(config_file) ? JSON.parse(File.read(config_file)) : {}
  config["user_mappings"] ||= {}
  config["user_mappings"][display_name] = user_id
  File.write(config_file, JSON.pretty_generate(config))
  puts "  ✓ Added #{display_name}#{user_id} to discord.json user_mappings"
rescue JSON::ParserError => e
  puts "  ⚠ Could not update discord.json: #{e.message}"
end

.on_agent_removed(agent_key, display_name) ⇒ Object

Called by brainiac CLI after agent remove — removes from Discord user_mappings.



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/brainiac/plugins/discord/cli.rb', line 295

def self.on_agent_removed(agent_key, display_name)
  config_file = File.join(ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac")), "discord.json")
  return unless File.exist?(config_file)

  config = JSON.parse(File.read(config_file))
  mappings = config["user_mappings"]
  return unless mappings

  removed = mappings.delete(display_name) || mappings.delete(agent_key)
  return unless removed

  File.write(config_file, JSON.pretty_generate(config))
  puts "  [Discord] Removed #{display_name} from discord.json user_mappings"
rescue JSON::ParserError
  nil
end

.register(app) ⇒ Object

Called by Brainiac plugin system during server startup.

Parameters:

  • app (Sinatra::Application)

    The running Brainiac server



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/brainiac/plugins/discord.rb', line 21

def register(app)
  # Load Discord config
  Brainiac::Plugins::Discord::Config.load!

  # Register channel prompt
  Brainiac.register_channel_prompt(:discord, Brainiac::Plugins::Discord::Prompts::CHANNEL)

  # Register as notification provider
  register_notification_handler!

  # Register crash handler
  register_crash_handler!

  # Register agent lifecycle hooks
  register_agent_lifecycle_hooks!

  # Start all per-agent Discord bot gateway connections
  Brainiac::Plugins::Discord::Gateway.start_all!

  # Start draft delivery poller
  Brainiac::Plugins::Discord::Delivery.start_poller!

  # Set up API routes
  setup_routes(app)

  LOG.info "[Discord] Plugin registered (#{Brainiac::Plugins::Discord::Gateway.bot_count} bots)"
end