feat(tui): priority-ordered footer hint dropping for narrow terminals - #107
Conversation
Rework `FooterWidget::status_line_spans` so the footer never wraps
mid-hint at any width. Hints now drop in priority order:
1. mode label (always visible; truncated only as a last resort)
2. model name (always visible alongside mode; truncated mid-word only
after status has already been dropped)
3. status label ("working", "draft", "refreshing context", ...) — drops
first when space is tight
Previously the model name would ellipsize the moment a long status
label crowded the line, even at 60–80 columns. The new tier system
keeps mode + model intact down to ~25 cols and only falls back to
mode-only on extreme narrow widths.
Includes snapshot-style tests at widths 40, 60, 80, 100, 120 covering
the full / drop-status / truncate-model / mode-only tiers.
Fixes #88
There was a problem hiding this comment.
Code Review
This pull request refactors the TUI footer's status line to implement a priority-ordered dropping mechanism, ensuring the footer remains on a single line across various widths. The logic prioritizes the mode label, followed by the model name, and finally the status label. A new helper method build_status_line_spans was introduced to consolidate span creation, and extensive unit tests were added to verify the truncation behavior at different column widths. One improvement was identified regarding an unnecessary heap allocation when rendering the mode label.
| return vec![Span::styled( | ||
| truncate_to_width(mode_label, max_width), | ||
| mode_label.to_string(), | ||
| Style::default().fg(self.props.mode_color), | ||
| )]; |
There was a problem hiding this comment.
mode_label is a &'static str. Since Span::styled can accept it directly to produce a Span<'static>, calling .to_string() here is an unnecessary heap allocation in the render loop.
| return vec![Span::styled( | |
| truncate_to_width(mode_label, max_width), | |
| mode_label.to_string(), | |
| Style::default().fg(self.props.mode_color), | |
| )]; | |
| return vec![Span::styled( | |
| mode_label, | |
| Style::default().fg(self.props.mode_color), | |
| )]; |
feat(tui): priority-ordered footer hint dropping for narrow terminals
Privileged release workflows no longer attach rust-cache, sccache, or npm caches to a workflow_dispatch checkout (CodeQL Hmbown#88-Hmbown#106). Catalog drift no longer prints raw bundled/upstream blobs (Hmbown#107).
All 19 open actions/cache-poisoning/poisonable-step alerts (#88-#106) sit in release.yml, release-candidate.yml and release-artifacts.yml: jobs interpolated the caller SHA into ref/caches and let setup-node's implicit npm cache key on run identity. Now caller source_sha is pinned against github.sha by a pin job (refusing any retarget), checkout and build identity use GITHUB_SHA through env indirection instead of template interpolation, rust-cache keys use stable prefix-key values, and setup-node's implicit package cache is off where it cannot be keyed safely. Also carries the CodeQL #107 fix from the same lane: catalog_models_dev.py prints remote limit values as numbers/null/redacted only and drops query and fragment material from source URLs before logging. Harvested from #5401 (workflow+script files; CHANGELOG edit intentionally excluded here and lands with the release branch; GHSA advisory text split to a later PR as advised). No-Issue: CodeQL alert remediation (alerts #88-#107); no single user-facing issue tracks these Signed-off-by: Hunter Bown <hunter@hmbown.com>
Summary
FooterWidget::status_line_spansto use priority-ordered hint dropping so the footer never wraps mid-hint at any terminal width.Fixes #88
Test plan
cargo fmt --all -- --checkcargo clippy -p deepseek-tui --all-targets --all-features --locked -- -D warningscargo test -p deepseek-tui --bin deepseek-tui --locked(1001 passed, 0 failed)