mirror of
https://github.com/theniceboy/.config.git
synced 2025-12-26 14:44:57 +08:00
update cc statusline
This commit is contained in:
parent
02eea13aa6
commit
0487e8b3ba
4 changed files with 171 additions and 14 deletions
|
|
@ -1,14 +1,29 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"lines": [
|
"lines": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "95e108c1-bf22-4a23-94c8-be096ccaf8c8",
|
||||||
|
"type": "model"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "222b40b7-1291-4090-a0ae-bc43637241b3",
|
||||||
|
"type": "custom-command",
|
||||||
|
"commandPath": "uv run ~/.config/claude/scripts/context-status.py"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "64a1187d-65c6-4490-9f30-fa618da8b8ce",
|
||||||
|
"type": "output-style"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id": "9fc4ae79-f172-4d4b-b7f8-c2c3e923e7aa",
|
"id": "9fc4ae79-f172-4d4b-b7f8-c2c3e923e7aa",
|
||||||
"type": "current-working-dir",
|
"type": "current-working-dir",
|
||||||
|
"color": "white",
|
||||||
"commandPath": "pwd | xargs basename",
|
"commandPath": "pwd | xargs basename",
|
||||||
"preserveColors": true,
|
"preserveColors": true,
|
||||||
"timeout": 5000,
|
"timeout": 5000
|
||||||
"color": "white"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4f12f8ba-4728-4590-ac5d-8c2b96ec91e8",
|
"id": "4f12f8ba-4728-4590-ac5d-8c2b96ec91e8",
|
||||||
|
|
@ -23,12 +38,33 @@
|
||||||
"type": "version"
|
"type": "version"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[],
|
[
|
||||||
[]
|
{
|
||||||
|
"id": "032c2103-52cd-42fd-9e03-325ee4dfc6c7",
|
||||||
|
"type": "session-cost"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e7177c91-ecb8-422d-9496-b380d05d6e6b",
|
||||||
|
"type": "session-clock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5aef38b5-a24f-40a7-b201-afd3a5870f2d",
|
||||||
|
"type": "custom-command",
|
||||||
|
"commandPath": "echo \"$(ccusage daily --json | jq -r 'if type == \\\"array\\\" then .[-1] else . end | if .totalCostUSD then \\\"$\\\" + (.totalCostUSD | tostring) else \\\"$0.00\\\" end') 📅\"",
|
||||||
|
"timeout": 10000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
||||||
|
"type": "custom-command",
|
||||||
|
"commandPath": "ccusage blocks --active --json | jq -r '.blocks[0] | \"$\" + (.costUSD | . * 100 | round / 100 | tostring) + \" block (\" + (.projection.remainingMinutes / 60 | floor | tostring) + \"h \" + (.projection.remainingMinutes % 60 | tostring) + \"m left)\"'",
|
||||||
|
"timeout": 10000
|
||||||
|
}
|
||||||
|
]
|
||||||
],
|
],
|
||||||
"flexMode": "full",
|
"flexMode": "full",
|
||||||
"compactThreshold": 60,
|
"compactThreshold": 60,
|
||||||
"colorLevel": 2,
|
"colorLevel": 2,
|
||||||
|
"defaultPadding": " ",
|
||||||
"inheritSeparatorColors": false,
|
"inheritSeparatorColors": false,
|
||||||
"globalBold": false,
|
"globalBold": false,
|
||||||
"powerline": {
|
"powerline": {
|
||||||
|
|
@ -41,8 +77,7 @@
|
||||||
],
|
],
|
||||||
"startCaps": [],
|
"startCaps": [],
|
||||||
"endCaps": [],
|
"endCaps": [],
|
||||||
"autoAlign": false,
|
"theme": "nord-aurora",
|
||||||
"theme": "nord-aurora"
|
"autoAlign": false
|
||||||
},
|
}
|
||||||
"defaultPadding": " "
|
|
||||||
}
|
}
|
||||||
72
claude/scripts/context-status.py
Executable file
72
claude/scripts/context-status.py
Executable file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Constant
|
||||||
|
CONTEXT_LIMIT = int(168000) # CC triggers /compact at ~78% context utilization
|
||||||
|
|
||||||
|
# Read JSON from stdin
|
||||||
|
data = json.load(sys.stdin)
|
||||||
|
|
||||||
|
transcript_path = data["transcript_path"]
|
||||||
|
|
||||||
|
# Parse transcript file to calculate context usage
|
||||||
|
context_used_token = 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(transcript_path, "r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
# Iterate from last line to first line
|
||||||
|
for line in reversed(lines):
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj = json.loads(line)
|
||||||
|
# Check if this line contains the required token usage fields
|
||||||
|
if (
|
||||||
|
obj.get("type") == "assistant"
|
||||||
|
and "message" in obj
|
||||||
|
and "usage" in obj["message"]
|
||||||
|
and all(
|
||||||
|
key in obj["message"]["usage"]
|
||||||
|
for key in [
|
||||||
|
"input_tokens",
|
||||||
|
"cache_creation_input_tokens",
|
||||||
|
"cache_read_input_tokens",
|
||||||
|
"output_tokens",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
):
|
||||||
|
usage = obj["message"]["usage"]
|
||||||
|
input_tokens = usage["input_tokens"]
|
||||||
|
cache_creation_input_tokens = usage["cache_creation_input_tokens"]
|
||||||
|
cache_read_input_tokens = usage["cache_read_input_tokens"]
|
||||||
|
output_tokens = usage["output_tokens"]
|
||||||
|
|
||||||
|
context_used_token = (
|
||||||
|
input_tokens
|
||||||
|
+ cache_creation_input_tokens
|
||||||
|
+ cache_read_input_tokens
|
||||||
|
+ output_tokens
|
||||||
|
)
|
||||||
|
break # Break after finding the first occurrence
|
||||||
|
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
# Skip malformed JSON lines
|
||||||
|
continue
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
# If transcript file doesn't exist, keep context_used_token as 0
|
||||||
|
pass
|
||||||
|
|
||||||
|
context_used_rate = (context_used_token / CONTEXT_LIMIT) * 100
|
||||||
|
|
||||||
|
# Create progress bar
|
||||||
|
bar_length = 20
|
||||||
|
filled_length = int(bar_length * context_used_token // CONTEXT_LIMIT)
|
||||||
|
bar = "█" * filled_length + "░" * (bar_length - filled_length)
|
||||||
|
|
||||||
|
print(f"[{bar}] {context_used_rate:.1f}% ({context_used_token:,})")
|
||||||
50
claude/scripts/usage-line.sh
Executable file
50
claude/scripts/usage-line.sh
Executable file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get current session cost (assuming current working directory as session)
|
||||||
|
session_data=$(ccusage session --json | jq -r '.sessions[] | select(.sessionId == "'"$(pwd | sed 's|/|-|g')"'") | .totalCost')
|
||||||
|
session_cost=${session_data:-0}
|
||||||
|
|
||||||
|
# Get today's cost
|
||||||
|
today_cost=$(ccusage daily --json | jq -r '.daily[0].totalCost // 0')
|
||||||
|
|
||||||
|
# Get current active block info
|
||||||
|
block_info=$(ccusage blocks --json | jq -r '
|
||||||
|
.blocks[] |
|
||||||
|
select(.isActive == true) |
|
||||||
|
"\(.costUSD // 0)|\(.startTime)|\(.endTime)"
|
||||||
|
')
|
||||||
|
|
||||||
|
if [[ -n "$block_info" ]]; then
|
||||||
|
block_cost=$(echo "$block_info" | cut -d'|' -f1)
|
||||||
|
start_time=$(echo "$block_info" | cut -d'|' -f2)
|
||||||
|
end_time=$(echo "$block_info" | cut -d'|' -f3)
|
||||||
|
|
||||||
|
# Calculate time left in block (5 hours from start)
|
||||||
|
start_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%S.%fZ" "$start_time" +%s 2>/dev/null || date -d "$start_time" +%s 2>/dev/null || echo "0")
|
||||||
|
current_epoch=$(date +%s)
|
||||||
|
elapsed_seconds=$((current_epoch - start_epoch))
|
||||||
|
remaining_seconds=$((18000 - elapsed_seconds)) # 5 hours = 18000 seconds
|
||||||
|
|
||||||
|
if [[ $remaining_seconds -gt 0 ]]; then
|
||||||
|
hours=$((remaining_seconds / 3600))
|
||||||
|
minutes=$(((remaining_seconds % 3600) / 60))
|
||||||
|
time_left="${hours}h ${minutes}m left"
|
||||||
|
else
|
||||||
|
time_left="expired"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Calculate hourly rate
|
||||||
|
if [[ $elapsed_seconds -gt 0 ]]; then
|
||||||
|
hourly_rate=$(echo "scale=2; $block_cost * 3600 / $elapsed_seconds" | bc -l 2>/dev/null || echo "0.00")
|
||||||
|
else
|
||||||
|
hourly_rate="0.00"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
block_cost="0.00"
|
||||||
|
time_left="no active block"
|
||||||
|
hourly_rate="0.00"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Format output
|
||||||
|
printf "💰 \$%.2f session / \$%.2f today / \$%.2f block (%s) | 🔥 \$%.2f/hr\n" \
|
||||||
|
"$session_cost" "$today_cost" "$block_cost" "$time_left" "$hourly_rate"
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
{
|
{
|
||||||
"model": "opusplan",
|
|
||||||
"includeCoAuthoredBy": false,
|
"includeCoAuthoredBy": false,
|
||||||
"statusLine": {
|
"model": "opusplan",
|
||||||
"type": "command",
|
|
||||||
"command": "bash ~/.config/claude/scripts/statusline.sh",
|
|
||||||
"padding": 0
|
|
||||||
},
|
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"Stop": [
|
"Stop": [
|
||||||
{
|
{
|
||||||
|
|
@ -18,5 +13,10 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
"statusLine": {
|
||||||
|
"type": "command",
|
||||||
|
"command": "bunx -y ccstatusline@latest",
|
||||||
|
"padding": 0
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue