问题与复现
现象 :当 LongBridge CLI 调用超时 (或返回未归类的错误)时,应用顶部的 LongBridge 横幅把问题描述成「需要安装 / 需要登录」,并给出与事实矛盾的处置建议 Install LongBridge CLI and run longbridge auth login.——可 CLI 其实已经装好、也可能已经登录,只是这次调用没在超时时间内返回。
完整链路 :
packages/longbridge-tools/src/status.ts:4-10 定义 LongBridgeStatusValue 共 6 个取值:'available' | 'not_installed' | 'not_authed' | 'rate_limited' | 'timeout' | 'unknown'。executor.ts:43-44 把超时映射成 LONGBRIDGE_TIMEOUT,status.ts:33-35 再映射成 status: 'timeout';status.ts:36 把其余错误(含 LONGBRIDGE_PARSE_FAILURE / LONGBRIDGE_UNKNOWN)映射成 'unknown'。
apps/electron/src/main/kernelHost.ts:2586-2597(修复前)只处理其中 3 个,其余全部落到 default: return undefined:
function getLongBridgeStatusAction ( status : string ) {
switch ( status ) {
case 'not_installed' :
return 'Install the LongBridge CLI (longbridge --help) and authenticate with longbridge auth login.' ;
case 'not_authed' :
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.' ;
default :
return undefined ; // ← 'timeout' / 'unknown' 也落在这里
}
}
kernelHost.ts:645-647 只在 available 时短路,其余状态都会调用上面的映射,于是 timeout / unknown 拿到 action: undefined。
UI packages/ui/src/components/layout/AppShell.tsx:67-73(修复前)把 undefined 兜底成「去安装」,标题也只有两分支:
if ( ! error && ( ! status || status . available ) ) return null ; // 只有 available 不显示
const message = error ?? status ?. message ?? 'LongBridge CLI status is unavailable.' ;
const action = status ?. action ?? 'Install LongBridge CLI and run longbridge auth login.' ; // ← undefined 兜底成"去安装"
const title = status ?. status === 'rate_limited' ? 'LongBridge paused: ' : 'LongBridge setup needed: ' ;
具体反例 :
输入 { installed: true, authed: true, available: false, status: 'timeout', error: { code: 'LONGBRIDGE_TIMEOUT', message: 'LongBridge CLI timed out.' } }
输出项
实际(修复前)
预期
action
undefined → UI 兜底显示 Install LongBridge CLI and run longbridge auth login.
提示超时 / 重试,而不是让人去装 CLI
横幅标题前缀
LongBridge setup needed:
LongBridge paused: (超时是暂时不可用,不是配置问题)
status: 'unknown' 时 action 同样为 undefined,UI 同样兜底成安装引导。
预期与修复方向
getLongBridgeStatusAction() 补齐 'timeout' 与 'unknown' 分支:让 6 个取值中除 'available'(由调用方短路、本就不需要动作)之外都有明确处置建议。
UI 标题的「paused」判定并入 'timeout'——超时与限流同属「暂时不可用」;'unknown' 保留 setup needed(原因未知,确实可能是环境问题)。
复现证据
环境:Windows 10、Bun 1.4.2(744846f84);基线 main 3a17eca6(2026-10-03T16:16:35Z)
聚焦测试 cd apps/electron && bun test src/main/kernelHost.test.ts(新增 3 个用例):
修复前 → 12 pass / 2 fail (两条新用例报 Expected: "string" / Received: "undefined")
修复后 → 14 pass / 0 fail
类型检查 bun run typecheck → @finagent/core / i18n / shared / ui / electron 全部 exit 0
全量 cd apps/electron && bun test → 32 pass / 1 fail 。唯一失败是 research-prompts.test.ts 的 synthesis prompt embeds SECURITY RULES before the data bundle,与本改动无关且属既有问题 :它单独运行是 4 pass / 0 fail,把本 PR 的 3 个文件还原成 main 版本后全量仍为 29 pass / 1 fail (同一条失败),且 research-prompts.ts / research-prompts.test.ts 与上游 main 逐字节一致——是既有的跨文件测试隔离问题。
未运行的测试:test:e2e / test:e2e:visible / test:package-smoke(Windows 上跑不起完整 e2e)。
说明:上游 .github/workflows/pr.yml 当前为 disabled_manually,新 PR 不会产生 check run;以上均为等价本地命令 结果。
查重与冲突
apps/electron/src/main/kernelHost.ts:84 个 open PR 中 11 个改动它。本 PR 的 hunk 为 @@ -2591,6 +2591,10 @@(插入在 default: 之前);最近的他人/自开 hunk 是 [Issue #34] Add conversation lineage foundation and operations #53 @@ -2610,6 +2637,34 @@、feat: close research platform issues 36-38 #56 @@ -2543,6 +2685,9 @@ 与 @@ -2654,6 +2799,98 @@、fix(automation): 校验规则保存的 IPC 输入 #276 @@ -2684,6 +2681,69 @@、fix(diagnostics): 诊断包恒报券商「已连接、1 个账户」,与是否登录无关 #246 @@ -2461,6 +2467,28 @@ ⇒ 均不相交 。
apps/electron/src/main/kernelHost.test.ts:8 个 PR 改动它,其中 fix(automation): 每日简报的组合敞口标签不再混用原币与本币 #277 / fix(eval): 可观测性链路把用户取消的运行记成 cancelled,不再记成任务失败 #255 / fix: resolve issue #96 #97 都在文件尾部 @@ -521,4 +… 追加用例;本 PR 新增用例位于 @@ -511,6 +511,57 @@(插在 wraps market data errors 用例之前),与这三者的插入点不相交 ;fix(automation): 校验规则保存的 IPC 输入 #276 / fix(portfolio-import): 草稿行全部带 issue 时仍静默创建空组合 #244 的 @@ -436,6 +436,41 @@ 在更上方,同样不相交。
packages/ui/src/components/layout/AppShell.tsx:零冲突 。
范围
3 个文件:
apps/electron/src/main/kernelHost.ts——新增 'timeout' / 'unknown' 两个 action 分支;
apps/electron/src/main/kernelHost.test.ts——新增 3 个用例(available 无动作、timeout 走重试而非安装、unknown 有自己的动作);
packages/ui/src/components/layout/AppShell.tsx——标题 paused 判定并入 timeout(该组件无单测基建,改动是单行条件扩展)。
不修改已支持状态的既有文案,不改动 IPC 契约与状态码。
问题与复现
现象:当 LongBridge CLI 调用超时(或返回未归类的错误)时,应用顶部的 LongBridge 横幅把问题描述成「需要安装 / 需要登录」,并给出与事实矛盾的处置建议
Install LongBridge CLI and run longbridge auth login.——可 CLI 其实已经装好、也可能已经登录,只是这次调用没在超时时间内返回。完整链路:
packages/longbridge-tools/src/status.ts:4-10定义LongBridgeStatusValue共 6 个取值:'available' | 'not_installed' | 'not_authed' | 'rate_limited' | 'timeout' | 'unknown'。executor.ts:43-44把超时映射成LONGBRIDGE_TIMEOUT,status.ts:33-35再映射成status: 'timeout';status.ts:36把其余错误(含LONGBRIDGE_PARSE_FAILURE/LONGBRIDGE_UNKNOWN)映射成'unknown'。apps/electron/src/main/kernelHost.ts:2586-2597(修复前)只处理其中 3 个,其余全部落到default: return undefined:kernelHost.ts:645-647只在available时短路,其余状态都会调用上面的映射,于是timeout/unknown拿到action: undefined。packages/ui/src/components/layout/AppShell.tsx:67-73(修复前)把undefined兜底成「去安装」,标题也只有两分支:具体反例:
输入
{ installed: true, authed: true, available: false, status: 'timeout', error: { code: 'LONGBRIDGE_TIMEOUT', message: 'LongBridge CLI timed out.' } }actionundefined→ UI 兜底显示Install LongBridge CLI and run longbridge auth login.LongBridge setup needed:LongBridge paused:(超时是暂时不可用,不是配置问题)status: 'unknown'时action同样为undefined,UI 同样兜底成安装引导。预期与修复方向
getLongBridgeStatusAction()补齐'timeout'与'unknown'分支:让 6 个取值中除'available'(由调用方短路、本就不需要动作)之外都有明确处置建议。'timeout'——超时与限流同属「暂时不可用」;'unknown'保留setup needed(原因未知,确实可能是环境问题)。复现证据
744846f84);基线 main3a17eca6(2026-10-03T16:16:35Z)cd apps/electron && bun test src/main/kernelHost.test.ts(新增 3 个用例):Expected: "string" / Received: "undefined")bun run typecheck→@finagent/core/i18n/shared/ui/electron全部 exit 0cd apps/electron && bun test→ 32 pass / 1 fail。唯一失败是research-prompts.test.ts的synthesis prompt embeds SECURITY RULES before the data bundle,与本改动无关且属既有问题:它单独运行是4 pass / 0 fail,把本 PR 的 3 个文件还原成 main 版本后全量仍为 29 pass / 1 fail(同一条失败),且research-prompts.ts/research-prompts.test.ts与上游 main 逐字节一致——是既有的跨文件测试隔离问题。test:e2e/test:e2e:visible/test:package-smoke(Windows 上跑不起完整 e2e)。.github/workflows/pr.yml当前为disabled_manually,新 PR 不会产生 check run;以上均为等价本地命令结果。查重与冲突
apps/electron/src/main/kernelHost.ts:84 个 open PR 中 11 个改动它。本 PR 的 hunk 为@@ -2591,6 +2591,10 @@(插入在default:之前);最近的他人/自开 hunk 是 [Issue #34] Add conversation lineage foundation and operations #53@@ -2610,6 +2637,34 @@、feat: close research platform issues 36-38 #56@@ -2543,6 +2685,9 @@与@@ -2654,6 +2799,98 @@、fix(automation): 校验规则保存的 IPC 输入 #276@@ -2684,6 +2681,69 @@、fix(diagnostics): 诊断包恒报券商「已连接、1 个账户」,与是否登录无关 #246@@ -2461,6 +2467,28 @@⇒ 均不相交。apps/electron/src/main/kernelHost.test.ts:8 个 PR 改动它,其中 fix(automation): 每日简报的组合敞口标签不再混用原币与本币 #277 / fix(eval): 可观测性链路把用户取消的运行记成 cancelled,不再记成任务失败 #255 / fix: resolve issue #96 #97 都在文件尾部@@ -521,4 +…追加用例;本 PR 新增用例位于@@ -511,6 +511,57 @@(插在wraps market data errors用例之前),与这三者的插入点不相交;fix(automation): 校验规则保存的 IPC 输入 #276 / fix(portfolio-import): 草稿行全部带 issue 时仍静默创建空组合 #244 的@@ -436,6 +436,41 @@在更上方,同样不相交。packages/ui/src/components/layout/AppShell.tsx:零冲突。范围
apps/electron/src/main/kernelHost.ts——新增'timeout'/'unknown'两个 action 分支;apps/electron/src/main/kernelHost.test.ts——新增 3 个用例(available 无动作、timeout 走重试而非安装、unknown 有自己的动作);packages/ui/src/components/layout/AppShell.tsx——标题 paused 判定并入timeout(该组件无单测基建,改动是单行条件扩展)。