mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-05-10 07:15:09 +02:00
Update CLAUDEs
This commit is contained in:
@@ -92,6 +92,7 @@ A web interface for MeshCore mesh radio networks. The backend connects to a Mesh
|
||||
│ │ ├── useWebSocket.ts # WebSocket hook
|
||||
│ │ └── components/
|
||||
│ │ ├── CrackerPanel.tsx # WebGPU key cracking
|
||||
│ │ ├── MapView.tsx # Leaflet map showing node locations
|
||||
│ │ └── ...
|
||||
│ └── vite.config.ts
|
||||
├── references/meshcore_py/ # MeshCore Python library
|
||||
@@ -206,6 +207,10 @@ All endpoints are prefixed with `/api` (e.g., `/api/health`).
|
||||
| POST | `/api/messages/direct` | Send direct message |
|
||||
| POST | `/api/messages/channel` | Send channel message |
|
||||
| POST | `/api/packets/decrypt/historical` | Decrypt stored packets |
|
||||
| GET | `/api/packets/decrypt/progress` | Get historical decryption progress |
|
||||
| POST | `/api/packets/maintenance` | Delete old packets (cleanup) |
|
||||
| POST | `/api/packets/dedup` | Remove duplicate raw packets |
|
||||
| GET | `/api/packets/dedup/progress` | Get deduplication progress |
|
||||
| POST | `/api/contacts/{key}/mark-read` | Mark contact conversation as read |
|
||||
| POST | `/api/channels/{key}/mark-read` | Mark channel as read |
|
||||
| POST | `/api/read-state/mark-all-read` | Mark all conversations as read |
|
||||
|
||||
@@ -331,6 +331,50 @@ KeyStore.clear_private_key()
|
||||
- Never logged
|
||||
- Lost on server restart (must re-export from radio)
|
||||
|
||||
## Advertisement Parsing (`decoder.py`)
|
||||
|
||||
Advertisement packets contain contact information including optional GPS coordinates.
|
||||
|
||||
### Packet Structure
|
||||
|
||||
```
|
||||
Bytes 0-31: Public key (32 bytes)
|
||||
Bytes 32-35: Timestamp (4 bytes, little-endian Unix timestamp)
|
||||
Bytes 36-99: Signature (64 bytes)
|
||||
Byte 100: App flags
|
||||
Bytes 101+: Optional fields (location, name) based on flags
|
||||
```
|
||||
|
||||
### App Flags (byte 100)
|
||||
|
||||
- Bits 0-3: Device role (1=Chat, 2=Repeater, 3=Room, 4=Sensor)
|
||||
- Bit 4: Has location (lat/lon follow)
|
||||
- Bit 5: Has feature 1
|
||||
- Bit 6: Has feature 2
|
||||
- Bit 7: Has name (null-terminated string at end)
|
||||
|
||||
### GPS Extraction
|
||||
|
||||
When bit 4 is set, latitude and longitude follow as signed int32 little-endian values,
|
||||
divided by 1,000,000 to get decimal degrees:
|
||||
|
||||
```python
|
||||
from app.decoder import parse_advertisement
|
||||
|
||||
advert = parse_advertisement(payload_bytes)
|
||||
if advert:
|
||||
print(f"Device role: {advert.device_role}") # 1=Chat, 2=Repeater
|
||||
if advert.lat and advert.lon:
|
||||
print(f"Location: {advert.lat}, {advert.lon}")
|
||||
```
|
||||
|
||||
### Data Flow
|
||||
|
||||
1. `event_handlers.py` receives ADVERTISEMENT event
|
||||
2. `packet_processor.py` calls `parse_advertisement()` to extract data
|
||||
3. Contact is upserted with location data (`lat`, `lon`) and `device_role` as `type`
|
||||
4. Frontend MapView displays contacts with GPS coordinates
|
||||
|
||||
## ACK and Repeat Detection
|
||||
|
||||
The `acked` field is an integer count, not a boolean:
|
||||
|
||||
+29
-4
@@ -12,6 +12,7 @@ This document provides context for AI assistants and developers working on the R
|
||||
- **shadcn/ui components** - Sheet, Tabs, Button (in `components/ui/`)
|
||||
- **meshcore-hashtag-cracker** - WebGPU-accelerated channel key bruteforcing
|
||||
- **nosleep.js** - Prevents device sleep during cracking
|
||||
- **leaflet / react-leaflet** - Interactive map for node locations
|
||||
|
||||
## Directory Structure
|
||||
|
||||
@@ -41,9 +42,11 @@ frontend/
|
||||
│ │ ├── MessageInput.tsx # Text input with imperative handle
|
||||
│ │ ├── ContactAvatar.tsx # Contact profile image component
|
||||
│ │ ├── RawPacketList.tsx # Raw packet feed display
|
||||
│ │ ├── CrackerPanel.tsx # WebGPU channel key cracker
|
||||
│ │ ├── MapView.tsx # Leaflet map showing node locations
|
||||
│ │ ├── CrackerPanel.tsx # WebGPU channel key cracker (lazy-loads wordlist)
|
||||
│ │ ├── NewMessageModal.tsx
|
||||
│ │ └── ConfigModal.tsx # Radio config + app settings
|
||||
│ │ ├── ConfigModal.tsx # Radio config + app settings
|
||||
│ │ └── MaintenanceModal.tsx # Database maintenance (cleanup, dedup)
|
||||
│ └── test/
|
||||
│ ├── setup.ts # Test setup (jsdom, matchers)
|
||||
│ ├── messageParser.test.ts
|
||||
@@ -204,8 +207,8 @@ interface Message {
|
||||
}
|
||||
|
||||
interface Conversation {
|
||||
type: 'contact' | 'channel' | 'raw';
|
||||
id: string; // PublicKey for contacts, ChannelKey for channels
|
||||
type: 'contact' | 'channel' | 'raw' | 'map';
|
||||
id: string; // PublicKey for contacts, ChannelKey for channels, 'raw'/'map' for special views
|
||||
name: string;
|
||||
}
|
||||
|
||||
@@ -566,6 +569,7 @@ Deep linking to conversations via URL hash:
|
||||
- `#channel/RoomName` - Opens a channel (leading `#` stripped from name for cleaner URLs)
|
||||
- `#contact/ContactName` - Opens a DM
|
||||
- `#raw` - Opens the raw packet feed
|
||||
- `#map` - Opens the node map
|
||||
|
||||
```typescript
|
||||
// Parse hash on initial load
|
||||
@@ -604,6 +608,27 @@ const maxLengthRef = useRef(6);
|
||||
|
||||
Progress reporting shows rate in Mkeys/s or Gkeys/s depending on speed.
|
||||
|
||||
## MapView
|
||||
|
||||
The `MapView` component displays contacts with GPS coordinates on an interactive Leaflet map.
|
||||
|
||||
### Features
|
||||
|
||||
- **Location filtering**: Only shows contacts with lat/lon that were heard within the last 7 days
|
||||
- **Freshness coloring**: Markers colored by how recently the contact was heard:
|
||||
- Bright green (`#22c55e`) - less than 1 hour ago
|
||||
- Light green (`#4ade80`) - less than 1 day ago
|
||||
- Yellow-green (`#a3e635`) - less than 3 days ago
|
||||
- Gray (`#9ca3af`) - older (up to 7 days)
|
||||
- **Node/repeater distinction**: Regular nodes have black outlines, repeaters are larger with no outline
|
||||
- **Geolocation**: Tries browser geolocation first, falls back to fitting all markers in view
|
||||
- **Popups**: Click a marker to see contact name, last heard time, and coordinates
|
||||
|
||||
### Data Source
|
||||
|
||||
Contact location data (`lat`, `lon`) is extracted from advertisement packets in the backend (`decoder.py`).
|
||||
The `last_seen` timestamp determines marker freshness.
|
||||
|
||||
## Sidebar Features
|
||||
|
||||
- **Sort toggle**: Default is 'recent' (most recent message first), can toggle to alphabetical
|
||||
|
||||
Reference in New Issue
Block a user