Files
derp/TODO.md
user 6083de13f9
Some checks failed
CI / gitleaks (push) Failing after 3s
CI / lint (push) Successful in 22s
CI / test (3.11) (push) Failing after 2m47s
CI / test (3.13) (push) Failing after 2m52s
CI / test (3.12) (push) Failing after 2m54s
CI / build (push) Has been skipped
feat: playlist shuffle, lazy resolution, TTS ducking, kept repair
Music:
- #random URL fragment shuffles playlist tracks before enqueuing
- Lazy playlist resolution: first 10 tracks resolve immediately,
  remaining are fetched in a background task
- !kept repair re-downloads kept tracks with missing local files
- !kept shows [MISSING] marker for tracks without local files
- TTS ducking: music ducks when merlin speaks via voice peer,
  smooth restore after TTS finishes

Performance (from profiling):
- Connection pool: preload_content=True for SOCKS connection reuse
- Pool tuning: 30 pools / 8 connections (up from 20/4)
- _PooledResponse wrapper for stdlib-compatible read interface
- Iterative _extract_videos (replace 51K-deep recursion with stack)
- proxy=False for local SearXNG

Voice + multi-bot:
- Per-bot voice config lookup ([<username>.voice] in TOML)
- Mute detection: skip duck silence when all users muted
- Autoplay shuffle deck (no repeats until full cycle)
- Seek clamp to track duration (prevent seek-past-end stall)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:21:47 +01:00

201 lines
7.6 KiB
Markdown

# derp - Backlog
## Core
- [x] Multi-server support (per-server config, shared plugins)
- [x] Stable plugin API (versioned, breaking change policy)
- [x] Paste overflow (auto-paste long output to FlaskPaste)
- [x] URL shortener integration (shorten URLs in subscription announcements)
- [x] Webhook listener (HTTP endpoint for push events to channels)
- [x] Granular ACLs (per-command: trusted, operator, admin)
## LLM Bridge
Goal: let an LLM agent interact with the bot over IRC in real-time,
with full machine access (bash, file ops, etc.).
### Architecture
Owner addresses the bot on IRC. A bridge daemon reads addressed
messages, feeds them to an LLM with tool access, and writes replies
back through the bot. The bot already has `owner` config
(`[bot] owner` hostmask patterns) to gate who can trigger LLM
interactions.
```
IRC -> bot stdout (addressed msgs) -> bridge -> LLM API -> bridge -> bot inbox -> IRC
```
### Approach options (ranked)
1. **Claude Code Agent SDK** (clean, non-trivial)
- Custom Python agent using `anthropic` SDK with `tool_use`
- Define tools: bash exec, file read/write, web fetch
- Persistent conversation memory across messages
- Full control over the event loop -- real-time IRC is natural
- Tradeoff: must implement and maintain tool definitions
2. **Claude Code CLI per-message** (simple, stateless)
- `echo "user said X" | claude --print --allowedTools bash,read,write`
- Each invocation is a cold start with no conversation memory
- Simple to implement but slow startup, no multi-turn context
- Could pass conversation history via system prompt (fragile)
3. **Persistent Claude Code subprocess** (hack, fragile)
- Long-running `claude` process with stdin/stdout piped
- Keeps context across messages within a session
- Not designed for this -- output parsing is brittle
- Session may drift or hit context limits
### Bot-side plumbing needed
- `--llm` CLI flag: route logging to file, stdout for addressed msgs
- `_is_addressed()`: DM or nick-prefixed messages
- `_is_owner()`: only owner hostmasks trigger LLM routing
- Inbox file polling (`/tmp/llm-inbox`): bridge writes `<target> <msg>`
- `llm-send` script: line splitting (400 char), FlaskPaste overflow
- Stdout format: `HH:MM [#chan] <nick> text` / `HH:MM --- status`
- Only LLM-originated replies echoed to stdout (not all bot output)
### Previous attempt (reverted)
The `--llm` mode was implemented and tested (commit ea6f079, reverted
in 6f1f4b2). The stdout/stdin plumbing worked but Claude Code CLI
cannot act as a real-time daemon -- each tool call is a blocking
round-trip, making interactive IRC conversation impractical. The code
is preserved in git history for reference.
## Plugins -- Security/OSINT
- [x] `emailcheck` -- SMTP VRFY/RCPT TO verification
- [x] `canary` -- canary token generator/tracker
- [x] `virustotal` -- hash/URL/IP/domain lookup (free API)
- [x] `abuseipdb` -- IP abuse confidence scoring (free tier)
- [x] `jwt` -- decode tokens, show claims/expiry, flag weaknesses
- [x] `mac` -- OUI vendor lookup (local IEEE database)
- [x] `pastemoni` -- monitor paste sites for keywords
- [x] `internetdb` -- Shodan InternetDB host recon (free, no API key)
## Plugins -- Utility
- [x] `paste` -- manual paste to FlaskPaste
- [x] `shorten` -- manual URL shortening
- [x] `cron` -- scheduled bot commands on a timer
## Teams
- [x] Microsoft Teams adapter via outgoing webhooks
- [x] TeamsBot + TeamsMessage (duck-typed with IRC Message)
- [x] HMAC-SHA256 webhook validation
- [x] Permission tiers via AAD object IDs
- [x] Route `send()` through SOCKS5 proxy (bug fix)
- [ ] Adaptive Cards for richer formatting
- [ ] Graph API integration for DMs
- [ ] Teams event handlers (member join/leave)
## Telegram
- [x] Telegram adapter via long-polling (no SDK)
- [x] TelegramBot + TelegramMessage (duck-typed with IRC Message)
- [x] All HTTP through SOCKS5 proxy
- [x] Message splitting at 4096-char limit
- [x] @botusername suffix stripping in groups
- [x] Permission tiers via user IDs
- [ ] Inline keyboard support for interactive replies
- [ ] Markdown/HTML formatting mode toggle
- [ ] Webhook mode (for setWebhook instead of getUpdates)
## Discord
- [ ] Discord adapter via WebSocket gateway + REST API (no SDK)
- [ ] DiscordBot + DiscordMessage (duck-typed with IRC Message)
- [ ] Gateway intents for message content
- [ ] Message splitting at 2000-char limit
- [ ] Permission tiers via user/role IDs
- [ ] Slash command registration (optional)
## Matrix
- [ ] Matrix adapter via long-poll `/sync` endpoint (no SDK)
- [ ] MatrixBot + MatrixMessage (duck-typed with IRC Message)
- [ ] Room-based messaging (rooms map to channels)
- [ ] Power levels map to permission tiers
- [ ] E2EE support (optional, requires libolm)
## XMPP
- [ ] XMPP adapter via persistent TCP + XML stanzas (no SDK)
- [ ] XMPPBot + XMPPMessage (duck-typed with IRC Message)
- [ ] MUC (Multi-User Chat) support -- rooms map to channels
- [ ] SASL authentication
- [ ] TLS/STARTTLS connection
## Performance
- [ ] Iterative `_extract_videos` in alert.py (51K recursive calls, 6.7s CPU)
- [ ] Bypass SOCKS5 for local services (FlaskPaste, SearXNG)
- [ ] Connection pool tuning (529 SOCKS connections per 25min session)
- [ ] Async HTTP client (aiohttp + aiohttp-socks) to avoid blocking executors
- [x] Connection pooling via urllib3 SOCKSProxyManager
- [x] Batch OG fetch via ThreadPoolExecutor
- [x] HTTP opener caching at module level
- [x] Per-backend error tracking with exponential backoff
## Mumble
- [x] Mumble adapter via TCP/TLS + protobuf control channel (no SDK)
- [x] MumbleBot + MumbleMessage (duck-typed with IRC Message)
- [x] Text chat only (no voice)
- [x] Channel-based messaging
- [x] Minimal protobuf encoder/decoder (no protobuf dep)
- [x] pymumble transport rewrite (voice + text)
- [x] Music playback (yt-dlp + ffmpeg + Opus)
- [x] Voice STT/TTS (Whisper + Piper)
- [x] Multi-bot with per-bot plugin filtering
- [x] Configurable voice profiles (voice, FX chain)
- [x] Self-mute support (auto mute/unmute around audio)
- [x] Bot audio isolation (ignore own bots in sound callback)
- [x] Pause/unpause with position tracking, stale stream re-download, rewind + fade-in
- [x] Autoplay continuous radio (random kept track, silence-aware, configurable cooldown)
- [x] Periodic resume state persistence (survives hard kills)
- [x] Track duration in `!np` (ffprobe), optional `!announce` toggle
- [x] Direct bot addressing (`merlin: say <text>`)
- [x] Self-deafen on connect
- [ ] Per-channel voice settings (different voice per channel)
- [ ] Voice activity log (who spoke, duration, transcript)
## Music Discovery
- [ ] Last.fm integration (API key, free tier)
- [ ] `!similar` command -- find similar artists/tracks via Last.fm
- [ ] `!tags` command -- show genre/style tags for current track
- [ ] Auto-queue similar tracks when autoplay has no kept tracks
- [ ] MusicBrainz fallback (no API key, 1 req/sec rate limit)
## Slack
- [ ] Slack adapter via Socket Mode WebSocket (no SDK)
- [ ] SlackBot + SlackMessage (duck-typed with IRC Message)
- [ ] OAuth token + WebSocket for events
- [ ] Channel/DM messaging
- [ ] Permission tiers via user IDs
## Mattermost
- [ ] Mattermost adapter via WebSocket API (no SDK)
- [ ] MattermostBot + MattermostMessage (duck-typed with IRC Message)
- [ ] Self-hosted Slack alternative
- [ ] Channel/DM messaging
## Bluesky
- [ ] Bluesky adapter via AT Protocol firehose + REST API (no SDK)
- [ ] BlueskyBot + BlueskyMessage (duck-typed with IRC Message)
- [ ] Mention-based command dispatch
- [ ] Post/reply via `com.atproto.repo.createRecord`
## Testing
- [x] Plugin command unit tests (encode, hash, dns, cidr, defang)
- [x] CI pipeline (Gitea Actions)