* fix: dedupe cancel-turn clicks to stop "turn cancelled" cascade
The cancel button had no in-flight feedback, so impatient users clicked
it repeatedly while the agent was tearing down a slow turn (e.g. a
Claude Monitor tool). Each click reached the backend and emitted its
own "Turn cancelled by user" message, with the second-and-later calls
also lazily creating phantom turns to host those messages.
Fix on both sides: SubmitButton now tracks isCancelling locally and
disables itself with a spinner while the request is in flight; the
orchestrator deduplicates concurrent CancelAgent calls per session via
a sync.Map guard so duplicates that slip through return immediately.
* fix: address PR review feedback
- Test: replace sleep-based polling in cancel-dedupe test with channel
synchronization (cancelAgentEntered) per project convention.
- UI: switch the cancel re-entrancy guard from state to a ref so
isCancelling no longer thrashes the useCallback dep array.
---------
Co-authored-by: Kandev Agent <agent@kandev.dev>