- Plugin registry: add unload_plugin(), reload_plugin(), path tracking - Bot: add load_plugin(), reload_plugin(), unload_plugin() public API - Core plugin: add !load, !reload, !unload, !plugins commands - Command dispatch: support unambiguous prefix matching (!h -> !help) - Help: support !help <plugin> to show plugin description and commands - Tests: 17 new tests covering hot-reload, prefix matching Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.3 KiB
4.3 KiB
Usage Guide
Running
# From project directory
derp
# With options
derp --config /path/to/derp.toml --verbose
CLI Flags
| Flag | Description |
|---|---|
-c, --config PATH |
Config file path |
-v, --verbose |
Debug logging |
-V, --version |
Print version |
-h, --help |
Show help |
Configuration
All settings in config/derp.toml:
[server]
host = "irc.libera.chat" # IRC server hostname
port = 6697 # Port (6697 = TLS, 6667 = plain)
tls = true # Enable TLS encryption
nick = "derp" # Bot nickname
user = "derp" # Username (ident)
realname = "derp IRC bot" # Real name field
password = "" # Server password (optional)
[bot]
prefix = "!" # Command prefix character
channels = ["#test"] # Channels to join on connect
plugins_dir = "plugins" # Plugin directory path
[logging]
level = "info" # Logging level: debug, info, warning, error
Built-in Commands
| Command | Description |
|---|---|
!ping |
Bot responds with "pong" |
!help |
List all available commands |
!help <cmd> |
Show help for a specific command |
!help <plugin> |
Show plugin description and its commands |
!version |
Show bot version |
!echo <text> |
Echo back text (example plugin) |
!cert <domain> [...] |
Lookup CT logs for up to 5 domains |
!load <plugin> |
Hot-load a plugin from the plugins directory |
!reload <plugin> |
Reload a plugin, picking up file changes |
!unload <plugin> |
Unload a plugin, removing its handlers |
!plugins |
List loaded plugins with handler counts |
Command Shorthand
Commands can be abbreviated to any unambiguous prefix:
!h -> !help (unique match)
!pi -> !ping (unique match)
!p -> error: ambiguous (ping, plugins)
Exact matches always take priority over prefix matches.
!cert -- Certificate Transparency Lookup
Query crt.sh CT logs to enumerate SSL certificates for domains. Reports totals (expired/valid) and flags domains still serving expired certs.
!cert example.com
!cert example.com badsite.com another.org
Output format:
example.com -- 127 certs (23 expired, 104 valid)
badsite.com -- 45 certs (8 expired, 37 valid) | live cert EXPIRED
broken.test -- error: timeout
- Max 5 domains per invocation
- crt.sh can be slow; the bot confirms receipt before querying
- Live cert check runs only when expired CT entries exist
Plugin Management
Plugins can be loaded, unloaded, and reloaded at runtime without restarting the bot.
!load crtsh # Hot-load a new plugin from plugins/
!reload crtsh # Reload a changed plugin
!unload crtsh # Remove a plugin and all its handlers
!plugins # List loaded plugins with handler counts
The core plugin cannot be unloaded (prevents losing !load/!reload),
but it can be reloaded.
Writing Plugins
Create a .py file in the plugins/ directory:
from derp.plugin import command, event
@command("hello", help="Greet the user")
async def cmd_hello(bot, message):
"""Handler receives bot instance and parsed Message."""
await bot.reply(message, f"Hello, {message.nick}!")
@event("JOIN")
async def on_join(bot, message):
"""Event handlers fire on IRC events (JOIN, PART, QUIT, etc.)."""
if message.nick != bot.nick:
await bot.send(message.target, f"Welcome, {message.nick}")
Plugin API
The bot object provides:
| Method | Description |
|---|---|
bot.send(target, text) |
Send message to channel or nick |
bot.reply(msg, text) |
Reply to source (channel or PM) |
bot.action(target, text) |
Send /me action |
bot.join(channel) |
Join a channel |
bot.part(channel [, reason]) |
Leave a channel |
bot.quit([reason]) |
Disconnect from server |
The message object provides:
| Attribute | Description |
|---|---|
message.nick |
Sender's nickname |
message.prefix |
Full nick!user@host prefix |
message.command |
IRC command (PRIVMSG, JOIN, etc.) |
message.target |
First param (channel or nick) |
message.text |
Trailing text content |
message.is_channel |
Whether target is a channel |
message.params |
All message parameters |