({
event,
onResponse,
onWaitingDismiss
}: {
event: ElicitationRequestEvent;
onResponse: Props['onResponse'];
onWaitingDismiss: Props['onWaitingDismiss'];
})
| 982 | </Dialog>; |
| 983 | } |
| 984 | function ElicitationURLDialog({ |
| 985 | event, |
| 986 | onResponse, |
| 987 | onWaitingDismiss |
| 988 | }: { |
| 989 | event: ElicitationRequestEvent; |
| 990 | onResponse: Props['onResponse']; |
| 991 | onWaitingDismiss: Props['onWaitingDismiss']; |
| 992 | }): React.ReactNode { |
| 993 | const { |
| 994 | serverName, |
| 995 | signal, |
| 996 | waitingState |
| 997 | } = event; |
| 998 | const urlParams = event.params as ElicitRequestURLParams; |
| 999 | const { |
| 1000 | message, |
| 1001 | url |
| 1002 | } = urlParams; |
| 1003 | const [phase, setPhase] = useState<'prompt' | 'waiting'>('prompt'); |
| 1004 | const phaseRef = useRef<'prompt' | 'waiting'>('prompt'); |
| 1005 | const [focusedButton, setFocusedButton] = useState<'accept' | 'decline' | 'open' | 'action' | 'cancel'>('accept'); |
| 1006 | const showCancel = waitingState?.showCancel ?? false; |
| 1007 | useNotifyAfterTimeout('Claude Code needs your input', 'elicitation_url_dialog'); |
| 1008 | useRegisterOverlay('elicitation-url'); |
| 1009 | |
| 1010 | // Keep refs in sync for use in abort handler (avoids re-registering listener) |
| 1011 | phaseRef.current = phase; |
| 1012 | const onWaitingDismissRef = useRef(onWaitingDismiss); |
| 1013 | onWaitingDismissRef.current = onWaitingDismiss; |
| 1014 | useEffect(() => { |
| 1015 | const handleAbort = () => { |
| 1016 | if (phaseRef.current === 'waiting') { |
| 1017 | onWaitingDismissRef.current?.('cancel'); |
| 1018 | } else { |
| 1019 | onResponse('cancel'); |
| 1020 | } |
| 1021 | }; |
| 1022 | if (signal.aborted) { |
| 1023 | handleAbort(); |
| 1024 | return; |
| 1025 | } |
| 1026 | signal.addEventListener('abort', handleAbort); |
| 1027 | return () => signal.removeEventListener('abort', handleAbort); |
| 1028 | }, [signal, onResponse]); |
| 1029 | |
| 1030 | // Parse URL to highlight the domain |
| 1031 | let domain = ''; |
| 1032 | let urlBeforeDomain = ''; |
| 1033 | let urlAfterDomain = ''; |
| 1034 | try { |
| 1035 | const parsed = new URL(url); |
| 1036 | domain = parsed.hostname; |
| 1037 | const domainStart = url.indexOf(domain); |
| 1038 | urlBeforeDomain = url.slice(0, domainStart); |
| 1039 | urlAfterDomain = url.slice(domainStart + domain.length); |
| 1040 | } catch { |
| 1041 | domain = url; |
nothing calls this directly
no test coverage detected