fix(stockbit): tell a polling agent when Stockbit refuses the sign-in

A refused cookie in idx's browser was only a stderr warning, which nobody
reads under idx-mcp: stockbit_status showed `waiting` until the timeout, and
the timeout message did not mention the refusal.

- runtime::on_warning sends a thread's warnings to a sink as well as
  stderr, until its guard drops.
- The background sign-in puts its warnings in `sign_in.warning`, cleared
  once it signs in.
- The errors that end a browser wait (timeout, window closed, browser
  exited) name a refusal it hit.

Claude-Session: https://claude.ai/code/session_01RqPPVeVDrnLoP7NUZmLRxY
This commit is contained in:
Rasyidan Akbar F. 2026-11-04 19:22:14 +07:00
commit 362d314118
8 changed files with 130 additions and 18 deletions

View file

@ -217,7 +217,10 @@ WIB as the fallback.
- `api/stockbit/signin.rs` is the one sign-in flow; `idx stockbit login` waits
on it in the foreground, and idx-mcp's `stockbit_login` runs it on a thread
(`start_background`) that `stockbit_status` reports on (`sign_in`: waiting,
signed_in or failed, with the error's code). A thread does not outlive
signed_in or failed, with the error's code). The thread's warnings go into
`sign_in.warning` through `runtime::on_warning`, since nobody reads
idx-mcp's stderr, and the error that ends a browser wait names a refusal
it hit. A thread does not outlive
`main`, so idx-mcp calls `signin::shutdown` when stdin closes or on SIGTERM
or Ctrl-C, which closes a waiting browser (SIGKILL cannot). `Method::Auto` uses the browser
unless the shell is over SSH or has no display, and falls back to the page