401a99dce7
Bun's WinHTTP backend can ignore AbortSignal once a TCP/TLS connection stalls (oven-sh/bun#15275, oven-sh/bun#18536), so Esc never reached the in-flight `web_search` fetch on Windows and the session froze until Ctrl+C. Only kimi shipped any timeout at all (server-side); every other provider passed `signal` to `fetch` with no client-side bound. Introduced `withHardTimeout(signal, ms=60_000)` in providers/utils and wired it into every web-search provider's outbound fetch — anthropic, brave, codex, exa, gemini, jina, kagi, kimi, parallel, perplexity (api-key and oauth), searxng, synthetic, tavily, z.ai. 60s tolerates legitimate slow LLM-mediated responses while still guaranteeing the request settles within a minute when Bun's abort fails to propagate. Independently, `executeSearch`'s provider-fallback loop swallowed every `AbortError` as a regular provider error and returned "All web search providers failed", masking cancellation on every platform. The catch block now calls `throwIfAborted(signal)` first so a caller-initiated cancel propagates as `ToolAbortError`. Fixes #1221