Files
claude-hud/dist/render/lines/identity.js
2026-02-03 12:15:13 +11:00

120 lines
5.0 KiB
JavaScript

import { isLimitReached } from '../../types.js';
import { getContextPercent, getBufferedPercent, getModelName } from '../../stdin.js';
import { coloredBar, cyan, dim, red, yellow, getContextColor, quotaBar, RESET } from '../colors.js';
const DEBUG = process.env.DEBUG?.includes('claude-hud') || process.env.DEBUG === '*';
export function renderIdentityLine(ctx) {
const model = getModelName(ctx.stdin);
const rawPercent = getContextPercent(ctx.stdin);
const bufferedPercent = getBufferedPercent(ctx.stdin);
const autocompactMode = ctx.config?.display?.autocompactBuffer ?? 'enabled';
const percent = autocompactMode === 'disabled' ? rawPercent : bufferedPercent;
if (DEBUG && autocompactMode === 'disabled') {
console.error(`[claude-hud:context] autocompactBuffer=disabled, showing raw ${rawPercent}% (buffered would be ${bufferedPercent}%)`);
}
const bar = coloredBar(percent);
const display = ctx.config?.display;
const parts = [];
const planName = display?.showUsage !== false ? ctx.usageData?.planName : undefined;
const modelDisplay = planName ? `${model} | ${planName}` : model;
if (display?.showModel !== false && display?.showContextBar !== false) {
parts.push(`${cyan(`[${modelDisplay}]`)} ${bar} ${getContextColor(percent)}${percent}%${RESET}`);
}
else if (display?.showModel !== false) {
parts.push(`${cyan(`[${modelDisplay}]`)} ${getContextColor(percent)}${percent}%${RESET}`);
}
else if (display?.showContextBar !== false) {
parts.push(`${bar} ${getContextColor(percent)}${percent}%${RESET}`);
}
else {
parts.push(`${getContextColor(percent)}${percent}%${RESET}`);
}
// Inline usage bar (only when usageBarEnabled is true in expanded mode)
const usageBarEnabled = display?.usageBarEnabled ?? true;
if (usageBarEnabled && display?.showUsage !== false && ctx.usageData?.planName) {
const usagePart = renderInlineUsage(ctx);
if (usagePart) {
parts.push(usagePart);
}
}
if (display?.showDuration !== false && ctx.sessionDuration) {
parts.push(dim(`⏱️ ${ctx.sessionDuration}`));
}
let line = parts.join(' | ');
if (display?.showTokenBreakdown !== false && percent >= 85) {
const usage = ctx.stdin.context_window?.current_usage;
if (usage) {
const input = formatTokens(usage.input_tokens ?? 0);
const cache = formatTokens((usage.cache_creation_input_tokens ?? 0) + (usage.cache_read_input_tokens ?? 0));
line += dim(` (in: ${input}, cache: ${cache})`);
}
}
return line;
}
function formatTokens(n) {
if (n >= 1000000) {
return `${(n / 1000000).toFixed(1)}M`;
}
if (n >= 1000) {
return `${(n / 1000).toFixed(0)}k`;
}
return n.toString();
}
function renderInlineUsage(ctx) {
if (!ctx.usageData?.planName) {
return null;
}
if (ctx.usageData.apiUnavailable) {
return yellow(``);
}
if (isLimitReached(ctx.usageData)) {
const resetTime = ctx.usageData.fiveHour === 100
? formatResetTime(ctx.usageData.fiveHourResetAt)
: formatResetTime(ctx.usageData.sevenDayResetAt);
return red(`⚠ Limit${resetTime ? ` (${resetTime})` : ''}`);
}
const display = ctx.config?.display;
const threshold = display?.usageThreshold ?? 0;
const fiveHour = ctx.usageData.fiveHour;
const sevenDay = ctx.usageData.sevenDay;
const effectiveUsage = Math.max(fiveHour ?? 0, sevenDay ?? 0);
if (effectiveUsage < threshold) {
return null;
}
const fiveHourDisplay = formatUsagePercent(fiveHour);
const fiveHourReset = formatResetTime(ctx.usageData.fiveHourResetAt);
const fiveHourPart = fiveHourReset
? `${quotaBar(fiveHour ?? 0)} ${fiveHourDisplay} (${fiveHourReset} / 5h)`
: `${quotaBar(fiveHour ?? 0)} ${fiveHourDisplay}`;
const sevenDayThreshold = display?.sevenDayThreshold ?? 80;
if (sevenDay !== null && sevenDay >= sevenDayThreshold) {
const sevenDayDisplay = formatUsagePercent(sevenDay);
const sevenDayReset = formatResetTime(ctx.usageData.sevenDayResetAt);
const sevenDayPart = sevenDayReset
? `${quotaBar(sevenDay)} ${sevenDayDisplay} (${sevenDayReset} / 7d)`
: `${quotaBar(sevenDay)} ${sevenDayDisplay}`;
return `${fiveHourPart} | ${sevenDayPart}`;
}
return fiveHourPart;
}
function formatUsagePercent(percent) {
if (percent === null) {
return dim('--');
}
const color = getContextColor(percent);
return `${color}${percent}%${RESET}`;
}
function formatResetTime(resetAt) {
if (!resetAt)
return '';
const now = new Date();
const diffMs = resetAt.getTime() - now.getTime();
if (diffMs <= 0)
return '';
const diffMins = Math.ceil(diffMs / 60000);
if (diffMins < 60)
return `${diffMins}m`;
const hours = Math.floor(diffMins / 60);
const mins = diffMins % 60;
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
}
//# sourceMappingURL=identity.js.map