fix(login): don't lose an approval to one dropped packet
The device flow polls for up to fifteen minutes against a network that only
has to hiccup once. It did: a single ConnectTimeoutError to the deployment
took the whole flow down with an uncaught rejection, several minutes into
waiting, while the operator was standing at a browser with a valid code. The
deployment was healthy the entire time.
A failed poll is not a failed approval, so transport errors are now data:
`post` returns them, the poll loop notes them and keeps going until the code
actually expires, and starting the flow retries three times. The only thing
that ends the wait is expiry or a real HTTP error.
Also adds `--write-env [path]`, because the alternative is a token on stdout
that has to be copied by hand or captured into a log file that then keeps it.
It rewrites IRIS_TOKEN in place at mode 600, leaving the rest of an existing
.env alone. Still opt-in: a credential silently dropped into a file is one
nobody remembers is there.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>