Commit Graph
193 Commits
Author SHA1 Message Date
agessaman 448dc39261 docs(config): document settings-UI keys in config.ini.example + drift test
Eight keys that plugins read and the web settings UI writes were missing
from config.ini.example, so config validation flagged them as unknown:
Path_Command confidence symbols, Alert_Command max_distance_km /
max_incident_age_hours, Wx_Command temperature_unit / wind_speed_unit,
and PacketCapture mqtt_enabled.

Adds a sync test so any future settings_schema key must be documented in
the example config (and thus known to validation) or CI fails.
2026-07-12 11:57:28 -07:00
agessaman c5bcfb3f26 feat(config): enhance connection configuration and documentation
- Updated `config.ini.example`, `config.ini.minimal-example`, and `config.ini.quickstart` to clarify connection type precedence and required keys for serial, BLE, and TCP connections.
- Added detailed comments and examples for each connection type, ensuring users understand how to configure their connection settings effectively.
- Introduced a new `[Service_Overrides]` section in `config.ini.example` for alternative service plugin implementations, improving extensibility.
- Enhanced documentation in `configuration.md` to reflect these changes and provide clearer guidance on connection options and templates.
2026-07-09 23:25:11 -07:00
agessaman 7e7279875c feat(packet_capture): decode packet payloads to MQTT and log
Add optional payload decoding to the packet capture service. GRP_TXT
channel messages are decrypted (sender/text), ADVERTs are parsed
(name/role/lat-lon), and a nested "decoded" object is attached to each
packet alongside the unchanged raw fields.

- Comprehensive channel key store: bot's configured radio channels plus
  decode_hashtag_channels, [Channels_List], decode_channel_keys, and the
  built-in default Public key.
- Publishing the decoded object to MQTT is off by default and
  configurable per broker via mqttN_include_decoded.
- Configurable packet-log rotation (off/size/time) for historical dumps.

The decoder lives in a standalone, dependency-free module
(modules/meshcore_payload_decode.py) so it can be shared verbatim with
the meshcore-packet-capture project.

Closes #197
Closes #35
2026-07-08 10:49:06 -07:00
agessaman 95b0601980 feat(command_prefix, config): enhance command prefix handling and documentation
- Updated `config.ini.example` to support single, multiple, and decorative command prefixes, improving flexibility in command invocation.
- Refactored `CommandManager` and `BaseCommand` to utilize new command prefix parsing logic, allowing for better handling of multiple prefixes and optional bare commands.
- Enhanced documentation to clarify command prefix configuration options and behavior, ensuring users understand how to set and use prefixes effectively.
- Added unit tests to verify the correct functionality of command prefix handling, including support for permissive and strict prefix modes.
2026-07-07 09:37:28 -07:00
agessaman 18f231b142 feat(config, command): add hops placeholders to path command responses
- Updated configuration examples to include new `{hops}` and `{hops_label}` placeholders for path command replies, enhancing response detail.
- Modified `BaseCommand` to support hop count retrieval and formatting, ensuring accurate display of hop information in responses.
- Enhanced unit tests to verify correct formatting of hop-related placeholders in response messages, improving overall command functionality.
2026-07-06 11:29:47 -07:00
agessaman b59fa9cec9 feat(config, docs): enhance rain command and stats collection configuration
- Updated the `[Rain_Command]` section in `config.ini.example` to include support for snow alongside rain, improving the command's functionality.
- Enhanced documentation for the rain command to reflect the new snow alias and clarify response behavior based on the selected keyword.
- Added a new `collect_stats` option in the `[Stats_Command]` section, allowing stats collection to be enabled independently of the user-facing command, with updated documentation to explain its behavior.
- Improved the web viewer documentation to clarify how stats are collected and displayed, ensuring users understand the configuration options.
2026-06-28 13:28:23 -07:00
agessaman d23ee5db9e refactor(config): remove custom syntax section from configuration files
- Deleted the `[Custom_Syntax]` section from `config.ini.example` and `core.py`, simplifying the configuration by removing outdated custom syntax patterns and examples.
- This change streamlines the configuration files, focusing on essential settings and improving clarity for users.
2026-06-28 08:55:25 -07:00
agessaman 24fdfb2370 feat(command_manager, help_command): improve command prefix handling and help command visibility
- Enhanced `CommandManager` to persist normalized message content, preventing prefix stripping from interfering with command matching.
- Updated `BaseCommand` to skip prefix handling if already normalized, ensuring all commands can be matched correctly.
- Modified `HelpCommand` to ensure unused commands are listed even when command statistics are present, improving user accessibility to all commands.
- Added unit tests to verify the correct behavior of command matching and help command functionality under various scenarios.
2026-06-28 08:42:58 -07:00
agessaman 6584800cb7 feat(command_manager, models): enhance flood scope handling for channels
- Introduced per-channel flood scope configuration in `config.ini.example`, allowing for more granular control over message routing.
- Updated `CommandManager` to normalize channel names and resolve flood scopes based on channel-specific settings, improving message delivery accuracy.
- Enhanced `MeshMessage` to consider channel-specific flood scopes when determining the effective outgoing flood scope.
- Added unit tests to verify the new flood scope resolution logic and ensure correct behavior across various scenarios.
2026-06-27 17:09:28 -07:00
agessaman 986fe67c01 feat(test_command): add RSSI placeholder support in response formatting
- Enhanced the `TestCommand` class to include the `rssi` value in the response format, allowing for more detailed output.
- Updated the example configuration to reflect the new placeholder usage for `rssi`.
- Added a unit test to verify that the `rssi` placeholder expands correctly in the response message.
2026-06-27 16:41:11 -07:00
agessaman 3b6ef66fd9 feat(connection): enhance command serialization and pacing for radio communication
- Introduced a new class `_SerializedCommands` to serialize host-to-radio commands, ensuring only one command is in-flight at a time to prevent USB-CDC buffer overruns and parser desynchronization.
- Added configuration options for `command_min_interval_ms` and `channel_fetch_interval_ms` to control pacing between commands and channel scans, improving firmware stability during reconnect sequences.
- Updated `ChannelManager` to utilize the new fetch interval during channel scans, and modified the reconnect delay to 10 seconds for gentler recovery from connection issues.
- Enhanced documentation in `config.ini.example` to reflect new settings and their purposes.
2026-06-22 18:58:08 -07:00
agessaman ea50ff274d feat(config): update public key prefix length configuration
- Added a new configuration option `prefix_bytes` to specify the length of public key prefixes for repeaters, enhancing mesh graph key management.
- Updated the example configuration to reflect the new default value of 3 bytes, replacing the previous default of 1 byte.
- Improved documentation within the config file to clarify the purpose and usage of the `prefix_bytes` setting.
2026-06-21 10:52:31 -07:00
agessaman f7ec71a114 feat(worldcup): enhance match state announcements with card and stoppage tracking
- Added configuration options for announcing red cards, yellow cards, and match stoppages in `config.ini.example`.
- Updated `ESPNClient` to parse and include red and yellow card details in match state data.
- Enhanced `WorldCupLiveService` to announce red and yellow cards, including formatted messages for players and stoppage events.
- Implemented unit tests to validate the new card and stoppage announcement functionalities, ensuring accurate reporting during matches.
2026-06-18 16:29:27 -07:00
agessaman 21676f0792 feat(worldcup): add support for announcing disallowed goals and enhance goal tracking
- Introduced a new configuration option `announce_disallowed` to allow notifications for goals overturned by VAR.
- Updated `WorldCupLiveService` to handle disallowed goals, including formatting for previously announced scorers.
- Enhanced `ESPNClient` to ensure accurate goal tracking and state management.
- Added unit tests to validate the new disallowed goal functionality and ensure correct behavior during matches.
2026-06-17 22:11:24 -07:00
agessaman 7537c76c63 feat(worldcup): add World Cup command and service configuration
- Introduced World Cup command and service settings in `config.ini.example`, `config.ini.minimal-example`, and `config.ini.quickstart` to enable FIFA World Cup score tracking and updates.
- Enhanced `espn_client.py` with methods to fetch tournament calendar and match states, supporting the new World Cup features.
- Updated `sports_command.py` to resolve World Cup nation names and integrate with the new command.
- Added translations for World Cup commands and messages in multiple languages, ensuring comprehensive support for users.
- Included mappings for World Cup nations in `sports_mappings.py` to facilitate accurate team identification.
2026-06-14 19:33:20 -07:00
rlwilliamson-dev e5666b7cce feat(rain): minute-level rain nowcast command + proactive incoming/ending push
Add a rain nowcast (Open-Meteo 15-minutely precipitation — worldwide, no API
key) as both an on-demand `rain`/`nowcast` command and an opt-in Weather_Service
push that announces rain starting and stopping at the bot's position.

- modules/commands/rain_command.py — command plus pure, unit-tested
  fetch/analyze/dedup/label helpers (also reused by the service)
- modules/service_plugins/weather_service.py — background poller mirroring the
  existing weather-alert poll pattern; ships disabled (opt-in)
- Location labels resolve to "City, ST" (US) / "City, Country" (non-US)
- 34 unit tests; rain_command added to the strict-mypy module list
2026-06-03 18:56:24 -05:00
Felix Moessbauer ae6c5fbd6a feat(darc_mowas_service): set scope based on alert region
As scopes now become usable in MeshCore, we want to limit the
distribution of the alerts to the regions they are issued for. For that,
we provide a configuration interface to define which region ids
("Regionalschluessel") are mapped to which MeshCore scopes. This reduces
the noise on the warning channels.
2026-05-19 17:26:29 +02:00
agessaman 0b56e86de9 feat(multibyte): add multibyte monitor feature with API endpoints
- Introduced a new configuration option `multibyte_monitor_enabled` in `config.ini.example` to control the visibility of the multibyte monitor page and API endpoints.
- Implemented the `/multibyte-rollout` and `/api/multibyte-rollout` routes in the web viewer, which are accessible only when the multibyte monitor feature is enabled.
- Updated documentation in `web-viewer.md` to reflect the new feature and its configuration.
- Added tests to ensure the multibyte routes are disabled by default and accessible when enabled.
2026-05-18 16:39:48 -07:00
agessaman cb54ca6a45 fix(config): clarify flood scope configuration and logging behavior
- Updated `config.ini.example` and `configuration.md` to enhance clarity on the `outgoing_flood_scope_override` and `flood_scopes` settings, detailing their behavior and interactions.
- Improved logging in `CommandManager` to provide better insights into scope resolution and potential issues during message sending.
- Added new methods in `MessageHandler` for improved RF data correlation, ensuring eligibility checks for flood scope matching.
- Enhanced unit tests to cover new behaviors and ensure robust handling of flood scope configurations.
2026-05-17 14:38:47 -07:00
agessaman 74b7de6f72 feat(flood_scope): enhance flood scope handling across services
- Introduced optional regional TC_FLOOD scope configuration for various services, allowing for more granular control over message routing.
- Updated the CommandManager to resolve and apply flood scopes from messages, configuration sections, and explicit parameters, ensuring correct message delivery.
- Enhanced service plugins to utilize the new flood scope functionality, including weather, earthquake, and webhook services.
- Added unit tests to verify the correct resolution and application of flood scopes in different scenarios, ensuring robust functionality.
2026-05-16 12:08:24 -07:00
agessaman 9d24e4824c feat(config, docs): add JWT configuration options for MQTT authentication
- Introduced `jwt_ttl_seconds` and `jwt_renewal_interval` settings in `config.ini.example` for global JWT management, allowing for better control over token expiration and renewal intervals.
- Updated documentation in `packet-capture.md` to clarify the usage of global and per-broker JWT settings, enhancing user understanding of authentication configurations.
- Refactored `PacketCaptureService` to incorporate new JWT settings, ensuring consistent handling of token lifetimes and renewal processes.
2026-05-15 20:46:05 -07:00
agessaman 4a0b989f5a feat(scheduler): optional flood scope for scheduled channel messages
Parse channel:#scope:body in [Scheduled_Messages], pass scope to
send_channel_message; extend schedule list and docs.
2026-05-14 11:32:20 -07:00
agessamanandCursor d4eba9ad11 fix(scheduler): stagger scheduled sends and skip global rate limit
Scheduled cron jobs now pass the cron key into the send path, apply a
deterministic [0, N) second delay from scheduled_message_max_stagger_seconds
(default 1.5), and call send_channel_message with skip_user_rate_limit=True
so simultaneous jobs are not dropped by rate_limit_seconds. Per-channel and
bot_tx limits still apply. Document the new Bot key in config.ini.example;
tests assert kwargs, skip flag, and stagger behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 11:18:25 -07:00
agessaman 70b2256752 feat(test): Test_Command response_format with piped path filters
Add format_piped_template (pathbytes_min, prefix_if_nonempty), utils
bytes-per-hop helpers, and [Test_Command] format priority over Keywords.
2026-05-12 19:30:42 -07:00
agessaman 13f22e4d7b feat(path_command): add reply prefix and minimum path bytes configuration
- Introduced `reply_prefix` to prepend a customizable string to path command replies, supporting placeholders for dynamic content.
- Added `minimum_path_bytes` setting to control the resolution of repeater names based on the number of bytes per hop, enhancing path command behavior.
- Updated relevant documentation and translations to reflect these new configuration options.
- Implemented unit tests to ensure correct functionality of the new features.
2026-05-12 17:23:22 -07:00
agessaman 4d35e103a2 refactor(scheduler): enhance scheduled message configuration and parsing
- Updated the scheduled message format in `config.ini.example` to support 5-field cron expressions and preset aliases, replacing the deprecated HHMM format.
- Improved the `MessageScheduler` class to parse and validate new schedule formats, logging warnings for deprecated usage.
- Adjusted the `ScheduleCommand` to display scheduled messages with their respective cron or preset labels.
- Added unit tests to ensure correct parsing and handling of various schedule formats, including legacy HHMM and cron expressions.
2026-05-05 14:12:02 -07:00
agessaman 263c73c2e2 feat(packet_capture): enhance MQTT packet publishing controls and path length decoding
- Added configuration options `mqtt_skip_unparseable_packets` and `advert_require_valid_signature` to control MQTT publishing behavior based on packet validity.
- Updated `decode_path_len_byte` function to return `None` for reserved size codes, improving path length validation.
- Implemented logic in `PacketCaptureService` to skip publishing unparseable packets and ADVERT packets with invalid signatures.
- Introduced `verify_meshcore_advert_ed25519` function for signature verification of ADVERT packets, with corresponding unit tests to ensure functionality.
- Enhanced documentation to reflect new configuration options and their effects on packet processing.
2026-05-01 21:32:40 -07:00
agessaman d34ad24e9b feat(weather): add default city configuration for wx commands
- Introduced a new configuration option `default_city` in `config.ini.example` for fallback city names when no location is provided.
- Updated `wx_command.py` and `wx_international.py` to utilize the `default_city` for location disambiguation, enhancing user experience when companion location is unavailable.
- Improved logging to reflect the use of default city or bot location as fallback options.
2026-04-25 21:15:51 -07:00
Adam GessamanandGitHub a5f3cb008a Merge pull request #165 from fmoessbauer/fm/darc-mowas-api
feat: add implementation of the DARC MoWaS gateway
2026-04-25 20:29:34 -07:00
agessaman 63592bdd65 feat(commands, config): implement path byte length requirements for commands
- Added configuration options to specify minimum path byte length requirements for the path, test, and multitest commands.
- Introduced methods to enforce these requirements and handle failure responses.
- Updated the packet capture service to correctly calculate packet hashes using the raw wire byte length.
- Enhanced unit tests to verify the correct behavior of the new path byte length logic.
2026-04-25 09:05:17 -07:00
Felix Moessbauer 63fcd26f7c feat(darc_mowas_service): retry messages that are not acked
For alert messages it is imporant to be sure they are received by the
network. For that, we implement a retry logic that waits for at least
one ack from a repeater and re-sends the message chunk if non is
received within a retry timeout.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-04-24 16:16:44 +02:00
Felix Moessbauer ffd93edd96 feat: add implementation of the DARC MoWaS gateway
We implement support for the DARC MoWaS service that distributes
emergency messages from the German BBK via the "Warnmultiplikator"
interface to Meshcore channels. This service is push-based and receives
alerts on /api/alert, which are then formatted similar to cell-broadcast
messages (without modification of the text) and re-distributed on
Meshcore.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-04-24 16:16:43 +02:00
agessaman 5f40c45f07 feat(PacketCapture): align RX/RAW correlation with meshcore-packet-capture
Deduplicate RAW_DATA against RX_LOG_DATA hex, cache RF metadata by packet
prefix, extend RAW payload extraction, fix payload_len for multi-byte paths.
2026-04-21 19:26:09 -07:00
agessaman 0e5daadd04 feat(config, message_handler, repeater_manager, scheduler): implement device mode for auto-managing contacts
- Enhanced configuration options for `auto_manage_contacts` to support 'device' mode, allowing firmware to handle companion auto-addition and favourite hygiene.
- Updated `MessageHandler` to track new companions based on the `auto_manage_contacts` setting, with distinct behaviors for 'false', 'device', and 'bot' modes.
- Introduced scheduled jobs in `MessageScheduler` for device mode to manage firmware preferences and favourite keys with specified delays.
- Modified `RepeaterManager` to skip companion auto-purge in device mode, ensuring firmware manages contact slots effectively.
- Added tests to validate new behaviors and configurations, ensuring robust handling of contact management across different modes.
2026-04-20 21:26:17 -07:00
agessaman bf6bc14de7 release(v0.9.0): readiness — silent-subscribe tests, py310, RF correlation fix
- Rewrite test_subscribe_packets/messages_emits_status_ack to match the
  silent subscription UX from 1ee84f2.
- Reconcile Python version: requires-python>=3.10, ruff target py310, CI
  matrix adds 3.13, pyupgrade UP0xx ignored pending a separate typing-rewrite
  PR; fix two B905 zip(strict=...) lints.
- Issue #80 fix in find_recent_rf_data: return None when correlation_key is
  provided but unmatched; prefer the longest observed path among samples
  sharing a packet_hash; narrow the no-key fallback to a configurable
  rf_fallback_window (default 2s).
- Issue #161: lower shipped max_response_hops default 10 -> 7.
- Add CHANGELOG.md, restructure BUGS.md around a ## v0.9.0 Fixed Bugs
  table, prune crossed-out duplicate outstanding rows, and add a
  Deferred-from-v0.9.0 triage section to TODO.md.
- Untrack coverage.json and add it to .gitignore.

Made-with: Cursor
2026-04-17 13:53:13 -07:00
agessaman b5cce55604 feat(config): add configurable timeouts for web viewer integration
Introduced optional timeout settings in the configuration for various web viewer operations, including edge and node post timeouts, SQLite connection timeout, and requeue timeout. Updated the web viewer integration to utilize these settings, enhancing flexibility and reliability. Added commands to inspect the resolved configuration with sensitive keys redacted, and updated documentation accordingly.
2026-04-16 19:56:47 -07:00
agessaman a4d5f5478b feat: add RandomLine command support for website generation
Introduced a new command structure for RandomLine entries in the website generation process, allowing for dynamic rendering of random lines based on configuration. Updated the configuration file to include a new category option for commands and enhanced documentation to reflect these changes. This addition improves the command reference organization and user experience on the website.
2026-04-15 09:40:39 -07:00
agessaman 90fdd0c77a feat: add cmd_reference_url option for Cmd_Command
Introduced a new configuration option `cmd_reference_url` in the Cmd_Command section, allowing users to override the default `cmd` output with a link to a full documentation page. Updated the CmdCommand class to utilize this new setting and modified related documentation and tests to ensure proper functionality.
2026-04-15 09:26:19 -07:00
agessaman 313dfccf75 fix: Align send suppression and security compatibility behavior
Make outbound send suppression consistent by honoring both radio-offline and zombie states across command-manager and scheduler paths. Preserve strict SSRF defaults while adding explicit private-feed URL opt-ins, persist allow_local_smtp from notifications config writes, reconcile zombie alert setting precedence, and replace deprecated UTC timestamp calls with timezone-aware UTC usage.
2026-04-14 12:18:02 -07:00
agessaman b8210b0fbe feat: enhance radio and admin configuration settings
Added new configuration options for radio health monitoring and alerting in config.ini.example, including radio_offline_threshold, radio_offline_alert_enabled, and radio_offline_alert_email. Introduced an [Admin] section with settings for a local admin API, including enabled, port, and token fields. Updated related files to reflect these changes, improving the organization and functionality of the configuration structure.
2026-04-14 11:44:17 -07:00
agessaman af6f693cff refactor: update max_results configuration for airplanes command
Changed the default value of max_results in config.ini.example from 0 (no limit) to 3, ensuring a more manageable output size for aircraft listings. Updated the AirplanesCommand class to reflect this new default and added logic to handle message size constraints when formatting the aircraft list. This refactor improves the user experience by preventing excessive data in responses while maintaining functionality.
2026-04-14 11:35:00 -07:00
agessaman 52227ae6ac refactor: replace fortune command with random lines fortunes command
Removed the fortune command and its associated files, transitioning to existing new random lines command that retrieves fortunes from a different file structure. Updated configuration settings in config.ini.example to reflect this change, including the new file path for fortunes. Adjusted the .gitignore to accommodate the new directory structure for random lines. This refactor enhances the organization of fortune-related content and improves maintainability.
2026-04-14 11:27:40 -07:00
agessaman 293383f885 refactor: reorganize radio configuration settings
Moved radio-related configuration options from the [Bot] section to a new [Connection] section in config.ini.example for better organization. Updated the core logic to reference the new configuration paths, ensuring that radio health monitoring and alert settings are correctly handled. This change enhances clarity and maintainability of the configuration structure.
2026-04-14 11:14:28 -07:00
Stacy Olivasandagessaman 7403c1e946 feat: airplanes command sends all aircraft without truncation
Remove the "(x more)" truncation from _format_aircraft_list — all
matching aircraft are now returned. The hard max_results=10 cap is
replaced with max_results=0 (no limit) as the default; operators can
still set max_results in config.ini to impose a ceiling, and users can
pass limit=N per-query. List results always route through
_send_split_response for chunked multi-message delivery.
2026-04-14 10:07:38 -07:00
Stacy Olivasandagessaman 13c10fd1a5 feat: add fortune command reading BSD fortune file format
Adds a new !fortune command that picks a random fortune from a
configured BSD-format fortune file (entries separated by a line
containing only %). The parser handles: % as separator or terminator,
multi-line fortunes, trailing whitespace, and % embedded mid-line.

Path validation via validate_safe_path() blocks path traversal before
any file open. Command is auto-discovered by the plugin loader.

Config section [Fortune_Command] added to config.ini.example with
enabled and file keys. Default file: data/fortune/fortunes.txt.

22 tests cover: parsing edge cases, security path rejection,
can_execute enable/disable, execute happy path, empty file fallback,
and plugin metadata.

Fortune file: BSD V8-fortunes (fortunes-freebsd-classic)
Source: https://github.com/HubTou/fortunes-freebsd-classic
1,903 fortunes drawn from the classic BSD UNIX fortune database.

Content note -- data/fortune/fortunes.txt (1,903 fortunes):
No racist, lewd, or pornographic content found. Six lines flagged
during review as mildly coarse; retained but noted here for reference
in case a future maintainer wishes to remove them:

  L1763: Some days chicken salad -- some days chicken shit.
  L2289: We retard what we cannot repel, we palliate what we cannot
         cure. -Johnson
  L3009: In New York they signal the wrong way just to fuck you up.
         -David Yost
  L3161: Sure [Somoza]'s a son-of-a-bitch, but he's OUR
         son-of-a-bitch.  -F.D. Roosevelt
  L3305: When better machines are built, jks will break them, and td
         will bitch about it.
  L3589: It's the thought, if any, that counts! -Dick Grantges
         ("Dick" is a proper name, not a slur)
2026-04-14 10:07:35 -07:00
agessaman 887068faa2 fix: resolve merge-marker cleanup and concise config docs
Clean up residual cherry-pick conflict markers and keep SMTP guidance in config templates brief while preserving full behavior in code and tests.

Made-with: Cursor
2026-04-14 10:06:44 -07:00
Stacy Olivasandagessaman 54aeb28bf0 security: SSRF hardening, log injection sanitization, and allow_local_smtp
Add SSRF host validation to maintenance.py send_nightly_email and
scheduler.py send_zombie_alert_email using validate_external_url().
New allow_local_smtp config key permits private-IP SMTP for local
relay setups.

Add sanitize_name() to security_utils and apply it to all log calls
in message_handler, repeater_manager, path_command, solarforecast_command,
command_manager, and discord_bridge_service to prevent log injection.

Move nightly email logic from duplicate scheduler._send_nightly_email()
into the canonical maintenance.py implementation, removing the duplicate.
Update tests to call maintenance.send_nightly_email() directly.

Add validate_external_url allow_private parameter with support for
loopback, RFC1918, CGN, and link-local address ranges.
2026-04-14 10:02:36 -07:00
Stacy Olivasandagessaman 9ce69702c2 feat: radio debug logging mode with web UI toggle 2026-04-14 10:01:51 -07:00
Stacy Olivasandagessaman d0ae737066 feat: zombie radio detection — health probe, timeout guards, and alert system 2026-04-14 10:01:51 -07:00
agessaman 8bea10cdc3 Enhance mention handling in message processing
- Updated `config.ini.example` to introduce the `respond_to_mentions` setting, allowing configuration of how the bot responds to mentions in channel messages.
- Refactored `MessageHandler` to implement logic for handling mentions based on the new configuration, including stripping mentions when appropriate.
- Added `cleanup_message_for_matching` method in `BaseCommand` to streamline message processing and mention validation.
- Enhanced various command classes to utilize the new cleanup method for consistent mention handling.
- Introduced tests to validate the behavior of the new mention handling logic across different configurations.
2026-04-11 18:45:34 -07:00