- Add MC_TCP_HOST and MC_TCP_PORT options to .env.example with clear
documentation for serial vs TCP transport selection
- Change default MC_TCP_PORT from 5000 to 5555 (avoids Flask conflict)
- Wire MC_TCP_HOST/MC_TCP_PORT through docker-compose.yml from .env
(previously was commented-out hardcoded values)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update api.py: messages, contacts, DM endpoints read from SQLite DB
- Add DB fallback paths for parser.py backward compatibility
- Replace bridge echo registration with DeviceManager event handling
- Update status endpoint to use db.get_stats()
- Update channel updates/DM updates endpoints for DB queries
- Delete channel messages via DB instead of parser
- Remove meshcore-bridge/ directory (no longer needed in v2)
- Remove MC_BRIDGE_URL from config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This variable was defined but never used in the code.
Contact cleanup threshold is controlled directly in the UI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bridge now detects device name from meshcli prompt ("DeviceName|*")
and exposes it via /health endpoint. mc-webui fetches this at startup
and uses RuntimeConfig for dynamic device name throughout the app.
Fallback chain: prompt detection → .infos command → MC_DEVICE_NAME env var
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove workaround for meshcore-cli 1.3.11 bug where SENT_MSG contained
sender name instead of recipient. Now using native SENT_MSG entries from
.msgs file with correct recipient and sender fields (requires meshcore-cli >= 1.3.12).
Changes:
- Add _parse_sent_msg() to parse SENT_MSG from .msgs file
- Update read_dm_messages() to process both PRIV and SENT_MSG from .msgs
- Remove save_sent_dm(), _read_sent_dm_log(), _parse_sent_dm_entry()
- Remove dm_sent_log_path property from config
- Add _cleanup_old_dm_sent_log() to remove obsolete log file
- Update comments and documentation
Benefits:
- Single source of truth (.msgs file only)
- Simpler codebase (-95 lines)
- No custom workarounds
- Better data consistency
Related: meshcore-cli update to 1.3.12 (commit ad4a7b3)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace DM modal with full-page view at /dm route for better mobile UX
- Add workaround for meshcore-cli bug where SENT_MSG contains sender's
name instead of recipient - now saving sent DMs to separate log file
- Fix DM button styling to match Reply button (btn-outline-secondary)
- Add dm.js for DM page functionality
- Add dm.html template with green navbar for visual distinction
- Update menu link to navigate to /dm instead of opening modal
- Remove unused DM modal functions from app.js
- Update documentation with new DM workflow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BREAKING CHANGE: Switched from single-container to multi-container setup
This commit introduces a meshcore-bridge service that isolates USB device
access from the main application, resolving persistent USB timeout and
deadlock issues in Docker + VM environments.
Changes:
- Add meshcore-bridge/ - Lightweight HTTP API wrapper for meshcli
- Flask server exposes /cli endpoint (port 5001, internal only)
- Exclusive USB device access via --device flag
- Health check endpoint at /health
- Refactor app/meshcore/cli.py
- Replace subprocess calls with HTTP requests to bridge
- Add requests library dependency
- Better error handling for bridge communication
- Update docker-compose.yml
- Define meshcore-bridge and mc-webui services
- Create meshcore-net Docker network
- Add depends_on with health check condition
- Bridge gets USB device, main app uses HTTP only
- Modify Dockerfile
- Remove meshcore-cli installation from main app
- Lighter image without gcc dependencies
- Update config.py
- Add MC_BRIDGE_URL environment variable
- Remove meshcli_command property (no longer needed)
- Update documentation (README.md, .claude/instructions.md)
- Document 2-container architecture
- Add troubleshooting section for bridge
- Update prerequisites (no host meshcore-cli needed)
- Add architecture diagram in project structure
Benefits:
✅ Solves USB device locking after container restarts
✅ Restartable main app without USB reset
✅ Better separation of concerns
✅ Easier debugging (isolated meshcli logs)
✅ No manual USB recovery scripts needed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements automatic daily archiving of messages to improve performance
and enable browsing historical chat by date.
Backend changes:
- Add APScheduler for daily archiving at midnight (00:00 UTC)
- Create app/archiver/manager.py with archive logic and scheduler
- Extend parser.py to read from archive files and filter by days
- Add archive configuration to config.py (MC_ARCHIVE_*)
API changes:
- Extend GET /api/messages with archive_date and days parameters
- Add GET /api/archives endpoint to list available archives
- Add POST /api/archive/trigger for manual archiving
Frontend changes:
- Add date selector dropdown in navbar for archive browsing
- Implement archive list loading and date selection
- Update formatTime() to show full dates in archive view
- Live view now shows only last 7 days (configurable)
Docker & Config:
- Add archive volume mount in docker-compose.yml
- Add MC_ARCHIVE_DIR, MC_ARCHIVE_ENABLED, MC_ARCHIVE_RETENTION_DAYS env vars
- Update .env.example with archive configuration section
Documentation:
- Update README.md with archive feature and usage instructions
- Update .claude/instructions.md with archive endpoints
Key features:
- Automatic daily archiving (midnight UTC)
- Live view filtered to last 7 days for better performance
- Browse historical messages by date via dropdown selector
- Archives stored as dated files: {device}.YYYY-MM-DD.msgs
- Original .msgs file never modified (safe, read-only approach)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented core backend functionality:
- Flask application structure with blueprints
- Configuration module loading from environment variables
- MeshCore CLI wrapper with subprocess execution and timeout handling
- Message parser for .msgs JSON Lines file format
- REST API endpoints (messages, status, sync, contacts cleanup)
- HTML views with Bootstrap 5 responsive design
- Frontend JavaScript with auto-refresh and live updates
- Custom CSS styling for chat interface
API Endpoints:
- GET /api/messages - List messages with pagination
- POST /api/messages - Send message with optional reply-to
- GET /api/status - Device connection status
- POST /api/sync - Trigger message sync
- POST /api/contacts/cleanup - Remove inactive contacts
- GET /api/device/info - Device information
Features:
- Auto-refresh every 60s (configurable)
- Reply to messages with @[UserName] format
- Toast notifications for feedback
- Settings modal for contact management
- Responsive design (mobile-friendly)
- Message bubbles with sender, timestamp, SNR, hop count
Ready for testing on production server (192.168.131.80:5000)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>