diff --git a/docs/superpowers/plans/2026-08-04-auto-detect-port-fix.md b/docs/superpowers/plans/2026-08-04-auto-detect-port-fix.md new file mode 100644 index 0000000..dfa14fa --- /dev/null +++ b/docs/superpowers/plans/2026-08-04-auto-detect-port-fix.md @@ -0,0 +1,181 @@ +# Auto-detect Upload Port Fix Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Fix auto-detect upload port failure when active log output interferes with ID? response detection. + +**Architecture:** Two-part fix — script-side filtering continues reading until ID match, firmware-side serial mute pauses all output during ID? response. + +**Tech Stack:** Python 3 + pyserial (script), ESP32-S3 + Arduino + ESP-IDF logging (firmware) + +--- + +## File Structure + +| File | Action | Purpose | +|------|--------|---------| +| `tools/pio_upload_port.py` | Modify | Filter ID responses in query_id() | +| `src/main.cpp` | Modify | Add serial mute for server | +| `src/client.cpp` | Modify | Add serial mute for client | + +--- + +### Task 1: Script-side ID filtering + +**Files:** +- Modify: `tools/pio_upload_port.py:46-61` + +- [ ] **Step 1: Update query_id() to filter for ID response** + +Replace lines 46-61 in `tools/pio_upload_port.py`: + +```python +def query_id(port, timeout=5): + try: + ser = serial.Serial(port, 115200, timeout=0.5) + time.sleep(0.1) + ser.reset_input_buffer() + ser.write(b"ID?\n") + deadline = time.time() + timeout + while time.time() < deadline: + line = ser.readline().decode("utf-8", errors="ignore").strip() + if "SylDa_Server" in line or "SylDa_Client" in line: + ser.close() + return line + ser.close() + except (serial.SerialException, OSError): + pass + return None +``` + +- [ ] **Step 2: Commit** + +```bash +git add tools/pio_upload_port.py +git commit -m "fix(script): filter ID response in query_id()" +``` + +--- + +### Task 2: Server firmware serial mute + +**Files:** +- Modify: `src/main.cpp` + +- [ ] **Step 1: Add serialMuted flag and mute helper** + +After line 17 (`static const char *TAG = "server";`), add: + +```cpp +static bool serialMuted = false; + +static void muteSerial() { + serialMuted = true; + esp_log_level_set("*", ESP_LOG_NONE); +} + +static void unmuteSerial() { + serialMuted = false; + esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL); +} +``` + +- [ ] **Step 2: Update ID? handler to use mute** + +Replace lines 591-592: + +```cpp + } else if (serialBuf == "ID?") { + Serial.flush(); + muteSerial(); + Serial.println("SylDa_Server"); + delay(50); + unmuteSerial(); +``` + +- [ ] **Step 3: Commit** + +```bash +git add src/main.cpp +git commit -m "fix(server): add serial mute during ID? response" +``` + +--- + +### Task 3: Client firmware serial mute + +**Files:** +- Modify: `src/client.cpp` + +- [ ] **Step 1: Add serialMuted flag and mute helper** + +After line 15 (`static const char *TAG = "client";`), add: + +```cpp +static bool serialMuted = false; + +static void muteSerial() { + serialMuted = true; + esp_log_level_set("*", ESP_LOG_NONE); +} + +static void unmuteSerial() { + serialMuted = false; + esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL); +} +``` + +- [ ] **Step 2: Update ID? handler to use mute** + +Replace lines 425-426: + +```cpp + } else if (serialBuf == "ID?") { + Serial.flush(); + muteSerial(); + Serial.println("SylDa_Client"); + delay(50); + unmuteSerial(); +``` + +- [ ] **Step 3: Commit** + +```bash +git add src/client.cpp +git commit -m "fix(client): add serial mute during ID? response" +``` + +--- + +### Task 4: Build and verify + +- [ ] **Step 1: Build both environments** + +```bash +pio run -e s3lite-server +pio run -e s3lite-client +``` + +Expected: Both compile without errors. + +- [ ] **Step 2: Verify firmware version bump** + +Check `version.txt` exists with correct format. + +- [ ] **Step 3: Push branch** + +```bash +git push -u origin fix/issue-16-auto-detect-port +``` + +--- + +## Testing Checklist + +After implementation, test with actual hardware: + +1. Connect both server and client via USB +2. Run `pio run -e s3lite-client -t upload` — should auto-detect client +3. Run `pio run -e s3lite-server -t upload` — should auto-detect server +4. Verify log output resumes after upload completes +5. Test during active ECDH handshake (worst case)