From ea1cdffb56d42d6d4a934731f7d4c988ccacbe71 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Mon, 10 Aug 2026 22:11:04 +0200 Subject: [PATCH] fix(serial): linkify bare emulated-subnet IPs, not only http:// URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The serial monitor turns printed device URLs into IoT-gateway links — but only when the sketch printed a full http:// URL. That matched the Arduino idiom and missed MicroPython's: `print("Open:", wlan.ifconfig()[0])` emits a bare "192.168.4.15", which rendered as plain text. The address is unreachable from the host by design (it only exists inside the emulated network), so exactly the users who just gained real WiFi were handed an IP with no way to open it. The scheme is now optional; a negative lookahead keeps longer dotted strings (192.168.4.15.99) from half-matching. ifconfig() tuples linkify every same-subnet address they contain — all of them route to the same gateway root, so the extra links are harmless. --- frontend/src/components/simulator/SerialMonitor.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/simulator/SerialMonitor.tsx b/frontend/src/components/simulator/SerialMonitor.tsx index 07ea11ef..103820c0 100644 --- a/frontend/src/components/simulator/SerialMonitor.tsx +++ b/frontend/src/components/simulator/SerialMonitor.tsx @@ -286,7 +286,13 @@ export const SerialMonitor: React.FC = () => { // ESP32 (QEMU slirp) hands out 192.168.4.x; the Pico W virtual // net hands out 10.13.37.x. Both reach their emulated server // through the same /api/gateway proxy, so linkify either subnet. - const ipRegex = /http:\/\/(?:192\.168\.4|10\.13\.37)\.(\d+)(\/[^\s]*)?/g; + // The http:// prefix is OPTIONAL: Arduino sketches tend to print + // full URLs, but MicroPython's idiom is the bare ifconfig()[0] + // ("Open: 192.168.4.15") — requiring the scheme left exactly + // those users with a dead-end IP that is unreachable outside + // the emulated network. The trailing dot-check keeps a longer + // address like 192.168.4.15.99 from half-matching. + const ipRegex = /(?:http:\/\/)?(?:192\.168\.4|10\.13\.37)\.(\d{1,3})(?!\d|\.\d)(\/[^\s]*)?/g; const matches = [...text.matchAll(ipRegex)]; if (matches.length > 0) {