| 1 | //! Codewhale's native composer footer rows, with representative caller data. |
| 2 | |
| 3 | use ratatui::{buffer::Buffer, layout::Rect}; |
| 4 | |
| 5 | use super::Entry; |
| 6 | use crate::{MetricKind, MetricSegment, MetricsLine, Paint, PostureBar, PostureFact, Role, Theme}; |
| 7 | |
| 8 | pub(crate) fn working_posture() -> PostureBar<'static> { |
| 9 | PostureBar::new("ask") |
| 10 | .permission_key("Shift+Tab to change") |
| 11 | .mode_ink("work", crate::TuiInk::ModeWork) |
| 12 | .mode_key("Tab") |
| 13 | .turn_clock("working 1m 15s", Role::Live) |
| 14 | .counts(vec![PostureFact::new("2 agents", Role::Live)]) |
| 15 | .session_clock("worked 41m 12s", Role::Live) |
| 16 | .hint("Esc to interrupt", Role::Hint) |
| 17 | .context_percent(61) |
| 18 | } |
| 19 | |
| 20 | pub(crate) fn working_metrics() -> MetricsLine<'static> { |
| 21 | MetricsLine::new(vec![ |
| 22 | MetricSegment::new(MetricKind::Model, "", "deepseek-v4").role(Role::Primary), |
| 23 | MetricSegment::new(MetricKind::Context, "ctx", "61%").role(Role::Primary), |
| 24 | MetricSegment::new(MetricKind::Cost, "", "$0.42"), |
| 25 | MetricSegment::new(MetricKind::Ttft, "ttft", "400ms"), |
| 26 | MetricSegment::new(MetricKind::Rate, "", "38 tok/s"), |
| 27 | MetricSegment::new(MetricKind::OutputTokens, "↓", "1.2K"), |
| 28 | ]) |
| 29 | .help_hint("/help") |
| 30 | } |
| 31 | |
| 32 | fn posture(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 33 | working_posture().paint(area, buf, theme); |
| 34 | } |
| 35 | |
| 36 | fn cap(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 37 | working_posture() |
| 38 | .context_percent(83) |
| 39 | .paint(area, buf, theme); |
| 40 | } |
| 41 | |
| 42 | fn compact_posture(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 43 | working_posture() |
| 44 | .compact(true) |
| 45 | .right("/rc connected", Role::Primary) |
| 46 | .paint(area, buf, theme); |
| 47 | } |
| 48 | |
| 49 | fn metrics(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 50 | working_metrics().paint(area, buf, theme); |
| 51 | } |
| 52 | |
| 53 | fn compact_metrics(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 54 | working_metrics().compact(true).paint(area, buf, theme); |
| 55 | } |
| 56 | |
| 57 | fn startup_metrics(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 58 | MetricsLine::new(vec![ |
| 59 | MetricSegment::new(MetricKind::Model, "", "model not connected").role(Role::Attention), |
| 60 | MetricSegment::new(MetricKind::Context, "ctx", "0%").role(Role::Primary), |
| 61 | ]) |
| 62 | .help_hint("/help") |
| 63 | .paint(area, buf, theme); |
| 64 | } |
| 65 | |
| 66 | pub(crate) fn entries() -> Vec<Entry> { |
| 67 | vec![ |
| 68 | Entry { |
| 69 | name: "posture-bar", |
| 70 | width: 112, |
| 71 | height: 1, |
| 72 | draw: posture, |
| 73 | }, |
| 74 | Entry { |
| 75 | name: "posture-narrow", |
| 76 | width: 40, |
| 77 | height: 1, |
| 78 | draw: posture, |
| 79 | }, |
| 80 | Entry { |
| 81 | name: "posture-context-cap", |
| 82 | width: 112, |
| 83 | height: 1, |
| 84 | draw: cap, |
| 85 | }, |
| 86 | Entry { |
| 87 | name: "posture-compact", |
| 88 | width: 96, |
| 89 | height: 1, |
| 90 | draw: compact_posture, |
| 91 | }, |
| 92 | Entry { |
| 93 | name: "metrics-line", |
| 94 | width: 112, |
| 95 | height: 1, |
| 96 | draw: metrics, |
| 97 | }, |
| 98 | Entry { |
| 99 | name: "metrics-narrow", |
| 100 | width: 32, |
| 101 | height: 1, |
| 102 | draw: metrics, |
| 103 | }, |
| 104 | Entry { |
| 105 | name: "metrics-compact", |
| 106 | width: 96, |
| 107 | height: 1, |
| 108 | draw: compact_metrics, |
| 109 | }, |
| 110 | Entry { |
| 111 | name: "metrics-startup", |
| 112 | width: 80, |
| 113 | height: 1, |
| 114 | draw: startup_metrics, |
| 115 | }, |
| 116 | ] |
| 117 | } |
| 118 |