claude-monitor
Version:
Real-time terminal monitoring tool for Claude AI token usage
113 lines • 3.99 kB
JavaScript
import { getSessionBillableTokens } from '../types/session-tokens.js';
export function calculateSessionMetrics(session, tokenLimit, currentTime = new Date()) {
const tokensUsed = getSessionBillableTokens(session);
const tokensRemaining = Math.max(0, tokenLimit - tokensUsed);
const usagePercentage = Math.round((tokensUsed / tokenLimit) * 100);
const sessionStartTime = session.startTime;
const sessionEndTime = session.endTime;
const elapsedMs = currentTime.getTime() - sessionStartTime.getTime();
const totalSessionMs = sessionEndTime.getTime() - sessionStartTime.getTime();
const remainingMs = Math.max(0, sessionEndTime.getTime() - currentTime.getTime());
const elapsedMinutes = elapsedMs / (1000 * 60);
const totalSessionMinutes = totalSessionMs / (1000 * 60);
const remainingMinutes = remainingMs / (1000 * 60);
const timePercentage = Math.round((elapsedMinutes / totalSessionMinutes) * 100);
const resetTime = sessionEndTime;
const minutesUntilReset = remainingMinutes;
let predictedEndTime = null;
let willExceedLimit = false;
let minutesUntilLimit = null;
if (session.burnRate && session.burnRate.tokensPerMinute > 0) {
const burnRate = session.burnRate.tokensPerMinute;
if (tokensRemaining > 0) {
minutesUntilLimit = tokensRemaining / burnRate;
predictedEndTime = new Date(currentTime.getTime() + minutesUntilLimit * 60 * 1000);
willExceedLimit = minutesUntilLimit < remainingMinutes;
}
else {
minutesUntilLimit = 0;
predictedEndTime = currentTime;
willExceedLimit = true;
}
}
return {
tokensUsed,
tokensRemaining,
usagePercentage,
sessionStartTime,
sessionEndTime,
currentTime,
elapsedMinutes,
totalSessionMinutes,
remainingMinutes,
timePercentage,
predictedEndTime,
willExceedLimit,
minutesUntilLimit,
resetTime,
minutesUntilReset,
};
}
export function formatTimeUntil(minutes) {
if (minutes <= 0)
return '0m';
const hours = Math.floor(minutes / 60);
const mins = Math.round(minutes % 60);
if (hours === 0) {
return `${mins}m`;
}
else if (mins === 0) {
return `${hours}h`;
}
else {
return `${hours}h ${mins}m`;
}
}
export function formatPredictedTime(predictedTime, timeFormat) {
if (!predictedTime)
return 'Never';
const hours = predictedTime.getHours();
const minutes = predictedTime.getMinutes();
const minutesStr = minutes.toString().padStart(2, '0');
if (timeFormat === '12') {
const period = hours >= 12 ? 'PM' : 'AM';
const displayHours = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
return `${displayHours}:${minutesStr} ${period}`;
}
else {
return `${hours.toString().padStart(2, '0')}:${minutesStr}`;
}
}
export function getStatusEmoji(percentage) {
if (percentage >= 90)
return '🔴';
if (percentage >= 70)
return '🟡';
return '🟢';
}
export function getBurnRateStatus(burnRate, remainingTokens, remainingMinutes) {
if (!burnRate || burnRate.tokensPerMinute === 0)
return 'smooth';
const projectedTokens = burnRate.tokensPerMinute * remainingMinutes;
const ratio = projectedTokens / remainingTokens;
if (ratio >= 2)
return 'critical';
if (ratio >= 1.5)
return 'high';
if (ratio >= 1)
return 'moderate';
return 'smooth';
}
export function formatBurnRateStatus(status) {
switch (status) {
case 'smooth':
return '🚢 Smooth sailing...';
case 'moderate':
return '⚡ Moderate usage';
case 'high':
return '🔥 High burn rate!';
case 'critical':
return '🚨 Critical usage!';
}
}
//# sourceMappingURL=session-metrics.js.map