9079276ec8b35f118a1aa69bda254504aee9083e
P1b's pure half (docs/RUST.md). Three pieces, all testable with no widget in sight: - `event_model::Event::ToolEnd` gains `is_error`, read from the CLI's own `tool_result` field by both the live translator and the import replay (`import::tool_result_is_error`, one reader so the two cannot disagree about the same conversation). Without it a result is all a card has, and a broken call draws exactly as confidently as one that worked -- the missing state, not a wrong one. `#[serde(default)]`, so an older transcript reads back as "not reported to have failed". - `client_core::transcript_fold::ToolState`: Running, Deciding, Succeeded, Failed, NoResult. The pair it exists for is the last two against Succeeded-with-empty-output -- a call that printed nothing and a call whose result never arrived leave the same empty string, and only the session's status separates "still going" from "nobody found out". - `client_core::tool_summary::parse_tool_input` and `client_core::durations`: `ToolInput.kt`'s subject/description/timeout split and `Durations.kt`'s span formatting, ported with their tests. The echo driver's three-call run now has a failing middle call, so the failed appearance is reachable from `ui-sandbox.sh` at all. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Languages
Rust
53%
Kotlin
44.4%
Shell
2.6%