Previously the bot only sent WHO on connect (001), so users joining
after the initial scan were never checked for oper status. Now sends
WHO <nick> on every JOIN event to detect opers mid-session.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Calendar reminders use bot.state (SQLite KV) for persistence across
restarts. Supports one-shot at specific date/time and yearly recurring
reminders with leap day handling. Restored automatically on connect
via 001 event handler.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Expand test coverage from 23 pure helper tests to 53 tests covering
the full plugin: _cleanup, _remind_once, _remind_repeat, and the
complete cmd_remind handler (usage, oneshot, repeating, list, cancel,
target routing). Fix IndexError on `!remind every` with no arguments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Supports duration parsing (5m, 1h30m, 2d12h), short hex IDs for
tracking, list/cancel subcommands, and repeating intervals via
`!remind every <duration> <text>`. Includes 23 unit tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same importlib fix as test_username.py -- load plugins.crtsh from
file path since plugins/ is not a Python package.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Load plugins.username via importlib.util.spec_from_file_location
since plugins/ is not a Python package on sys.path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Queue-based _MockConnection replaces IRCConnection to test the full
bot pipeline (registration -> dispatch -> handler -> response) without
network I/O. 14 tests cover CAP negotiation, PING/PONG, command
dispatch, prefix matching, admin enforcement, channel filtering,
and CTCP responses.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
53 tests covering regex validation, service registry integrity,
classification logic (status/json/body), formatting, and category
grouping.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement CAP LS 302 flow with configurable ircv3_caps list, replacing
the minimal SASL-only registration. Parse IRCv3 message tags (@key=value)
with proper value unescaping. Add channel management plugin (kick, ban,
unban, topic, mode) and bot API methods. Add SQLite key-value StateStore
for plugin state persistence with !state inspection command.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hostmask-based admin controls with automatic IRCOP detection via WHO.
Permission enforcement in the central dispatch path denies restricted
commands to non-admins. Includes !whoami and !admins commands, marks
load/reload/unload as admin-only.
Also lands previously-implemented SASL PLAIN auth, token-bucket rate
limiting, and CTCP VERSION/TIME/PING responses that were staged but
uncommitted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Query CT logs via crt.sh to enumerate SSL certs for domains,
report expired/valid counts, and flag live expired certs.
Uses ThreadPoolExecutor(3) for blocking I/O on RPi5.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>