diff --git a/apps/electron/src/main/kernelHost.test.ts b/apps/electron/src/main/kernelHost.test.ts index 0a5684e3..7cd1348f 100644 --- a/apps/electron/src/main/kernelHost.test.ts +++ b/apps/electron/src/main/kernelHost.test.ts @@ -511,6 +511,57 @@ describe('AgentKernelHost', () => { host.dispose(); }); + it('leaves the LongBridge action empty while the CLI is available', async () => { + const host = new AgentKernelHost(); + + const result = await host.getLongBridgeStatus(); + + expect(result.status).toBe('available'); + expect(result.action).toBeUndefined(); + host.dispose(); + }); + + it('maps a LongBridge timeout to a retry action, not an install prompt', async () => { + const host = new AgentKernelHost(); + const marketData = lastMarketData as unknown as { + getLongBridgeStatus: () => Promise>; + }; + marketData.getLongBridgeStatus = async () => ({ + installed: true, + authed: true, + available: false, + status: 'timeout', + error: { code: 'LONGBRIDGE_TIMEOUT', message: 'LongBridge CLI timed out.' }, + }); + + const result = await host.getLongBridgeStatus(); + + expect(typeof result.action).toBe('string'); + expect(result.action).toContain('timed out'); + expect(result.action).not.toContain('Install the LongBridge CLI'); + host.dispose(); + }); + + it('maps an unrecognised LongBridge failure to its own action', async () => { + const host = new AgentKernelHost(); + const marketData = lastMarketData as unknown as { + getLongBridgeStatus: () => Promise>; + }; + marketData.getLongBridgeStatus = async () => ({ + installed: true, + authed: false, + available: false, + status: 'unknown', + error: { code: 'LONGBRIDGE_UNKNOWN', message: 'Unexpected failure.' }, + }); + + const result = await host.getLongBridgeStatus(); + + expect(typeof result.action).toBe('string'); + expect(result.action).not.toContain('Install the LongBridge CLI'); + host.dispose(); + }); + it('wraps market data errors into IPC results', async () => { const host = new AgentKernelHost(); const { toIpcResult } = await import('./kernelHost.ts'); diff --git a/apps/electron/src/main/kernelHost.ts b/apps/electron/src/main/kernelHost.ts index 63bea455..8e6f2a70 100644 --- a/apps/electron/src/main/kernelHost.ts +++ b/apps/electron/src/main/kernelHost.ts @@ -2591,6 +2591,10 @@ function getLongBridgeStatusAction(status: string) { return 'Run longbridge auth login to authenticate the LongBridge CLI.'; case 'rate_limited': return 'LongBridge is rate-limited; market data requests are paused. Try again later.'; + case 'timeout': + return 'LongBridge CLI timed out; market data requests are paused. Check your network or proxy and retry.'; + case 'unknown': + return 'LongBridge CLI reported an unexpected error; run `longbridge --version` in a terminal to verify the install and retry.'; default: return undefined; } diff --git a/packages/ui/src/components/layout/AppShell.tsx b/packages/ui/src/components/layout/AppShell.tsx index 8177f9be..5fd41da4 100644 --- a/packages/ui/src/components/layout/AppShell.tsx +++ b/packages/ui/src/components/layout/AppShell.tsx @@ -70,7 +70,10 @@ const LongBridgeBanner: React.FC = () => { const message = error ?? status?.message ?? 'LongBridge CLI status is unavailable.'; const action = status?.action ?? 'Install LongBridge CLI and run longbridge auth login.'; - const title = status?.status === 'rate_limited' ? 'LongBridge paused: ' : 'LongBridge setup needed: '; + // `timeout` is a transient pause, not a setup problem: the CLI is installed + // and authenticated, the call just did not come back in time. + const paused = status?.status === 'rate_limited' || status?.status === 'timeout'; + const title = paused ? 'LongBridge paused: ' : 'LongBridge setup needed: '; return (