Skip to content

Commit baca292

Browse files
committed
Add comprehensive AI agent instructions to .github/copilot-instructions.md
1 parent a685135 commit baca292

1 file changed

Lines changed: 215 additions & 0 deletions

File tree

.github/copilot-instructions.md

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# MeshCore GOME WarDriver - AI Agent Instructions
2+
3+
> **Keeping This File Updated**: When you make architectural changes, add new workflows, or modify critical patterns, update this file. Ask the AI: *"Update .github/copilot-instructions.md to reflect the changes I just made"* - it will analyze the modifications and update relevant sections.
4+
5+
## Project Overview
6+
7+
Browser-based Progressive Web App for wardriving with MeshCore mesh network devices. Connects via Web Bluetooth to send GPS-tagged pings to a `#wardriving` channel, track repeater echoes, and post coverage data to the MeshMapper API for community mesh mapping.
8+
9+
**Tech Stack**: Vanilla JavaScript (ES6 modules), Web Bluetooth API, Geolocation API, Tailwind CSS v4
10+
11+
**Critical Files**:
12+
- `content/wardrive.js` (4500+ lines) - Main application logic
13+
- `content/mc/` - MeshCore BLE protocol library (Connection classes, Packet parsing, Buffer utilities)
14+
- `index.html` - Single-page UI with embedded Leaflet map
15+
- `docs/` - Comprehensive workflow documentation (CONNECTION_WORKFLOW.md, PING_WORKFLOW.md, etc.)
16+
17+
## Architecture & Data Flow
18+
19+
### 1. Connection Architecture
20+
Three-layer connection system:
21+
- **BLE Layer**: `WebBleConnection` (extends `Connection` base class) handles GATT connection, characteristic notifications
22+
- **Protocol Layer**: `Connection.js` (2200+ lines) implements MeshCore companion protocol - packet framing, encryption, channel management, device queries
23+
- **App Layer**: `wardrive.js` orchestrates connect/disconnect workflows with 10-step sequences (see `docs/CONNECTION_WORKFLOW.md`)
24+
25+
**Connect Sequence**: BLE GATT → Protocol Handshake → Device Info → Time Sync → Capacity Check (API slot acquisition) → Channel Setup → GPS Init → Connected
26+
27+
### 2. Ping Lifecycle & API Queue System
28+
Two independent data flows merge into a unified API batch queue:
29+
30+
**TX Flow** (Transmit):
31+
1. User sends ping → `sendPing()` validates GPS/geofence/distance
32+
2. Sends `@[MapperBot]<LAT LON>[ <power>]` to `#wardriving` channel via BLE
33+
3. Starts 6-second RX listening window for repeater echoes
34+
4. After window: posts to API queue with type "TX"
35+
5. Triggers 3-second flush timer for real-time map updates
36+
37+
**RX Flow** (Receive - Passive monitoring):
38+
1. Always-on `handleUnifiedRxLogEvent()` captures ALL incoming packets (no filtering)
39+
2. Validates path length > 0 (must route via repeater, not direct)
40+
3. Buffers RX events per repeater with GPS coordinates
41+
4. Flushes to API queue on 25m movement or 30s timeout, type "RX"
42+
43+
**API Queue** (`apiQueue.messages[]`):
44+
- Max 50 messages, auto-flush on size/30s timer/TX triggers
45+
- Batch POST to `yow.meshmapper.net/wardriving-api.php`
46+
- See `docs/FLOW_WARDRIVE_API_QUEUE_DIAGRAM.md` for visual flow
47+
48+
### 3. GPS & Geofencing
49+
- **GPS Watch**: Continuous `navigator.geolocation.watchPosition()` with high accuracy
50+
- **Freshness**: Manual pings use 60s max age, auto pings require fresh acquisition
51+
- **Ottawa Geofence**: 150km radius from Parliament Hill (45.4215, -75.6972) - hard boundary
52+
- **Min Distance Filter**: 25m between pings (prevents spam, separate from 25m RX batch trigger)
53+
54+
### 4. State Management
55+
Global `state` object tracks:
56+
- `connection`: Active BLE connection instance
57+
- `wardrivingChannel`: Channel object for ping sends
58+
- `txRxAutoRunning` / `autoTimerId` / `nextAutoPingTime`: Auto-ping state
59+
- `lastPingLat/Lon`: For distance validation
60+
- `cooldownEndTime`: 7-second cooldown after each ping
61+
- `sessionId`: UUID for correlating TX/RX events per wardrive session
62+
63+
**RX Batch Buffer**: `Map` keyed by repeater node ID → `{rxEvents: [], bufferedSince, lastFlushed, flushTimerId}`
64+
65+
## Critical Developer Workflows
66+
67+
### Build & Development
68+
```bash
69+
npm install # Install Tailwind CLI
70+
npm run build:css # One-time CSS build
71+
npm run watch:css # Watch mode for development
72+
```
73+
74+
**No bundler/compiler** - Open `index.html` directly in browser (Chrome/Chromium required for Web Bluetooth).
75+
76+
### Debug Logging System
77+
All debug output controlled by `DEBUG_ENABLED` flag (URL param `?debug=true` or hardcoded):
78+
```javascript
79+
debugLog("[TAG] message", ...args); // General info
80+
debugWarn("[TAG] message", ...args); // Warnings
81+
debugError("[TAG] message", ...args); // Errors (also adds to UI Error Log)
82+
```
83+
84+
**Required Tags** (see `docs/DEVELOPMENT_REQUIREMENTS.md`): `[BLE]`, `[GPS]`, `[PING]`, `[API QUEUE]`, `[RX BATCH]`, `[UNIFIED RX]`, `[UI]`, etc. NEVER log without a tag.
85+
86+
### Status Message System
87+
**Two separate status bars** (NEVER mix them):
88+
1. **Connection Status** (`setConnStatus(text, color)`) - ONLY "Connected", "Connecting", "Disconnected", "Disconnecting"
89+
2. **Dynamic Status** (`setDynamicStatus(text, color, immediate)`) - All operational messages, 500ms minimum visibility, blocks connection words
90+
91+
Use `STATUS_COLORS` constants: `idle`, `success`, `warning`, `error`, `info`
92+
93+
## Project-Specific Patterns
94+
95+
### 1. Countdown Timer Pattern
96+
Reusable countdown system for cooldowns, auto-ping intervals, RX listening windows:
97+
```javascript
98+
function createCountdownTimer(getEndTime, getStatusMessage) {
99+
// Returns timer state, updates UI every 500ms
100+
// Handles pause/resume for manual ping interrupts
101+
}
102+
```
103+
Used by `startAutoCountdown()`, `startRxListeningCountdown()`, cooldown logic.
104+
105+
### 2. Channel Hash & Decryption
106+
**Pre-computed at startup**:
107+
```javascript
108+
WARDRIVING_CHANNEL_KEY = await deriveChannelKey("#wardriving"); // PBKDF2 SHA-256
109+
WARDRIVING_CHANNEL_HASH = await computeChannelHash(key); // PSK channel identifier
110+
```
111+
Used for:
112+
- Repeater echo detection (match `channelHash` in received packets)
113+
- Message decryption (AES-ECB via aes-js library)
114+
115+
### 3. Wake Lock Management
116+
Auto-ping mode acquires Screen Wake Lock to keep GPS active:
117+
```javascript
118+
await acquireWakeLock(); // On auto-ping start
119+
await releaseWakeLock(); // On stop/disconnect
120+
```
121+
Handles visibility changes (release on hidden, reacquire on visible).
122+
123+
### 4. Capacity Check (API Slot Management)
124+
Before connecting, app must acquire a slot from MeshMapper backend:
125+
```javascript
126+
POST /capacitycheck.php { iatacode: "YOW", apikey: "...", apiver: "1.6.0" }
127+
Response: { valid: true, reason: null } or { valid: false, reason: "outofdate" }
128+
```
129+
Slot released on disconnect. Prevents backend overload.
130+
131+
## Documentation Requirements (CRITICAL)
132+
133+
**ALWAYS update docs when modifying workflows**:
134+
135+
1. **Connection Changes** → Update `docs/CONNECTION_WORKFLOW.md` (steps, states, error handling)
136+
2. **Ping/Auto-Ping Changes** → Update `docs/PING_WORKFLOW.md` (validation, lifecycle, UI impacts)
137+
3. **New Status Messages** → Add to `docs/STATUS_MESSAGES.md` (exact text, trigger, color)
138+
4. **Code Comments** → Use JSDoc (`@param`, `@returns`) for all functions
139+
5. **Architecture/Pattern Changes** → Update `.github/copilot-instructions.md` (this file) to reflect new patterns, data flows, or critical gotchas
140+
141+
### Status Message Documentation Format
142+
```markdown
143+
#### Message Name
144+
- **Message**: `"Exact text shown"`
145+
- **Color**: Green/Red/Yellow/Blue (success/error/warning/info)
146+
- **When**: Detailed trigger condition
147+
- **Source**: `content/wardrive.js:functionName()`
148+
```
149+
150+
## Integration Points & External APIs
151+
152+
### MeshMapper API (yow.meshmapper.net)
153+
- **Capacity Check**: `capacitycheck.php` - Slot acquisition before connect
154+
- **Wardrive Data**: `wardriving-api.php` - Batch POST TX/RX coverage blocks
155+
- Payload: `[{type:"TX"|"RX", lat, lon, who, power, heard, session_id, iatacode}]`
156+
- Auth: `apikey` in JSON body (NOT query string - see `docs/GEO_AUTH_DESIGN.md`)
157+
158+
### MeshCore Protocol (content/mc/)
159+
Key methods on `Connection` class:
160+
- `deviceQuery(protoVer)` - Protocol handshake
161+
- `getDeviceName()`, `getPublicKey()`, `getDeviceSettings()` - Device info
162+
- `sendTime()` - Time sync
163+
- `getChannels()`, `createChannel()`, `deleteChannel()` - Channel CRUD
164+
- `sendChannelMsg(channel, text)` - Send text message to channel
165+
166+
**Packet Structure**: Custom binary protocol with BufferReader/Writer utilities for serialization.
167+
168+
## Common Pitfalls & Gotchas
169+
170+
1. **Unified RX Handler accepts ALL packets** - No header filtering at entry point (removed in PR #130). Session log tracking filters headers internally.
171+
172+
2. **GPS freshness varies by context**: Manual pings tolerate 60s old GPS data, auto pings force fresh acquisition. Check `GPS_WATCH_MAX_AGE_MS` vs `GPS_FRESHNESS_BUFFER_MS`.
173+
174+
3. **Control locking during ping lifecycle** - `sendPing()` disables all controls until API post completes. Must call `unlockPingControls()` in ALL code paths (success/error).
175+
176+
4. **Auto-ping pause/resume** - Manual pings during auto mode pause countdown, resume after completion. Handle in `handleManualPingBlockedDuringAutoMode()`.
177+
178+
5. **Disconnect cleanup order matters**: Flush API queue → Release capacity → Delete channel → Close BLE → Clear timers/GPS/wake locks → Reset state. Out-of-order causes errors.
179+
180+
6. **Tailwind config paths**: Build scans `index.html` and `content/**/*.{js,html}`. Missing paths = missing styles.
181+
182+
7. **Status message visibility race** - Use `immediate=true` for countdown updates, `false` for first display (enforces 500ms minimum).
183+
184+
## Code Style Conventions
185+
186+
- **No frameworks/bundlers** - Vanilla JS with ES6 modules (`import`/`export`)
187+
- **Functional > Classes** - Most code uses functions + closures (except mc/ library uses classes)
188+
- **State centralization** - Global `state` object, explicit mutations
189+
- **Constants at top** - All config in SCREAMING_SNAKE_CASE (intervals, URLs, thresholds)
190+
- **Async/await** - Preferred over `.then()` chains
191+
- **Error handling** - Wrap BLE/API calls in try-catch, log with `debugError()`
192+
193+
## Key Files Reference
194+
195+
- `content/wardrive.js:connect()` (line ~2020) - 10-step connection workflow
196+
- `content/wardrive.js:sendPing()` (line ~2211) - Ping validation & send logic
197+
- `content/wardrive.js:handleUnifiedRxLogEvent()` (line ~3100) - RX packet handler
198+
- `content/wardrive.js:flushApiQueue()` (line ~3800) - Batch API POST
199+
- `content/mc/connection/connection.js` - MeshCore protocol implementation
200+
- `docs/FLOW_WARDRIVE_API_QUEUE_DIAGRAM.md` - Visual API queue architecture
201+
- `docs/COVERAGE_TYPES.md` - Coverage block definitions (BIDIR, TX, RX, DEAD, DROP)
202+
203+
## Testing Approach
204+
205+
**No automated tests** - Manual testing only:
206+
1. **Syntax check**: `node -c content/wardrive.js`
207+
2. **Desktop testing**: Primary development on Chrome/Chromium desktop
208+
- Use Chrome DevTools Sensors tab for GPS simulation
209+
- Mobile device emulation for responsive UI testing
210+
3. **Debug logging**: Enable via `?debug=true` to trace workflows
211+
4. **Production validation**: App primarily used on mobile (Android Chrome, iOS Bluefy)
212+
- Desktop testing sufficient for most development
213+
- Real device testing with MeshCore companion for final validation
214+
215+
**Mobile-first app, desktop-tested workflow** - Most development happens on desktop with DevTools, but remember users are on phones with real GPS and BLE constraints.

0 commit comments

Comments
 (0)