15525751ce
The water-spout strip in the footer used to be hard-gated by `!low_motion`, which meant the typewriter-streaming option silently killed the spout animation — even with `fancy_animations = true` the strip stayed plain whitespace. Users testing the typewriter pacing in v0.8.29 reported "where did the whale go," which is on us: we'd collapsed two concerns (streaming pacing vs footer animation) onto one flag. This commit makes the two flags orthogonal: - `low_motion` governs streaming pacing only (typewriter = one char per commit tick vs upstream cadence = drain everything queued). - `fancy_animations` governs whether the spout-strip is rendered at all. It also wires in a new idea that fell out naturally once the two were decoupled: instead of driving the wave animation off wall-clock milliseconds, drive it off a per-turn character-commit counter (`StreamingState::stream_commit_frame`). The wave then visually moves at the same cadence as the text: - Typewriter mode → wave drips at one frame per character. - Upstream mode → wave surges when V4-pro bursts a warm-cache turn. - Tool calls and planning pauses → no chars arrive, wave freezes. The textual `working...` pulse still ticks on wall-clock, so a heartbeat is always visible. - New turn (`StreamingState::reset`) → counter zeroes so each turn opens with a fresh wave shape. `stream_commit_frame` is a `u64` advanced inside `commit_text` and `finalize_block_text` by the character count of each committed slice, so multi-byte UTF-8 (e.g., CJK) advances the wave by one glyph per character rather than three frames per character — matching the visual weight of each glyph. Regression-guarded by five new tests in `crates/tui/src/tui/streaming/mod.rs`: - `stream_commit_frame_advances_by_character_count_on_commit` - `stream_commit_frame_counts_unicode_chars_not_bytes` - `stream_commit_frame_advances_on_finalize` - `stream_commit_frame_resets_on_reset` - `stream_commit_frame_freezes_when_no_text_arrives` Also folds in `cargo fmt` cleanup for two files where prior commits on this branch landed without re-formatting (`crates/tui/src/tui/ui.rs` around the new Esc-arm wrapper introduced for the `gg` double-tap, and the new `fireworks_custom_base_url_preserves_provider_model` test in `crates/config/src/lib.rs`). No behavior change from those edits. Settings doc comments in `crates/tui/src/settings.rs` updated to spell out the new orthogonal semantics so the next maintainer doesn't have to reverse-engineer it from `render_footer`. CHANGELOG entry added under a new `[Unreleased]` section.