Completed
on 5 Jan 2026, 1:17 am

Output

/konnectvol/bin/statusline-token-tracker.sh

StatusLine hook that captures token telemetry from Claude Code CLI

#!/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

# 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
if [ "$CURRENT_INPUT" -gt 0 ] || [ "$CURRENT_OUTPUT" -gt 0 ]; then
  # Fire and forget - don't block the status line
  (echo "$input" | jq -c '. + {receivedAt: ...}' | \
    curl -s -X POST "http://localhost:8020/statusline" \
      -H "Content-Type: application/json" \
      -d @- > /dev/null 2>&1 &)
fi

# Output status line display
printf "[%s] %d%% | $%.4f | %dK in/%dK out" ...

How it works

TriggerRuns every ~300ms during active Claude turns
InputFull JSON from Claude Code CLI on stdin
ActionPOSTs to localhost:8020/statusline (konsole)
OutputFormatted status: [Opus] 45% | $0.0234 | 15K in/4K out
StorageRaw JSONL at /konnectvol/konsole/data/statusline-raw.jsonl

Quick Actions

Original Request

No layout configured

Details

Type General
Status Completed
Scope vibetools
Tags consoletelemetryconfig
Created 5 Jan 2026, 1:17 am
Updated 5 Jan 2026, 1:17 am
Created By claude

Raw Data

{
  "id": "072bc1e1-bcc2-4b68-84fa-b33d1132c0ad",
  "type": "general",
  "status": "completed",
  "title": "StatusLine Hook Script",
  "description": "Token tracker hook script for Claude Code CLI telemetry",
  "context": {
    "output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:'Consolas','Monaco',monospace;\"><h2 style=\"font-family:sans-serif;color:#fff;margin:0 0 16px 0;\">/konnectvol/bin/statusline-token-tracker.sh</h2><p style=\"color:#7f848e;margin:0 0 12px 0;font-family:sans-serif;\">StatusLine hook that captures token telemetry from Claude Code CLI</p><pre style=\"background:#2d2d2d;padding:16px;border-radius:6px;overflow-x:auto;line-height:1.6;margin:0;font-size:0.85rem;\"><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\n<span style=\"color:#7f848e;\"># Read JSON input from stdin</span>\n<span style=\"color:#e5c07b;\">input</span><span style=\"color:#c678dd;\">=</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:#c678dd;\">=</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:#c678dd;\">=</span><span style=\"color:#98c379;\">$(echo \"$input\" | jq -r '.session_id // \"\"')</span>\n<span style=\"color:#e5c07b;\">CONTEXT_SIZE</span><span style=\"color:#c678dd;\">=</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:#c678dd;\">=</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:#c678dd;\">=</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:#c678dd;\">=</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:#c678dd;\">=</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:#c678dd;\">=</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:#c678dd;\">=</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:#c678dd;\">=</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</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:#c678dd;\">then</span>\n  <span style=\"color:#7f848e;\"># Fire and forget - don't block the status line</span>\n  (echo <span style=\"color:#98c379;\">\"$input\"</span> | jq -c <span style=\"color:#98c379;\">'. + {receivedAt: ...}'</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>\nprintf <span style=\"color:#98c379;\">\"[%s] %d%% | $%.4f | %dK in/%dK out\"</span> ...</pre><div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-top:16px;font-family:sans-serif;\"><h4 style=\"margin:0 0 12px 0;color:#fff;\">How it works</h4><table style=\"width:100%;border-collapse:collapse;font-size:0.9rem;\"><tr><td style=\"padding:8px 0;color:#7f848e;vertical-align:top;width:100px;\">Trigger</td><td style=\"padding:8px 0;color:#e0e0e0;\">Runs every ~300ms during active Claude turns</td></tr><tr><td style=\"padding:8px 0;color:#7f848e;vertical-align:top;\">Input</td><td style=\"padding:8px 0;color:#e0e0e0;\">Full JSON from Claude Code CLI on stdin</td></tr><tr><td style=\"padding:8px 0;color:#7f848e;vertical-align:top;\">Action</td><td style=\"padding:8px 0;color:#e0e0e0;\">POSTs to <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:4px;\">localhost:8020/statusline</code> (konsole)</td></tr><tr><td style=\"padding:8px 0;color:#7f848e;vertical-align:top;\">Output</td><td style=\"padding:8px 0;color:#e0e0e0;\">Formatted status: <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:4px;\">[Opus] 45% | $0.0234 | 15K in/4K out</code></td></tr><tr><td style=\"padding:8px 0;color:#7f848e;vertical-align:top;\">Storage</td><td style=\"padding:8px 0;color:#e0e0e0;\">Raw JSONL at <code style=\"background:#3d3d3d;padding:2px 6px;border-radius:4px;\">/konnectvol/konsole/data/statusline-raw.jsonl</code></td></tr></table></div></div>",
    "requestedAt": "2026-01-05T14:18:00Z",
    "requestId": "ef67fb17-dc17-45a1-b35c-5eb9f9adfe1c",
    "choices": [
      {
        "label": "View raw data",
        "value": "Show the last 5 entries from statusline-raw.jsonl",
        "primary": true
      },
      {
        "label": "Check konsole",
        "value": "Run kon-status to check if konsole is running"
      },
      {
        "label": "View settings",
        "value": "Show me the Claude settings.json again"
      }
    ]
  },
  "createdBy": "claude",
  "createdAt": "2026-01-04T15:17:53.228Z",
  "updatedAt": "2026-01-04T15:17:53.556Z",
  "requestId": "ef67fb17-dc17-45a1-b35c-5eb9f9adfe1c",
  "scope": "vibetools",
  "tags": [
    "console",
    "telemetry",
    "config"
  ],
  "targetUser": "claude"
}
DashboardReportsKontasksSessionsTelemetryLogs + Go