Added two new HTTP endpoints to meshcore-bridge for managing pending contacts
(contacts awaiting manual approval when manual_add_contacts mode is enabled):
New endpoints:
- GET /pending_contacts - List all pending contacts awaiting approval
- Parses meshcli output format: "Name: <hex_public_key>"
- Returns JSON array with {name, public_key} objects
- Includes raw_stdout for debugging
- POST /add_pending - Approve and add a pending contact
- Accepts JSON body: {"selector": "<name_or_pubkey>"}
- Validates selector is non-empty string
- Executes meshcli add_pending command via persistent session
Additional changes:
- Added curl to mc-webui Dockerfile for testing endpoints
- Updated README with Testing Bridge API section
- Included example curl commands and expected responses
Implementation notes:
- Uses existing MeshCLISession.execute_command() - no new processes
- Same persistent session and command queue architecture
- Consistent error handling with existing /cli endpoint
Enables future UI for manual contact approval workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 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>
Moved Dockerfile and docker-compose.yml from docker/ to root directory for simpler workflow.
This allows running 'docker compose up' directly without -f flag.
Changes:
- Moved docker/Dockerfile -> Dockerfile
- Moved docker/docker-compose.yml -> docker-compose.yml
- Updated docker-compose.yml context and env_file paths
- Updated README.md with simplified Docker commands
- Updated CLAUDE_CODE_PROMPT.md project structure
- Moved .claude/instructions.md to root (from technotes/)
- Updated all documentation to reflect new structure
Now deployment is simpler:
docker compose up -d --build
instead of:
docker compose -f docker/docker-compose.yml up -d --build