Skip to content

Commit 192afc3

Browse files
feat(statusline): add visual burn rate options and enhance display logic
1 parent a32a322 commit 192afc3

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

src/commands/statusline.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Formatter } from 'picocolors/types';
12
import process from 'node:process';
23
import { Result } from '@praha/byethrow';
34
import getStdin from 'get-stdin';
@@ -26,6 +27,8 @@ function formatRemainingTime(remaining: number): string {
2627
return `${remainingMins}m left`;
2728
}
2829

30+
const visualBurnRateChoices = ['off', 'emoji', 'text', 'emoji-text'] as const;
31+
2932
export const statuslineCommand = define({
3033
name: 'statusline',
3134
description: 'Display compact status line for Claude Code hooks (Beta)',
@@ -34,6 +37,15 @@ export const statuslineCommand = define({
3437
...sharedArgs.offline,
3538
default: true, // Default to offline mode for faster performance
3639
},
40+
visualBurnRate: {
41+
type: 'enum',
42+
choices: visualBurnRateChoices,
43+
description: 'Controls the visualization of the burn rate status',
44+
default: 'off',
45+
short: 'vb',
46+
negatable: false,
47+
toKebab: true,
48+
},
3749
},
3850
async run(ctx) {
3951
// Set logger to silent for statusline output
@@ -140,17 +152,40 @@ export const statuslineCommand = define({
140152
const burnRate = calculateBurnRate(activeBlock);
141153
const burnRateInfo = burnRate != null
142154
? (() => {
155+
const renderEmojiStatus = ctx.values.visualBurnRate === 'emoji' || ctx.values.visualBurnRate === 'emoji-text';
156+
const renderTextStatus = ctx.values.visualBurnRate === 'text' || ctx.values.visualBurnRate === 'emoji-text';
143157
const costPerHour = burnRate.costPerHour;
144158
const costPerHourStr = `${formatCurrency(costPerHour)}/hr`;
145159

146-
// Apply color based on burn rate (tokens per minute non-cache)
147-
const coloredBurnRate = burnRate.tokensPerMinuteForIndicator < 2000
148-
? pc.green(costPerHourStr) // Normal
160+
type BurnStatus = 'normal' | 'moderate' | 'high';
161+
162+
const burnStatus: BurnStatus = burnRate.tokensPerMinuteForIndicator < 2000
163+
? 'normal'
149164
: burnRate.tokensPerMinuteForIndicator < 5000
150-
? pc.yellow(costPerHourStr) // Moderate
151-
: pc.red(costPerHourStr); // High
165+
? 'moderate'
166+
: 'high';
167+
168+
const burnStatusMappings: Record<BurnStatus, { emoji: string; textValue: string; coloredString: Formatter }> = {
169+
normal: { emoji: '🟢', textValue: 'Normal', coloredString: pc.green },
170+
moderate: { emoji: '⚠️', textValue: 'Moderate', coloredString: pc.yellow },
171+
high: { emoji: '🚨', textValue: 'High', coloredString: pc.red },
172+
};
173+
174+
const { emoji, textValue, coloredString } = burnStatusMappings[burnStatus];
175+
176+
const burnRateOutputSegments: string[] = [
177+
coloredString(costPerHourStr),
178+
];
179+
180+
if (renderEmojiStatus) {
181+
burnRateOutputSegments.push(emoji);
182+
}
183+
184+
if (renderTextStatus) {
185+
burnRateOutputSegments.push(coloredString(`(${textValue})`));
186+
}
152187

153-
return ` | 🔥 ${coloredBurnRate}`;
188+
return ` | 🔥 ${burnRateOutputSegments.join(' ')}`;
154189
})()
155190
: '';
156191

0 commit comments

Comments
 (0)