From cffe15e1f6eb9aea949422126a7f214f7d83bfe0 Mon Sep 17 00:00:00 2001 From: SirBlobby Date: Mon, 27 Jul 2026 12:00:04 -0400 Subject: [PATCH] Widen side cards, add icon badges and graphics, add wallpaper button --- ags/lib/claude-usage.sh | 17 ++++++++---- ags/style.css | 48 +++++++++++++++++++++++++++++---- ags/widget/ClaudeUsage.tsx | 30 ++++++++++----------- ags/widget/QuickSettings.tsx | 52 +++++++++++++++++++++++++++--------- ags/widget/WidgetCard.tsx | 22 +++++++++++++++ install.sh | 1 + 6 files changed, 132 insertions(+), 38 deletions(-) create mode 100644 ags/widget/WidgetCard.tsx diff --git a/ags/lib/claude-usage.sh b/ags/lib/claude-usage.sh index f5246ed..02cf6a6 100755 --- a/ags/lib/claude-usage.sh +++ b/ags/lib/claude-usage.sh @@ -2,24 +2,31 @@ PROJECTS_DIR="$HOME/.claude/projects" TODAY=$(date -u '+%Y-%m-%d') +EMPTY='{"available":false,"tokens":0,"messages":0,"cacheHitPercent":0}' if [ ! -d "$PROJECTS_DIR" ]; then - echo '{"available":false,"tokens":0,"messages":0}' + echo "$EMPTY" exit 0 fi FILES=$(find "$PROJECTS_DIR" -name "*.jsonl" -newermt "$TODAY") if [ -z "$FILES" ]; then - echo '{"available":true,"tokens":0,"messages":0}' + echo '{"available":true,"tokens":0,"messages":0,"cacheHitPercent":0}' exit 0 fi jq -s --arg today "$TODAY" ' [.[] | select(.timestamp != null and (.timestamp | startswith($today)) and .message.usage != null) | .message.usage] as $usages + | ([$usages[] | .input_tokens // 0] | add // 0) as $input + | ([$usages[] | .output_tokens // 0] | add // 0) as $output + | ([$usages[] | .cache_creation_input_tokens // 0] | add // 0) as $cacheCreate + | ([$usages[] | .cache_read_input_tokens // 0] | add // 0) as $cacheRead + | ($input + $cacheCreate + $cacheRead) as $totalInput | { available: true, - tokens: ([$usages[] | (.input_tokens // 0) + (.output_tokens // 0) + (.cache_creation_input_tokens // 0) + (.cache_read_input_tokens // 0)] | add // 0), - messages: ($usages | length) + tokens: ($totalInput + $output), + messages: ($usages | length), + cacheHitPercent: (if $totalInput > 0 then (($cacheRead / $totalInput) * 100) else 0 end) } -' $FILES 2>/dev/null || echo '{"available":false,"tokens":0,"messages":0}' +' $FILES 2>/dev/null || echo "$EMPTY" diff --git a/ags/style.css b/ags/style.css index d41b488..244f012 100644 --- a/ags/style.css +++ b/ags/style.css @@ -350,20 +350,27 @@ } .qs-side-panel { - min-width: 170px; + min-width: 240px; } .widget-card { - padding: 10px; + padding: 12px; } -.widget-card-icon { +.widget-card-header { + margin-bottom: 2px; +} + +.widget-icon-badge { + background-color: alpha(@accent, 0.18); + border-radius: 8px; + padding: 5px 8px; color: @accent; - font-size: 14px; + font-size: 16px; } .widget-card-title { - font-size: 12px; + font-size: 13px; font-weight: bold; color: @foreground; } @@ -384,6 +391,37 @@ opacity: 0.6; } +.widget-hero-value { + font-size: 20px; + font-weight: bold; + color: @foreground; +} + +.widget-stat-row { + padding: 1px 0; +} + +.widget-stat-icon { + color: @color5; + font-size: 13px; + min-width: 18px; +} + +.widget-level-bar { + min-height: 6px; +} + +.widget-level-bar trough { + min-height: 6px; + border-radius: 6px; + background-color: alpha(@foreground, 0.15); +} + +.widget-level-bar block.filled { + border-radius: 6px; + background-color: @accent; +} + .control-center { min-width: 360px; } diff --git a/ags/widget/ClaudeUsage.tsx b/ags/widget/ClaudeUsage.tsx index 3c8e49c..6e2baa2 100644 --- a/ags/widget/ClaudeUsage.tsx +++ b/ags/widget/ClaudeUsage.tsx @@ -1,22 +1,24 @@ import { Gtk } from "ags/gtk3" import { createPoll } from "ags/time" import { shell } from "../lib/utils" +import { CardHeader, StatRow } from "./WidgetCard" type ClaudeUsage = { available: boolean tokens: number messages: number + cacheHitPercent: number } const usage = createPoll( - { available: false, tokens: 0, messages: 0 }, + { available: false, tokens: 0, messages: 0, cacheHitPercent: 0 }, 60000, shell("bash $HOME/.config/ags/lib/claude-usage.sh"), (stdout) => { try { return JSON.parse(stdout.trim()) } catch { - return { available: false, tokens: 0, messages: 0 } + return { available: false, tokens: 0, messages: 0, cacheHitPercent: 0 } } }, ) @@ -29,11 +31,8 @@ function formatTokens(tokens: number) { export function ClaudeUsageCard() { return ( - - - + +