6589ff44aa
Three foreground-visible v0.8.8 regressions surfaced after the GitHub Release went up. v0.8.8 was taken back down (release deleted, tag deleted) so this lands cleanly on a re-tag. 1. Worked-chip claimed model work that never happened ===================================================== `footer_worked_chip` read `App::session_started_at.elapsed()`, so a TUI that had been open and idle for 4 minutes rendered "worked 4m" even though no turn had ever fired. The label literally says "worked" — it should track real model work, not idle uptime. Fix: - Add `App::cumulative_turn_duration: Duration`, init to zero. - Increment on `EngineEvent::TurnComplete` from the just-finished turn's elapsed time (the same value already captured for the desktop-notification path). - Drop the now-unused `session_started_at` field. - `FooterProps::from_app` reads `cumulative_turn_duration`. The 60s threshold inside `footer_worked_chip` stays — it now means "60s of real model work," not "60s since launch." New regression test pins the invariant: idle app with zero cumulative turn time → empty chip; 90s of real work → "worked 1m 30s." 2. RLM child-token cost wasn't reaching `session_cost` ======================================================= A user reported the dashboard showing $0.15 spent for a session that the DeepSeek website billed at $3+. Sub-agent token usage already feeds the parent's cost via `MailboxMessage::TokenUsage` (#166), but the `rlm` tool spawns its own DeepSeek calls under `child_model` and reports them only in display metadata (`input_tokens` / `output_tokens`) that nothing consumes for billing. A session that uses RLM heavily under-reports cost linearly with the child token count. Fix: define a contract — tools that spawn their own LLM calls populate `metadata.child_input_tokens` / `child_output_tokens` / `child_prompt_cache_hit_tokens` / `child_prompt_cache_miss_tokens` / `child_model`. `tool_routing::accrue_child_token_cost_if_any` runs after every `handle_tool_call_complete`, reads those fields, and routes the cost through `accrue_subagent_cost`. RLM's metadata block is updated to populate the contract. Generic on purpose — future tools that spawn LLM calls (batch summarizers, retrieval helpers) get accrued for free. 3. OSC 8 hyperlinks corrupting Windows console rendering ======================================================== A Windows user reported the model-name strip showing "eepseek-v4-flash" (leading `d` consumed) and three overlapping copies of the composer panel. Likely cause: legacy `cmd.exe` and pre-Win11 PowerShell consoles don't always honor the OSC 8 string terminator (`ESC \`) cleanly, and v0.8.8 emitted OSC 8 by default. Fix: default `osc8_links` to `false` on Windows targets only (`!cfg!(windows)`). Mac/Linux still default-on. Windows users on modern terminals (Windows Terminal, Alacritty, WezTerm) can opt back in via `[ui] osc8_links = true`. Doesn't address the rest of the rendering corruption — that needs a Windows machine to reproduce — but the OSC 8 escape was the most likely culprit and disabling it on Windows is a strict no-op for terminals that *don't* support it. Verified ======== - `cargo fmt --all -- --check` - `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings` - `cargo test --workspace --all-features --locked` - New regression test for worked-chip pins the bug.