feat: make token counter visible by default with color coding

Changes:
- Remove display:none from token counter (always visible)
- Add compact formatting (2.5k / 200k tokens instead of 2500 tokens)
- Color coding based on usage percentage:
  - Green: < 50% usage
  - Yellow: 50-80% usage
  - Red: > 80% usage
- Keep counter visible even on error (shows 0 / 200k)
- Improve discoverability of token tracking feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-16 22:13:15 -07:00
parent 8c70e0558f
commit 41437e1751
2 changed files with 28 additions and 6 deletions

View File

@@ -662,7 +662,7 @@
</form> </form>
<div class="status-bar"> <div class="status-bar">
<span id="status-text" class="status-text">Ready</span> <span id="status-text" class="status-text">Ready</span>
<div id="token-counter" class="token-counter" style="display: none;"> <div id="token-counter" class="token-counter">
<span id="token-count-total" class="token-count">0 tokens</span> <span id="token-count-total" class="token-count">0 tokens</span>
<button id="token-details-btn" class="token-details-btn" title="Show breakdown"> <button id="token-details-btn" class="token-details-btn" title="Show breakdown">
<svg width="12" height="12" viewBox="0 0 16 16" fill="none"> <svg width="12" height="12" viewBox="0 0 16 16" fill="none">

View File

@@ -1639,6 +1639,14 @@ function setupKeyboardShortcuts() {
// Token Counter // Token Counter
let tokenUpdateTimeout = null; let tokenUpdateTimeout = null;
// Helper function to format token counts
function formatTokenCount(count) {
if (count >= 1000) {
return (count / 1000).toFixed(1) + 'k';
}
return count.toString();
}
async function updateTokenCount() { async function updateTokenCount() {
// Debounce token count updates // Debounce token count updates
if (tokenUpdateTimeout) { if (tokenUpdateTimeout) {
@@ -1653,11 +1661,23 @@ async function updateTokenCount() {
currentInput currentInput
}); });
// Update total display // Update total display with color coding
const tokenCounter = document.getElementById('token-counter'); const tokenCounter = document.getElementById('token-counter');
const tokenCountTotal = document.getElementById('token-count-total'); const tokenCountTotal = document.getElementById('token-count-total');
tokenCountTotal.textContent = `${tokenData.total} tokens`; const contextLimit = 200000; // Claude 200k context
tokenCounter.style.display = 'flex'; const percentage = (tokenData.total / contextLimit) * 100;
// Format: "2.5k / 200k tokens"
tokenCountTotal.textContent = `${formatTokenCount(tokenData.total)} / ${formatTokenCount(contextLimit)} tokens`;
// Apply color coding based on usage
if (percentage < 50) {
tokenCountTotal.style.color = '#4ade80'; // Green
} else if (percentage < 80) {
tokenCountTotal.style.color = '#facc15'; // Yellow
} else {
tokenCountTotal.style.color = '#f87171'; // Red
}
// Update breakdown // Update breakdown
document.getElementById('token-system').textContent = tokenData.system_prompt; document.getElementById('token-system').textContent = tokenData.system_prompt;
@@ -1671,8 +1691,10 @@ async function updateTokenCount() {
document.getElementById('token-total-detail').textContent = tokenData.total; document.getElementById('token-total-detail').textContent = tokenData.total;
} catch (error) { } catch (error) {
console.error('Failed to update token count:', error); console.error('Failed to update token count:', error);
// Hide token counter on error // Keep counter visible, just show 0
document.getElementById('token-counter').style.display = 'none'; const tokenCountTotal = document.getElementById('token-count-total');
tokenCountTotal.textContent = '0 / 200k tokens';
tokenCountTotal.style.color = 'var(--text-secondary)';
} }
}, 300); // Update after 300ms of no typing }, 300); // Update after 300ms of no typing
} }