Port 8080 is listening. The process is kubectl, PID 4411, launched three days ago from a terminal you've since closed. That row is technically true and practically useless — because the interesting part isn't the binary, it's the other end. That socket might be a shell into production. This is about teaching the list to say so, and then about le forward — a port-forward that refuses to die quietly.
Tunnels wear costumes
A kubectl port-forward shows up in every process list as… kubectl. A Cloudflare tunnel shows up as cloudflared. Neither name answers the question you're actually asking, which is some flavor of: if I kill this, what breaks — and if I type into this port, where does it go?
The answer was sitting in plain sight the whole time. We already read every listener's command line to name Node scripts and Python servers, so the arguments of kubectl port-forward svc/payments 8080:80 --context prod were already in memory — we were just ignoring them. Now there's a proper tunnel kind in the scanner: those rows stop pretending to be ordinary processes and say what they are — a port-forward into svc/payments, local 8080 to remote 80, context prod. Cloudflare tunnels get the same treatment. The word prod on that row is doing more safety work than any confirmation dialog we could draw around the Stop button.
Both surfaces got it: the app's rows and detail view, and the CLI table — where the WHAT column now reads svc/payments 8080→80 (prod) instead of kubectl.
The part where port-forwards die
Once the list could see port-forwards, the second problem became impossible to ignore: kubectl port-forward is fragile by design. The pod restarts, the rollout replaces it, the connection idles out — and the forward dies. Silently. The process often keeps running, the port sometimes stays open, and your next curl hangs while you debug entirely the wrong layer. Every Kubernetes developer has a tab full of dead forwards and a reflex: up-arrow, enter, again.
le forward is that reflex, automated honestly:
le forward svc/payments 8080:80 --context prod
It runs the same kubectl port-forward you would have typed — the command is printed, nothing hidden — and then it supervises it. When the forward drops, it reconnects with backoff, and it tells you it did, with a timestamped line, because a reconnect you don't know about is a gap in your mental model of what's been up. Ctrl-C stops the supervisor and the forward both — no orphan kubectl left squatting the port.
The app grew the same muscle as a tool — Port forward, in the Ports & Processes section — with the running forward visible in the listener list like anything else, wearing its honest tunnel label.
What we didn't do
No kubeconfig parsing, no cluster API calls, no auth of any kind. Everything here comes from the process table you can already see — command lines and sockets. The scanner stays local-only: it never talks to your cluster, it just finally reads what your own machine was already saying. And when the arguments don't parse — someone's exotic wrapper script, a renamed binary — the row falls back to the plain process view instead of guessing. A tunnel label is a safety feature only while it's never wrong.
Where it ships: the CLI side is out now in le v0.1.16 — brew upgrade le or the install script. The app side arrives in 1.2.0.