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