← Back to Kontasks
StatusLine Token Tracker Script
Contents of the statusline-token-tracker.sh hook script
Output
📊 statusline-token-tracker.sh
/konnectvol/bin/statusline-token-tracker.sh
#!/bin/bash # Status Line hook for capturing token usage from Claude Code CLI # Posts FULL JSON data to konsole for raw capture and telemetry aggregation # # This script runs on every status line update from Claude Code CLI (~300ms). # It receives rich JSON data on stdin including token usage, costs, and session info. # Read JSON input from stdin input=$(cat) # Extract key fields for display MODEL=$(echo "$input" | jq -r '.model.display_name // "unknown"') SESSION_ID=$(echo "$input" | jq -r '.session_id // ""') CONTEXT_SIZE=$(echo "$input" | jq -r '.context_window.context_window_size // 200000') CURRENT_INPUT=$(echo "$input" | jq -r '.context_window.current_usage.input_tokens // 0') CURRENT_OUTPUT=$(echo "$input" | jq -r '.context_window.current_usage.output_tokens // 0') TOTAL_INPUT=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0') TOTAL_OUTPUT=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0') TOTAL_COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0') # Calculate usage percentage PERCENT_USED=0 if [ "$CONTEXT_SIZE" -gt 0 ]; then PERCENT_USED=$(( (CURRENT_INPUT + CURRENT_OUTPUT) * 100 / CONTEXT_SIZE )) fi # Post FULL JSON to konsole if we have meaningful data (skip if all zeros) if [ "$CURRENT_INPUT" -gt 0 ] || [ "$CURRENT_OUTPUT" -gt 0 ] || [ "$TOTAL_COST" != "0" ]; then # Fire and forget - don't block the status line # Add timestamp to the full input and send to konsole (echo "$input" | jq -c '. + {receivedAt: "'"$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)"'"}' | \ curl -s -X POST "http://localhost:8020/statusline" \ -H "Content-Type: application/json" \ -d @- > /dev/null 2>&1 &) fi # Output status line display # Format: [Model] Context% | Cost | Tokens if [ "$TOTAL_COST" != "0" ]; then # Show cost if available printf "[%s] %d%% | \$%.4f | %dK in/%dK out" \ "$MODEL" "$PERCENT_USED" "$TOTAL_COST" \ "$(( TOTAL_INPUT / 1000 ))" "$(( TOTAL_OUTPUT / 1000 ))" else # Show tokens only printf "[%s] %d%% | %dK in/%dK out" \ "$MODEL" "$PERCENT_USED" \ "$(( TOTAL_INPUT / 1000 ))" "$(( TOTAL_OUTPUT / 1000 ))" fi
📋 Script Overview
| Purpose | Claude Code StatusLine hook for token telemetry |
| Update Rate | ~300ms during active turns |
| Data Posted To | http://localhost:8020/statusline |
| Storage | /konnectvol/konsole/data/statusline-raw.jsonl |
| Display Format | [Model] %% | $cost | XK in/YK out |
🔧 Key Features
- Fire-and-forget - Posts to konsole asynchronously, never blocks
- Full JSON capture - Sends complete StatusLine data for analysis
- Timestamp injection - Adds
receivedAtfield - Smart filtering - Only posts when there's meaningful data
Quick Actions
Original Request
No layout configured
Details
Type
General
Status
Completed
Scope
vibetools
Tags
konsoletelemetrystatusline
Created
5 Jan 2026, 1:29 am
Updated
5 Jan 2026, 1:30 am
Timing
⏱️ 66.2s
2 tools
● TTFE 5%
● Thinking 95%
● Tools 1%
Created By
claude
Raw Data
{
"id": "2347e1b6-0d4d-4c1f-b98c-f05d3fe8efd5",
"type": "general",
"status": "completed",
"title": "StatusLine Token Tracker Script",
"description": "Contents of the statusline-token-tracker.sh hook script",
"context": {
"output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:'Consolas','Monaco',monospace;\">\n<h2 style=\"font-family:sans-serif;color:#fff;margin:0 0 16px 0;\">📊 statusline-token-tracker.sh</h2>\n<p style=\"font-family:sans-serif;color:#9ca3af;margin:0 0 16px 0;\"><code style=\"background:#2d2d2d;padding:2px 6px;border-radius:4px;\">/konnectvol/bin/statusline-token-tracker.sh</code></p>\n\n<pre style=\"background:#2d2d2d;padding:16px;border-radius:6px;overflow-x:auto;line-height:1.6;color:#e0e0e0;font-size:0.9rem;\"><span style=\"color:#7f848e;\">#!/bin/bash</span>\n<span style=\"color:#7f848e;\"># Status Line hook for capturing token usage from Claude Code CLI</span>\n<span style=\"color:#7f848e;\"># Posts FULL JSON data to konsole for raw capture and telemetry aggregation</span>\n<span style=\"color:#7f848e;\">#</span>\n<span style=\"color:#7f848e;\"># This script runs on every status line update from Claude Code CLI (~300ms).</span>\n<span style=\"color:#7f848e;\"># It receives rich JSON data on stdin including token usage, costs, and session info.</span>\n\n<span style=\"color:#7f848e;\"># Read JSON input from stdin</span>\n<span style=\"color:#e5c07b;\">input</span>=<span style=\"color:#98c379;\">$(cat)</span>\n\n<span style=\"color:#7f848e;\"># Extract key fields for display</span>\n<span style=\"color:#e5c07b;\">MODEL</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.model.display_name // \"unknown\"')</span>\n<span style=\"color:#e5c07b;\">SESSION_ID</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.session_id // \"\"')</span>\n<span style=\"color:#e5c07b;\">CONTEXT_SIZE</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.context_window.context_window_size // 200000')</span>\n<span style=\"color:#e5c07b;\">CURRENT_INPUT</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.context_window.current_usage.input_tokens // 0')</span>\n<span style=\"color:#e5c07b;\">CURRENT_OUTPUT</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.context_window.current_usage.output_tokens // 0')</span>\n<span style=\"color:#e5c07b;\">TOTAL_INPUT</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.context_window.total_input_tokens // 0')</span>\n<span style=\"color:#e5c07b;\">TOTAL_OUTPUT</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.context_window.total_output_tokens // 0')</span>\n<span style=\"color:#e5c07b;\">TOTAL_COST</span>=<span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.cost.total_cost_usd // 0')</span>\n\n<span style=\"color:#7f848e;\"># Calculate usage percentage</span>\n<span style=\"color:#e5c07b;\">PERCENT_USED</span>=<span style=\"color:#d19a66;\">0</span>\n<span style=\"color:#c678dd;\">if</span> [ <span style=\"color:#98c379;\">\"$CONTEXT_SIZE\"</span> -gt <span style=\"color:#d19a66;\">0</span> ]; <span style=\"color:#c678dd;\">then</span>\n <span style=\"color:#e5c07b;\">PERCENT_USED</span>=<span style=\"color:#98c379;\">$(( (CURRENT_INPUT + CURRENT_OUTPUT) * 100 / CONTEXT_SIZE ))</span>\n<span style=\"color:#c678dd;\">fi</span>\n\n<span style=\"color:#7f848e;\"># Post FULL JSON to konsole if we have meaningful data (skip if all zeros)</span>\n<span style=\"color:#c678dd;\">if</span> [ <span style=\"color:#98c379;\">\"$CURRENT_INPUT\"</span> -gt <span style=\"color:#d19a66;\">0</span> ] || [ <span style=\"color:#98c379;\">\"$CURRENT_OUTPUT\"</span> -gt <span style=\"color:#d19a66;\">0</span> ] || [ <span style=\"color:#98c379;\">\"$TOTAL_COST\"</span> != <span style=\"color:#98c379;\">\"0\"</span> ]; <span style=\"color:#c678dd;\">then</span>\n <span style=\"color:#7f848e;\"># Fire and forget - don't block the status line</span>\n <span style=\"color:#7f848e;\"># Add timestamp to the full input and send to konsole</span>\n (<span style=\"color:#c678dd;\">echo</span> <span style=\"color:#98c379;\">\"$input\"</span> | jq -c <span style=\"color:#98c379;\">'. + {receivedAt: \"'\"$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)\"'\"}'</span> | \\\n curl -s -X POST <span style=\"color:#98c379;\">\"http://localhost:8020/statusline\"</span> \\\n -H <span style=\"color:#98c379;\">\"Content-Type: application/json\"</span> \\\n -d @- > /dev/null 2>&1 &)\n<span style=\"color:#c678dd;\">fi</span>\n\n<span style=\"color:#7f848e;\"># Output status line display</span>\n<span style=\"color:#7f848e;\"># Format: [Model] Context% | Cost | Tokens</span>\n<span style=\"color:#c678dd;\">if</span> [ <span style=\"color:#98c379;\">\"$TOTAL_COST\"</span> != <span style=\"color:#98c379;\">\"0\"</span> ]; <span style=\"color:#c678dd;\">then</span>\n <span style=\"color:#7f848e;\"># Show cost if available</span>\n printf <span style=\"color:#98c379;\">\"[%s] %d%% | \\$%.4f | %dK in/%dK out\"</span> \\\n <span style=\"color:#98c379;\">\"$MODEL\"</span> <span style=\"color:#98c379;\">\"$PERCENT_USED\"</span> <span style=\"color:#98c379;\">\"$TOTAL_COST\"</span> \\\n <span style=\"color:#98c379;\">\"$(( TOTAL_INPUT / 1000 ))\"</span> <span style=\"color:#98c379;\">\"$(( TOTAL_OUTPUT / 1000 ))\"</span>\n<span style=\"color:#c678dd;\">else</span>\n <span style=\"color:#7f848e;\"># Show tokens only</span>\n printf <span style=\"color:#98c379;\">\"[%s] %d%% | %dK in/%dK out\"</span> \\\n <span style=\"color:#98c379;\">\"$MODEL\"</span> <span style=\"color:#98c379;\">\"$PERCENT_USED\"</span> \\\n <span style=\"color:#98c379;\">\"$(( TOTAL_INPUT / 1000 ))\"</span> <span style=\"color:#98c379;\">\"$(( TOTAL_OUTPUT / 1000 ))\"</span>\n<span style=\"color:#c678dd;\">fi</span></pre>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-top:16px;font-family:sans-serif;\">\n<h4 style=\"margin:0 0 12px 0;color:#fff;\">📋 Script Overview</h4>\n<table style=\"width:100%;border-collapse:collapse;font-size:0.9rem;\">\n<tr style=\"border-bottom:1px solid #444;\">\n <td style=\"padding:8px 12px;color:#9ca3af;\">Purpose</td>\n <td style=\"padding:8px 12px;color:#e0e0e0;\">Claude Code StatusLine hook for token telemetry</td>\n</tr>\n<tr style=\"border-bottom:1px solid #444;\">\n <td style=\"padding:8px 12px;color:#9ca3af;\">Update Rate</td>\n <td style=\"padding:8px 12px;color:#e0e0e0;\">~300ms during active turns</td>\n</tr>\n<tr style=\"border-bottom:1px solid #444;\">\n <td style=\"padding:8px 12px;color:#9ca3af;\">Data Posted To</td>\n <td style=\"padding:8px 12px;color:#61afef;\">http://localhost:8020/statusline</td>\n</tr>\n<tr style=\"border-bottom:1px solid #444;\">\n <td style=\"padding:8px 12px;color:#9ca3af;\">Storage</td>\n <td style=\"padding:8px 12px;color:#e0e0e0;\">/konnectvol/konsole/data/statusline-raw.jsonl</td>\n</tr>\n<tr>\n <td style=\"padding:8px 12px;color:#9ca3af;\">Display Format</td>\n <td style=\"padding:8px 12px;color:#98c379;font-family:monospace;\">[Model] %% | $cost | XK in/YK out</td>\n</tr>\n</table>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-top:16px;font-family:sans-serif;\">\n<h4 style=\"margin:0 0 12px 0;color:#fff;\">🔧 Key Features</h4>\n<ul style=\"margin:0;padding-left:20px;color:#e0e0e0;line-height:1.8;\">\n<li><strong style=\"color:#98c379;\">Fire-and-forget</strong> - Posts to konsole asynchronously, never blocks</li>\n<li><strong style=\"color:#61afef;\">Full JSON capture</strong> - Sends complete StatusLine data for analysis</li>\n<li><strong style=\"color:#e5c07b;\">Timestamp injection</strong> - Adds <code style=\"background:#1e1e1e;padding:2px 4px;border-radius:2px;\">receivedAt</code> field</li>\n<li><strong style=\"color:#c678dd;\">Smart filtering</strong> - Only posts when there's meaningful data</li>\n</ul>\n</div>\n\n</div>",
"requestedAt": "2026-01-05T12:00:00.000Z",
"requestId": "c7a4e9f0-e659-4965-8c3d-2399871787da",
"turnTiming": {
"totalMs": 66239,
"ttfeMs": 3193,
"thinkingMs": 62665,
"toolExecutionMs": 377,
"toolCallCount": 2,
"thinkingPct": 95,
"toolsPct": 1,
"ttfePct": 5
}
},
"createdBy": "claude",
"createdAt": "2026-01-04T15:29:54.037Z",
"updatedAt": "2026-01-04T15:30:03.968Z",
"requestId": "c7a4e9f0-e659-4965-8c3d-2399871787da",
"scope": "vibetools",
"tags": [
"konsole",
"telemetry",
"statusline"
],
"targetUser": "claude"
}