What it is
Anonymous chat that works anywhere — FastAPI + WebSocket behind an SSH reverse tunnel, so friends on any network join via a short da.gd link. Shares any file up to 50MB and shows the host each device's type, brand, OS and browser. When the host closes the tab, the room blanks instantly for everyone.
Version history
Straight from the project’s own card data — what each version added.
LAN text chat.
Internet tunnel + short links.
File sharing + device detection.
Instant blank on host-leave.
What broke, and what I’d change
Not written yet. This is the part only I can write — what actually went wrong, and what I’d do differently. It lives in builds/reflections/wifi-chat.md (see _TEMPLATE.md); as soon as that file has words in it, this section fills in on the next build.
Everything else on this page — the spec, the version history, the file counts — is generated from the project’s own build notes and files, so nothing here is guesswork.
Build spec
The project’s own build notes, rendered. Open the raw .md ↗
Show the spec
WiFi Chat
Category: Software & Apps · Status: Done
Anonymous chat that works anywhere — FastAPI + WebSocket behind an SSH reverse tunnel, so friends on any network join via a short da.gd link. Shares any file up to 50MB and shows the host each device's type, brand, OS and browser.
Stack / Tools: FastAPI, WebSocket, localhost.run, da.gd, python-multipart
Build path:
- V1 — LAN text chat.
- V2 — Internet tunnel + short links.
- V3 — File sharing + device detection.
- V4 — Instant blank on host-leave.
Location: ~/Desktop/wifi-chat/
Anonymous chat where Isaac is always the host. Anyone anywhere joins through a short link — no same-WiFi requirement (the school WiFi blocks device-to-device, so the launcher spins up an SSH reverse tunnel through localhost.run and shortens the .lhr.life URL with da.gd using unambiguous characters only).
How it works
launcher.pystarts uvicorn, opens the tunnel, fetches a short URL, pops a dialog, opens the browser.server/main.py— FastAPI app:/health,/link,/upload, WebSocket/ws. Host claims with a secrethost_tokenfrom the URL; host sees the 👥 admin panel.server/chat_manager.py—ChatUserdataclass +user-agentslibrary detects device type/brand/OS/browser (iPhone, Android Phone, Mac, Windows…).client/index.html— single-file HTML5 client, no build step.
Key decisions
- Host detection via secret URL token (not IP) — the host opens the LAN link, so IP-matching broke.
.commandlauncher (not AppleScript.app) — the.appsilently failed to open Terminal.- da.gd is the only shortener that accepts
.lhr.life; custom unambiguous codes avoid 0/1/I/l/O confusion. - File sharing:
UploadFilePOST to/upload, then afile_shareWebSocket broadcast. MIME field is namedmime(nottype) becausetypecollides with the message-type field. - Host-leave: grace period 0 → instant
chat_endedbroadcast → client hides the whole app and shows a blank white screen.
Pitfalls
python-multipartmust be installed or/uploadthrowsRuntimeError: Form data requires "python-multipart".- File MIME must NOT reuse the
typekey in the WS payload. - Tunnel dies when the Mac sleeps; the launcher re-runs are cheap.