The !sawTerminalEvent guard must check signal.aborted first and throw the caller's reason (not a generic disconnect message) so that Agent.abort('user-interrupt') surfaces the custom reason in errorMessage instead of overwriting it.
read
skill://