Commit graph

11 commits

Author SHA1 Message Date
Rosie Val
5e41658d7d Re-enable Report/Delete/Profile context menus, remove Bookmark, fix reports
Re-enabled the "Report to Wormhole", "Delete from Network", and "Wormhole
Profile" context menus (previously disabled entirely). Removed "Bookmark
(Wormhole)" per request — the prefix `wh bm list`/`clear` commands are
untouched, but note this was the only way to *add* a bookmark, so that
feature is now list/clear-only for existing entries.

Wormhole Profile is now considerably richer: account creation date, total
cross-network message count, global-ban status, and per-network karma/
server-count/muted/banned status, sorted busiest-network-first.

Fixed both report-creation paths (the "Report to Wormhole" context menu's
modal, and `wh report msg`): report_counter was read before the config lock
and written after, so concurrent reports could collide on the same id with
the counter never advancing. Now computed and saved atomically inside the
lock. Also gave both paths full parity — message id, jump link, and a real
content preview (the context-menu path previously stored `hash()` of the
content, which is randomized per-process in Python 3 and useless for
anything; the prefix-command path never even recorded who wrote the
message). `wh report view` now surfaces all of it.

Also added the "Find Origin" context menu (right-click a message -> find
its true source server/channel/author across the network) as a separate,
complementary feature to Profile — not a replacement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 00:02:49 +01:00
Rosie Val
ece196748c Add Wormhole 'Find Origin' right-click context menu
Right-click any relayed message -> Apps -> Find Origin resolves it back to
the true source: origin server (name + ID), channel, author (name + ID),
message ID, and a jump link. Uses the existing message_map reverse lookup,
falling back to the same brute-force search across the network's member
channels that _ctx_delete_message/wh mod nuke already rely on when the
relay map doesn't have a direct answer. Mod-gated (deanonymizes real
identity across servers). Registered independently of the existing bulk
Report/Bookmark/Delete/Profile context-menu registration, which is
currently disabled — left that decision alone rather than reviving it as
a side effect.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 23:53:57 +01:00
root
2f97926ca6 fix(wormhole): remove wait_until_ready() from _init() to prevent load timeout
Root cause: _init() was blocking on wait_until_ready() for up to 30 seconds,
causing Red's package load to timeout. Red then reports 'Failed to load
package wormhole (timeout)' but the cog is actually partially loaded,
causing 'already loaded' errors on retry.

Timeline:
1. [p]load wormhole starts
2. setup() calls bot.add_cog(cog) ✓
3. setup() calls await cog._init()
4. _init() blocks on wait_until_ready() for 30s
5. Red's load timeout (30s) triggers
6. Red reports 'timeout' but cog is registered
7. [p]load wormhole again → 'already loaded' error

Solution: Remove wait_until_ready() from _init() since:
- Bot is already ready when cogs load on startup
- Background loops have their own wait_until_ready() calls
- _init() shouldn't block setup()

Background loops still wait_until_ready() independently (correct behavior).

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-05-26 16:43:46 +00:00
root
6fd48e93af fix(wormhole): rename cog class to WormholeV4 to bypass stale registration
Problem: Red's internal state has stale 'Wormhole' cog registrations from
previous versions (both identifier 7730187301 and 928374650), causing
'Cog named Wormhole already loaded' errors even on fresh bot starts.

Root cause: Multiple config identifiers registered under same cog name:
  - wormhole: {'wormhole': {}}  (old lowercase)
  - Wormhole: {'7730187301': {}, '928374650': {}}  (two identifiers!)

Solution: Rename cog class Wormhole → WormholeV4 to bypass all stale
registration state. This gives a clean slate without requiring users to
manually purge config data.

Changes:
- class Wormhole → class WormholeV4 in core.py
- Updated __init__.py import and setup()
- Config identifier unchanged (928374650)

This completely sidesteps the phantom load bug without touching user data.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-05-26 16:38:56 +00:00
root
0c41ae0b9f feat(wormhole): disable context menus to eliminate load issues
Problem: Context menus persist in Discord's command tree even after bot
shutdown, causing 'already loaded' errors on restart. The idempotent
registration fix helped but added complexity.

Solution: Disable context menus entirely. All functionality remains
available via slash/prefix commands:
  - Report: /wh report message [msg_id] [reason]
  - Bookmark: /wh bookmark save [msg_id]
  - Delete: /wh delete [msg_id] (staff only)
  - Profile: /wh profile [user]

Changes:
- Commented out _register_context_menus() call in _init()
- Kept registration/callback code for future reference
- Simplified cog_unload() - no context menus to remove

Benefits:
- No command tree registration complexity
- Clean reload every time
- No phantom 'already loaded' state
- Simpler cog lifecycle

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-05-26 16:35:27 +00:00
root
c8bc14fb42 fix(wormhole): make context menu registration idempotent
Problem: If bot crashes or shuts down ungracefully, context menus stay
registered in Discord's command tree. On restart, add_command() fails
with 'already loaded' error.

Solution: Remove existing context menus before registering new ones.
This makes registration idempotent (safe to run multiple times).

Changes:
- _register_context_menus() now removes existing menus first
- Wrapped in try/except to handle 'not found' gracefully
- Ensures clean reload even after ungraceful shutdown

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-05-26 16:33:09 +00:00
root
44d7f79c13 fix(wormhole): fix persistence bug and finalize v4.0.0 modular architecture
BREAKING: Removed obsolete monolithic wormhole.py (4,782 lines)
The v4.0.0 modular architecture was already implemented but the old
file was still present causing confusion.

Fixes:
- Fix context menu cleanup in cog_unload (add type parameter)
- Remove obsolete wormhole.py monolith (archived as .old)
- Context menus now properly unregister on reload

Architecture:
- core.py (731 lines) - main cog class
- commands/ (14 modules, 2,645 lines) - command mixins
- listeners/ (3 modules) - event handlers
- models/ (3 modules) - data structures
- services/ (1 module) - business logic
- ui/ (2 modules) - Discord UI components

Documentation:
+ ARCHITECTURE.md - design overview and history
+ MODULE_MAP.md - developer quick reference

This fixes the "already loaded" phantom state bug where wormhole
wouldn't persist through restarts and required double-loading.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-05-26 16:26:03 +00:00
Viktor AI
2ad7a7b691 fix: wire up missing feature enforcement in relay
- Mirror channels now receive relayed messages (was blocked from sending but never sent to)
- Server allowlist enforced in relay (allowlist_servers gate check)
- Silent mode suppresses status broadcasts (_status respects 'silent' flag)
- Welcome message sent when channel joins via 'wh open'
2026-05-14 19:33:58 +00:00
Viktor AI
4bc143b26f fix: group all commands under 'wh' parent — no more flat wh-xxx commands
Commands now show as 'wh create', 'wh staff add', 'wh set relaymode'
instead of 'wh-create', 'wh-staff add', 'wh-set relaymode'.

- Added commands/_base.py with root 'wh' group and all 20 subgroup stubs
- All 13 command mixins inherit from WormholeBase
- Decorators changed: @commands.hybrid_command(name='wh-X') → @WormholeBase.wh.command(name='X')
- Subgroup commands: @wh_X.command() → @WormholeBase.wh_X.command()
- Removed duplicate 'wh' group from core.py (now in _base.py)
- Fixed alias: 'wh-color' → 'color' for colour command
2026-05-14 19:24:37 +00:00
Viktor AI
5a4421fb6c fix: remove duplicate slash command registrations causing CommandAlreadyRegistered
The hybrid_command decorator on mixin classes already auto-registers
slash commands. The manual registrations in _register_context_menus
clashed, causing 'wh-list already registered' on load. Removed all
manual slash commands — only context menus remain.
2026-05-14 19:12:55 +00:00
Viktor AI
0b028e7bb9 refactor: Wormhole v4.0.0 — full modular architecture with hierarchical staff
BREAKING: Complete cog restructure from monolithic wormhole.py into modular architecture.

## Architecture
- models/permissions.py — Role IntEnum (MEMBER→OWNER), requires_role() decorator
- models/config.py — DEFAULT_NETWORK/DEFAULT_GLOBAL with 80+ config keys
- models/message_map.py — MessageMap class (extracted from _MessageMap)
- services/emoji.py — Foreign emoji resolution and relay
- ui/views.py — Reply jump button view
- ui/modals.py — Report modal
- core.py — Main Wormhole class, helpers, background loops, context menus
- commands/ — 13 command modules as mixin classes
- listeners/ — relay pipeline, edit/delete/reaction sync, typing/pin sync

## Staff System (new)
Per-network hierarchical roles replacing flat owner/staff:
  Bot Owner (Red built-in) — global override
  └─ Network Owner → Admin → Moderator → Helper → Member
  Each role assigned per-network. Higher roles can assign lower.
  Legacy staff_ids auto-migrated to ADMIN role.

## Enhanced Moderation
- Server-level ban/mute (not just user-level)
- Allowlist mode (only whitelisted servers can send)
- Mod edit and nuke (delete N messages by user)
- Anti-raid detector with auto-freeze
- Expanded automod: anti-zalgo, anti-emote-spam, anti-newline-spam

## Commands (100+)
network, settings, staff, moderation, filters, social, dm, mentions,
tos, reports, bridge, advanced (polls/afk/auto-responses/scheduled/
analytics/quiet-hours/colours/invites/announcements/blackout/portal),
debug (health/trace/testsend/relaydebug/backup/restore/version)

## Files
- 30 Python files, 5,274 lines total (was 4,782 in monolith)
- Original wormhole.py preserved for reference
- utils.py unchanged (all helpers reused)
2026-05-14 19:07:49 +00:00