on main help sign in
feat(ui): add hypercredit readout to small top header
commitce314b8e0d2ad6a8c0661ab2dbde6d8f2ecf65b1 authorChristian Rocha <christian@rocha.is> dateFri 1 May 2026, 12:13 (6 months ago) parentd5b5a9e
5 files changed+14−3
internal/ui/common/elements.go+3−3 internal/ui/model/header.go+8 internal/ui/model/ui.go+1 internal/ui/styles/quickstyle.go+1 internal/ui/styles/styles.go+1
internal/ui/common/elements.go+3−3
@@ -81,7 +81,7 @@ func ModelInfo(t *styles.Styles, modelName, providerName, reasoningInfo string,
8181 if providerName == hyper.DisplayName && hyperCredits != nil {
8282 hcInfo := t.ModelInfo.HypercreditIcon.Render(styles.HypercreditIcon)
8383 hcInfo += " "
84− hcInfo += t.ModelInfo.HypercreditText.Render(fmt.Sprintf("%s Hypercredits", formatCredits(*hyperCredits)))
84+ hcInfo += t.ModelInfo.HypercreditText.Render(fmt.Sprintf("%s Hypercredits", FormatCredits(*hyperCredits)))
8585 parts = append(parts, "", hcInfo)
8686 }
8787
@@ -124,8 +124,8 @@ func formatTokensAndCost(t *styles.Styles, tokens, contextWindow int64, cost flo
124124 return fmt.Sprintf("%s %s", formattedTokens, formattedCost)
125125}
126126
127−// formatCredits formats an integer with comma separators for thousands.
128−func formatCredits(n int) string {
127+// FormatCredits formats an integer with comma separators for thousands.
128+func FormatCredits(n int) string {
129129 s := strconv.FormatInt(int64(n), 10)
130130 if n < 1000 {
131131 return s
internal/ui/model/header.go+8
@@ -69,6 +69,7 @@ func (h *header) drawHeader(
6969 compact bool,
7070 detailsOpen bool,
7171 width int,
72+ hyperCredits *int,
7273) {
7374 t := h.com.Styles
7475 if width != h.width || compact != h.compact {
@@ -101,6 +102,7 @@ func (h *header) drawHeader(
101102 lspErrorCount,
102103 detailsOpen,
103104 availDetailWidth,
105+ hyperCredits,
104106 )
105107
106108 remainingWidth := width -
@@ -131,6 +133,7 @@ func renderHeaderDetails(
131133 lspErrorCount int,
132134 detailsOpen bool,
133135 availWidth int,
136+ hyperCredits *int,
134137) string {
135138 t := com.Styles
136139
@@ -148,6 +151,11 @@ func renderHeaderDetails(
148151 parts = append(parts, formattedPercentage)
149152 }
150153
154+ if com.IsHyper() && hyperCredits != nil {
155+ hc := t.Header.Hypercredit.Render(styles.HypercreditIcon) + " " + t.Header.Percentage.Render(common.FormatCredits(*hyperCredits))
156+ parts = append(parts, hc)
157+ }
158+
151159 const keystroke = "ctrl+d"
152160 if detailsOpen {
153161 parts = append(parts, t.Header.Keystroke.Render(keystroke)+t.Header.KeystrokeTip.Render(" close"))
internal/ui/model/ui.go+1
@@ -2109,6 +2109,7 @@ func (m *UI) drawHeader(scr uv.Screen, area uv.Rectangle) {
21092109 m.isCompact,
21102110 m.detailsOpen,
21112111 area.Dx(),
2112+ m.hyperCredits,
21122113 )
21132114}
21142115
internal/ui/styles/quickstyle.go+1
@@ -577,6 +577,7 @@ func quickStyle(o quickStyleOpts) Styles {
577577 s.Header.Charm = base.Foreground(o.secondary)
578578 s.Header.Diagonals = base.Foreground(o.primary)
579579 s.Header.Percentage = muted
580+ s.Header.Hypercredit = base.Foreground(charmtone.Dolly)
580581 s.Header.Keystroke = muted
581582 s.Header.KeystrokeTip = subtle
582583 s.Header.WorkingDir = muted
internal/ui/styles/styles.go+1
@@ -64,6 +64,7 @@ type Styles struct {
6464 Charm lipgloss.Style // Style for "Charm™" label
6565 Diagonals lipgloss.Style // Style for diagonal separators (╱)
6666 Percentage lipgloss.Style // Style for context percentage
67+ Hypercredit lipgloss.Style // Style for Hypercredit count (◆ N)
6768 Keystroke lipgloss.Style // Style for keystroke hints (e.g., "ctrl+d")
6869 KeystrokeTip lipgloss.Style // Style for keystroke action text (e.g., "open", "close")
6970 WorkingDir lipgloss.Style // Style for current working directory