({
ideSelection,
mcpClients,
notifications,
isInOverageMode,
isTeamOrEnterprise,
apiKeyStatus,
debug,
verbose,
tokenUsage,
mainLoopModel,
shouldShowAutoUpdater,
autoUpdaterResult,
isAutoUpdating,
isShowingCompactMessage,
onAutoUpdaterResult,
onChangeIsUpdating
}: {
ideSelection: IDESelection | undefined;
mcpClients?: MCPServerConnection[];
notifications: {
current: Notification | null;
queue: Notification[];
};
isInOverageMode: boolean;
isTeamOrEnterprise: boolean;
apiKeyStatus: VerificationStatus;
debug: boolean;
verbose: boolean;
tokenUsage: number;
mainLoopModel: string;
shouldShowAutoUpdater: boolean;
autoUpdaterResult: AutoUpdaterResult | null;
isAutoUpdating: boolean;
isShowingCompactMessage: boolean;
onAutoUpdaterResult: (result: AutoUpdaterResult) => void;
onChangeIsUpdating: (isUpdating: boolean) => void;
})
| 222 | return s.notifications; |
| 223 | } |
| 224 | function NotificationContent({ |
| 225 | ideSelection, |
| 226 | mcpClients, |
| 227 | notifications, |
| 228 | isInOverageMode, |
| 229 | isTeamOrEnterprise, |
| 230 | apiKeyStatus, |
| 231 | debug, |
| 232 | verbose, |
| 233 | tokenUsage, |
| 234 | mainLoopModel, |
| 235 | shouldShowAutoUpdater, |
| 236 | autoUpdaterResult, |
| 237 | isAutoUpdating, |
| 238 | isShowingCompactMessage, |
| 239 | onAutoUpdaterResult, |
| 240 | onChangeIsUpdating |
| 241 | }: { |
| 242 | ideSelection: IDESelection | undefined; |
| 243 | mcpClients?: MCPServerConnection[]; |
| 244 | notifications: { |
| 245 | current: Notification | null; |
| 246 | queue: Notification[]; |
| 247 | }; |
| 248 | isInOverageMode: boolean; |
| 249 | isTeamOrEnterprise: boolean; |
| 250 | apiKeyStatus: VerificationStatus; |
| 251 | debug: boolean; |
| 252 | verbose: boolean; |
| 253 | tokenUsage: number; |
| 254 | mainLoopModel: string; |
| 255 | shouldShowAutoUpdater: boolean; |
| 256 | autoUpdaterResult: AutoUpdaterResult | null; |
| 257 | isAutoUpdating: boolean; |
| 258 | isShowingCompactMessage: boolean; |
| 259 | onAutoUpdaterResult: (result: AutoUpdaterResult) => void; |
| 260 | onChangeIsUpdating: (isUpdating: boolean) => void; |
| 261 | }): ReactNode { |
| 262 | // Poll apiKeyHelper inflight state to show slow-helper notice. |
| 263 | // Gated on configuration — most users never set apiKeyHelper, so the |
| 264 | // effect is a no-op for them (no interval allocated). |
| 265 | const [apiKeyHelperSlow, setApiKeyHelperSlow] = useState<string | null>(null); |
| 266 | useEffect(() => { |
| 267 | if (!hasConfiguredApiKeyHelper()) return; |
| 268 | const interval = setInterval((setSlow: React.Dispatch<React.SetStateAction<string | null>>) => { |
| 269 | const next = getCurrentApiKeyHelperSlowNoticeDuration(); |
| 270 | setSlow(prev => next === prev ? prev : next); |
| 271 | }, 1000, setApiKeyHelperSlow); |
| 272 | return () => clearInterval(interval); |
| 273 | }, []); |
| 274 | |
| 275 | // Voice state (VOICE_MODE builds only, runtime-gated by GrowthBook) |
| 276 | const voiceState = feature('VOICE_MODE') ? |
| 277 | // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant |
| 278 | useVoiceState(s => s.voiceState) : 'idle' as const; |
| 279 | // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant |
| 280 | const voiceEnabled = feature('VOICE_MODE') ? useVoiceEnabled() : false; |
| 281 | const voiceError = feature('VOICE_MODE') ? |
nothing calls this directly
no test coverage detected