现象
SKILL.md 明确写了 bsk evaluate 的退出码语义:
bsk evaluate <expression> — Run JS in agent tab; JS throw → stderr, exit 0
错误码表也确认了这一点:
0 — Success (including evaluate where JS threw but RPC succeeded)
即:JS 抛异常时,命令仍返回 exit 0。
实测证据(bsk CLI 0.1.10)
$ bsk evaluate "throw new Error('boom')" --session <id>
evaluate threw: Error: boom
at <anonymous>:1:7
exit=0 # JS 抛异常,退出码仍是 0
$ bsk evaluate "1+1" --session <id>
2
exit=0 # JS 正常,退出码也是 0
两者退出码完全相同,Agent 仅凭 exit code 无法区分成功与失败。
问题本质
bsk evaluate 的退出码反映的是「RPC 调用是否成功」(CLI ↔ daemon ↔ extension 的通信链路是否打通),而不是「JS 代码是否执行成功」。
- JS throw → RPC 层成功送达并返回 → exit 0
- 但 JS 本身失败了,异常只进了 stderr
Agent 通常只凭 exit code 判断成败。它看到 exit 0 就认定"JS 执行成功",实际上 JS 已抛异常、返回的是空/错误结果——产生静默失败(silent failure)。
影响
所有用 bsk evaluate 做数据提取、页面状态判断、DOM 操作的 Agent 都会踩:
- 数据提取:JS 抛异常拿到空结果,Agent 误当有效数据继续跑
- 状态判断:JS 判断失败但 exit 0,Agent 误以为"操作成功/条件满足"
- 静默错误难排查:没有明显的失败信号,只能在最终结果里发现不对
期望
提供一个机器可读的 JS 成功/失败信号,让 Agent 能可靠地区分"RPC 成功"和"JS 成功":
- 方案 A:
--json 输出增加 js_error 字段(是否抛异常 + 异常信息)
- 方案 B:
evaluate 结构化返回 { success: bool, value, error }
- 方案 C:新增
--strict 标志,JS throw 时 exit 非 0(opt-in,保持默认兼容)
兼容性考虑
默认行为(exit 0)可能已有调用方依赖,建议新增 opt-in 信号而非直接改退出码语义,避免破坏现有 Agent。
待官方对齐
- exit 0 的 RPC 语义是否有意为之、是否愿意为 Agent 正确性让步?
- 若改,倾向"退出码反映 JS 结果"还是"
--json 加 js_error 字段"?
现象
SKILL.md 明确写了
bsk evaluate的退出码语义:错误码表也确认了这一点:
即:JS 抛异常时,命令仍返回 exit 0。
实测证据(bsk CLI 0.1.10)
两者退出码完全相同,Agent 仅凭 exit code 无法区分成功与失败。
问题本质
bsk evaluate的退出码反映的是「RPC 调用是否成功」(CLI ↔ daemon ↔ extension 的通信链路是否打通),而不是「JS 代码是否执行成功」。Agent 通常只凭 exit code 判断成败。它看到 exit 0 就认定"JS 执行成功",实际上 JS 已抛异常、返回的是空/错误结果——产生静默失败(silent failure)。
影响
所有用
bsk evaluate做数据提取、页面状态判断、DOM 操作的 Agent 都会踩:期望
提供一个机器可读的 JS 成功/失败信号,让 Agent 能可靠地区分"RPC 成功"和"JS 成功":
--json输出增加js_error字段(是否抛异常 + 异常信息)evaluate结构化返回{ success: bool, value, error }--strict标志,JS throw 时 exit 非 0(opt-in,保持默认兼容)兼容性考虑
默认行为(exit 0)可能已有调用方依赖,建议新增 opt-in 信号而非直接改退出码语义,避免破坏现有 Agent。
待官方对齐
--json加js_error字段"?