Commit Graph

28 Commits

Author SHA1 Message Date
user
6d86e8d7f8 fix: retry transient SSL/connection errors in alert backends
Add retry loop (3 attempts, exponential backoff) for SSLError,
ConnectionError, TimeoutError, and OSError in alert poll cycle.
Non-transient errors fail immediately. Also fixes searx test
mocks to match direct urlopen usage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:51:28 +01:00
user
b973635445 fix: route SearXNG direct via static route, drop proxy
SearXNG instance at 192.168.122.119 is reachable via grokbox
static route -- no need to tunnel through SOCKS5. Reverts searx
and alert plugins to stdlib urlopen for SearXNG queries. YouTube
and Twitch in alert.py still use the proxy. Also removes cprofile
flag from docker-compose command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:52:43 +01:00
user
29e77f97b2 fix: route searx and alert SearXNG traffic through SOCKS5 proxy
Both plugins called urllib.request.urlopen directly, bypassing the
proxy. Switch to derp.http.urlopen and update the SearXNG endpoint
to the public domain (searx.mymx.me). Update test mocks to match.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:56:45 +01:00
user
26063a0e8f feat: add TCP DNS plugin with SOCKS5 proxy support
Extract shared DNS wire-format helpers into src/derp/dns.py so both
the UDP plugin (dns.py) and the new TCP plugin (tdns.py) share the
same encode/decode/build/parse logic.

The !tdns command routes queries through the SOCKS5 proxy via
derp.http.open_connection, using TCP framing (2-byte length prefix).
Default server: 1.1.1.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:09:35 +01:00
user
1bdba0ea06 feat: route raw TCP traffic through SOCKS5 proxy
Add create_connection and open_connection helpers to the shared proxy
module, covering portcheck, whois, tlscheck, and crtsh live-cert check.
UDP-based plugins (dns, blacklist, subdomain) stay direct.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:01:17 +01:00
user
97bbc6a825 feat: route plugin HTTP traffic through SOCKS5 proxy
Add PySocks dependency and shared src/derp/http.py module providing
proxy-aware urlopen() and build_opener() that route through
socks5h://127.0.0.1:1080. Subclassed SocksiPyHandler passes SSL
context through to HTTPS connections.

Swapped 14 external-facing plugins to use the proxied helpers.
Local-only traffic (SearXNG, raw DNS/TLS sockets) stays direct.
Updated test mocks in test_twitch and test_alert accordingly.
2026-02-15 15:53:49 +01:00
user
10f62631be feat: add SearX search plugin and alert backend
Add standalone !searx command for on-demand SearXNG search (top 3 results).
Add SearX as a third backend (sx) to the alert plugin for keyword monitoring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:28:00 +01:00
user
8fd6393273 feat: add keyword alert subscription plugin
Search keywords across YouTube (InnerTube) and Twitch (GQL)
simultaneously, announcing new results per channel. Supports
add/del/list/check subcommands with per-platform seen lists.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:16:29 +01:00
user
50fb8015cd feat: add Twitch livestream notification plugin
Poll Twitch streamers via public GQL endpoint and announce
offline-to-live transitions in IRC channels. Tracks stream ID
to avoid re-announcing the same stream.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:50:30 +01:00
user
3955935da4 feat: add YouTube channel follow plugin
Follow YouTube channels via Atom feeds with !yt follow/unfollow/list/check.
Resolves any YouTube URL to a channel ID, polls for new videos, and
announces them in IRC channels.
2026-02-15 14:34:20 +01:00
user
6b7572defc feat: auto-join channels on admin invite 2026-02-15 13:52:15 +01:00
user
125a4c5d4d feat: add per-channel RSS feed subscription plugin
Subscribe RSS/Atom feeds to IRC channels with periodic polling,
new-item announcements, deduplication, and persistence across restarts.
Supports conditional HTTP requests (ETag/Last-Modified), automatic
backoff on errors, and per-channel feed limits.
2026-02-15 13:36:23 +01:00
user
02ea81d059 fix: debounce WHO on JOIN to prevent flood on netsplit recovery
WHO doesn't support multiple targets (absent from TARGMAX on all
major IRCds). Replace per-nick WHO with a debounced per-channel WHO:
on JOIN, schedule WHO #channel after 2s delay. Subsequent JOINs
within the window reset the timer, so a netsplit producing dozens
of JOINs results in a single WHO.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:03:35 +01:00
user
fd8f72c3cc fix: detect oper status when users join channels
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>
2026-02-15 12:53:12 +01:00
user
f888faf2bd feat: add calendar-based reminders (at/yearly) with persistence
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>
2026-02-15 12:39:42 +01:00
user
021a0ddbe3 test: comprehensive remind plugin tests with IndexError fix
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>
2026-02-15 12:17:31 +01:00
user
70d203f96e feat: add remind plugin with one-shot and repeating reminders
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>
2026-02-15 12:09:34 +01:00
user
f48b32cd65 fix: resolve test_crtsh.py import for plugins/ directory
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>
2026-02-15 06:18:06 +01:00
user
7184c43b08 fix: resolve test_username.py import for plugins/ directory
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>
2026-02-15 06:17:11 +01:00
user
fa88422c36 test: add integration tests with mock IRC server
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>
2026-02-15 06:09:14 +01:00
user
13c1f76767 test: add username plugin tests
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>
2026-02-15 04:47:26 +01:00
user
668d7f89b8 test: add channel filter and JSON log tests
TestChannelFilter: allowed/denied/PM/no-config/core-exempt/ampersand.
TestChannelConfig: TOML loading, defaults. TestJsonFormatter: fields,
exception, unicode, single-line, timestamp format.
2026-02-15 04:16:49 +01:00
user
8129b79cdb test: add config, format_msg, and Bot API tests
New test_config.py: merge, load, resolve_config tests.
Extend test_irc.py: format_msg edge cases (colon, empty, multi-param).
Extend test_plugin.py: Bot API via FakeConnection, _split_utf8 tests.
Test count: 92 -> 120.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 03:27:18 +01:00
user
f86cd1ad49 feat: add IRCv3 cap negotiation, channel management, state persistence
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>
2026-02-15 03:07:06 +01:00
user
f96224afb1 feat: add admin/owner permission system
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>
2026-02-15 02:26:27 +01:00
user
77f9a364e6 feat: add hot-reload, shorthand commands, and plugin help
- 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>
2026-02-15 01:15:59 +01:00
user
ad18a902dd feat: add crt.sh certificate transparency lookup plugin
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>
2026-02-15 00:56:55 +01:00
user
bf45abcbad feat: initial implementation
Asyncio IRC bot with decorator-based plugin system.
Zero external dependencies, Python 3.11+.

- IRC protocol: message parsing, formatting, async TCP/TLS connection
- Plugin system: @command and @event decorators, file-based loading
- Bot orchestrator: connect, dispatch, reconnect, nick recovery
- CLI: argparse entry point with TOML config
- Built-in plugins: ping, help, version, echo
- 28 unit tests for parser and plugin system
2026-02-15 00:37:31 +01:00