Files
meshcore-bot/TODO.md
T
agessaman 8d1c5ea9c0 build(web_viewer): vendor the last CDN libraries and keep them updated with Dependabot
Bootstrap 5.1.3, Font Awesome 6.0.0, Socket.IO 4.7.2 and Chart.js 4.4.0 are now served from static/vendor/ at the versions the CDNs served, so every page works on a LAN with no internet. Only map tiles still need it. The Content-Security-Policy drops jsDelivr and cdnjs.

Every vendored package, the map stack and login fonts included, is pinned in scripts/web-vendor/package.json and its lockfile. sync.mjs copies the listed files into static/, strips the source-map comment, empties each directory it owns first, and regenerates the version table in static/vendor/README.md; it reproduces the previously vendored files byte for byte. Font Awesome ships only its woff2 fonts, which every supported browser takes before the .ttf.

Dependabot watches that directory: security fixes as advisories land, grouped minor and patch releases monthly, majors one per PR. Dependabot can't regenerate the vendored files, so vendor-refresh.yml adds them to its PRs as a second commit and dispatches the tests, since a GITHUB_TOKEN push doesn't trigger them. It runs on pull_request_target, so it uses the base branch's sync.mjs, spells out its commands instead of running the PR's npm scripts, and installs with install scripts disabled. A new CI job re-runs the sync and fails if anything under static/ changes.

Tests now check that no template loads a script, stylesheet or font from another host, that every vendored file a template names exists, and that the CSP allows no CDN host. In Chrome, 12 pages load with no external request, failed load or console error.
2026-10-24 12:02:40 -07:00

5.2 KiB
Raw Blame History

TODO

Forward-looking task list for meshcore-bot development. Completed work is not tracked here — see CHANGELOG.md for shipped changes and BUGS.md for known defects.

The Inline TODOs section at the bottom is auto-generated by python scripts/update_todos.py (see Auto-Update).

Last updated: 2026-09-20. The v1.1.0 suite reports 57% coverage, and fail_under = 50.


Test coverage

Coverage is 57% as of v1.1.0. The enforced floor is 50%.

Hardware- and API-dependent modules cap the realistic ceiling, so the list below is ordered by value rather than by percentage. Per-module figures below are from the v1.0.0 run and should be refreshed in a separate coverage review.

Pure logic — best value:

  • greeter_command.py (15%) — greeting detection, per-channel greetings, new-contact detection
  • repeater_command.py (10%) — repeater list/info formatting
  • sports_command.py (16%) — score formatting, schedule display
  • prefix_command.py (13%) — prefix lookup and collision paths
  • alert_command.py (21%) — alert formatting and thresholds
  • trace_runner.py (24%) — trace execution, path assembly
  • earthquake_service.py (17%) — alert threshold, message format (USGS API is mockable)
  • telegram_bridge_service.py (36%) — message relay, topic routing, listener lifecycle
  • packet_capture_utils.py (12%) — decode and dimension helpers

API/hardware heavy — lower priority:

  • solarforecast_command.py (11%), map_uploader_service.py (10%), airplanes_command.py (10%), wx_command.py (18%)

Other:

  • MQTT fixture parser tests — decode raw hex, validate payload types against tests/fixtures/mqtt_packets.json. See the MQTT Test Framework section of TESTING.md.

Planned features

Bridges

  • Two-way Discord bridge — receive messages from Discord and relay to MeshCore
  • Two-way Telegram bridge — relay Telegram messages back into MeshCore channels
  • Telegram message_thread_id support — route bridged messages to forum topics (BUG-008)
  • Bridge DM support — optional, opt-in bridging of DMs (requires a consent mechanism)

Web viewer

  • Mobile-responsive improvements — optimize layout for small screens
  • Dashboard follow-ups — wire the expand-chart interaction to /api/dashboard/series (the endpoint exists, no UI yet); consider the deferred observed_paths(last_seen, path_length, bytes_per_hop, public_key) covering index if refresher timing shows the path-length histogram dominating
  • Evaluate moving the web viewer to a separate installable package

Commands and features

  • !wx non-US improvement — promote wx_international.py to default with US fallback
  • Repeater auto-purge dry-run mode — log what would be purged without acting
  • Feed manager JSON API feeds — support JSON endpoints, not just RSS/Atom

Backlog

  • TheSportsDB request fan-out — fetch_league_scores() (modules/clients/thesportsdb_client.py:305–314) gathers ~8 calls (next events + past events + one per day for 6 days). _rate_limit() is correctly serialized by an asyncio.Lock, so those 8 calls take ~17 s wall clock at min_request_interval = 2.1, and the client is a single shared instance (sports_command.py:92) — one sports nfl blocks every other TheSportsDB-backed command for that whole window. The lock is not the bug: without it the calls burst past the documented free-tier limit and risk 429s. Fix the fan-out instead — collapse the 6 per-day calls into a single range query if the API supports it, cache per-league results for the poll interval, or drop the day-by-day lookahead. Consider a user-visible "working…" ack if latency stays high.
  • meshcore IndexError handler polish — the base fix shipped (BUG-022); the asyncio exception handler in core.py:start() suppresses at DEBUG. Revisit whether it can be narrowed.

Triage

  • PR #25 — "Add Docker containerization support" — still open; close as superseded by the in-repo Dockerfile, docker-compose.yml, and multi-arch build pipeline
  • Issue #137 — minimal-config install "not responding" — needs a reporter repro with logs before it can be actioned

Auto-Update

The Inline TODOs section below is auto-generated by scanning source files for # TODO, # FIXME, and # HACK markers. Regenerate it with:

python scripts/update_todos.py

The script also updates the **Last updated:** date at the top of this file, and --check exits non-zero if the file is stale (for a CI gate).

Or run it as part of a pre-commit hook by adding to .pre-commit-config.yaml:

- repo: local
  hooks:
    - id: update-todos
      name: Update TODO.md inline scan
      language: python
      entry: python scripts/update_todos.py
      pass_filenames: false

Inline TODOs (auto-generated)

Last scanned: 2026-08-07. No # TODO, # FIXME, or # HACK markers found in modules/ or tests/. Run python scripts/update_todos.py to refresh.