An agent deciding on a sign-in could not tell its own from someone else's. Every local client's origin is http://localhost, and the server marks every one as new, so "first time" said nothing. The prompt now gives the redirect port the agent can match against the URL its own vibescrobble login printed. Remote clients render as before. Measured on 2026-10-14 with this branch's hook run directly against the live daemon (the plugin is not installed), for one vibescrobble login sign-in:
before: client: http://localhost (first time for this account)
after: client: unverified local app, redirect port 45769
The decision carries only clientOrigin, and didbot's canonical local client_id drops redirect ports, so the port can't come from the decision. No lexicon or socket field is added. When a tool call prints a local authorize URL, the hook parses the port from its client_id, sends the request_uri in the protocol's existing show ask, and labels the pending decision with the matching token. A decision it can't pair says "redirect port unknown". A refused one, which has nothing to approve, gives no port. The parser reads loopback hosts the way didbot's WHATWG url crate does (127.1, 0x7f.0.0.1, [::0.0.0.1], full-width digits, http:///localhost\, default port 80). It agreed with Node 24's WHATWG URL on all 44 spellings in the tests.
🤖 Generated with Claude Code