qqq login --browser signs in with the authorization code and S256 PKCE on a
loopback redirect (RFC 8252): a one-shot listener on 127.0.0.1 takes the
callback, the state is checked, and the code is exchanged at the provider with
the verifier (no nonce, as UI-API-CLIENTS.md section 7 asks). --port,
--redirect-host and --no-open cover exact registered URIs and headless hosts.
A denied request, a forged state or a refused exchange exits 3 and saves
nothing; the new token is checked against the server before it is kept.
qqq logout --provider-logout revokes the refresh token (RFC 7009) and opens
the provider end-session URL with the ID token, which refreshes now keep. A
refresh the provider refuses becomes UNAUTHENTICATED (exit 3, sign in again).
qqq-dev-idp gains the authorize endpoint (Approve/Deny page or auto-approve,
loopback redirects and S256 only), the authorization_code grant, ID tokens,
revocation and end-session. The device flow was run end to end for the first
time against a sample on OAUTH2 (8078) and worked unchanged.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>