#!/usr/bin/env bash # KeiSei tamagotchi โ€” statusline renderer. Outputs ONE line. # SSoT: reads the kit's OWN tracking, does not maintain a parallel one. # - running sub-agents โ† ~/.claude/memory/time-metrics/.task-.start # (written by hooks/task-timer.sh: {id,desc,type,start_epoch}) # - agent token / cost โ† ~/.claude/memory/agent-events.jsonl # (written by hooks/agent-event-done.sh: {tokens,cost_usd,...}) # - mood / lang / plan โ† ~/.claude/pet/state (keisei-pet-update.sh) set -u if [ ! -t 0 ]; then cat >/dev/null 2>&1 || true; fi STATE="${HOME}/.claude/pet/state" TM_DIR="${HOME}/.claude/memory/time-metrics" EVENTS="${HOME}/.claude/memory/agent-events.jsonl" mood="neutral"; message=""; since=$(date +%s) rust_today=0; patents_today=0; violations=0; lang=""; plan="" # shellcheck source=/dev/null [ -f "$STATE" ] && source "$STATE" 2>/dev/null || true now=$(date +%s) dim=$'\033[2m'; reset=$'\033[0m' _agent_emoji() { case "$1" in *researcher*) echo "๐Ÿ”ฌ";; *architect*) echo "๐Ÿ—๏ธ";; *critic*) echo "๐Ÿ”ช";; *security*) echo "๐Ÿ›ก๏ธ";; *validator*) echo "โœ…";; *cost*) echo "๐Ÿ’ฐ";; *modal*) echo "โ˜๏ธ";; *fal*) echo "๐ŸŽจ";; *ml-implementer*|*ml_implementer*) echo "๐Ÿง ";; *ml-researcher*|*ml_researcher*) echo "๐Ÿ“š";; *infra*) echo "๐Ÿ”ง";; *implementer*) echo "โš™๏ธ";; *patent*) echo "๐Ÿ“œ";; Explore|*explore*) echo "๐Ÿ”ญ";; Plan|*plan*) echo "๐Ÿ“";; *) echo "๐Ÿค–";; esac } _elapsed() { local s=$1 if [ "$s" -lt 60 ]; then printf '%ds' "$s" elif [ "$s" -lt 3600 ]; then printf '%dm' $(( s / 60 )) else printf '%dh%dm' $(( s / 3600 )) $(( (s % 3600) / 60 )); fi } # โ”€โ”€ running sub-agents (from task-timer's .task-*.start) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ agents=""; n_agents=0 if [ -d "$TM_DIR" ]; then for f in "$TM_DIR"/.task-*.start; do [ -f "$f" ] || continue typ="$(jq -r '.type // "agent"' "$f" 2>/dev/null)" st="$(jq -r '.start_epoch // empty' "$f" 2>/dev/null)" [ -z "$st" ] && continue age=$(( now - st )) [ "$age" -gt 7200 ] && continue # ignore stale (kit removes on done) short="$(printf '%s' "$typ" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9].*$//' | cut -c1-12)" agents+=" $(_agent_emoji "$typ")${short}ยท$(_elapsed "$age")" n_agents=$((n_agents+1)) done fi # โ”€โ”€ agent token / cost spend today (from agent-events.jsonl) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ spend="" if [ -f "$EVENTS" ]; then today="$(date -u +%Y-%m-%d)" read -r tot_tok tot_cost < <(awk -v d="$today" ' index($0,d)>0 { t=0; c=0 if (match($0,/total_tokens[^0-9]*[0-9]+/)) { s=substr($0,RSTART,RLENGTH); gsub(/[^0-9]/,"",s); t=s } if (match($0,/"cost_usd"[: ]*[0-9.]+/)) { s=substr($0,RSTART,RLENGTH); gsub(/[^0-9.]/,"",s); c=s } T+=t; C+=c } END { printf "%d %.4f", T+0, C+0 }' "$EVENTS" 2>/dev/null) if [ "${tot_cost:-0}" != "0.0000" ] && [ -n "${tot_cost:-}" ]; then spend=" ๐Ÿ’ฐ\$$(printf '%.2f' "$tot_cost" 2>/dev/null)" elif [ "${tot_tok:-0}" -gt 0 ] 2>/dev/null; then if [ "$tot_tok" -ge 1000 ]; then spend=" ๐Ÿช™$(( tot_tok / 1000 ))k"; else spend=" ๐Ÿช™${tot_tok}"; fi fi fi # โ”€โ”€ mood face โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ idle=$(( now - since )) if [ "$idle" -gt 300 ] && [ "$mood" != "angry" ] && [ "$mood" != "alert" ] && [ "$n_agents" -eq 0 ]; then mood="sleep"; message="zzz" fi case "$mood" in happy) face="(แต”แดฅแต”)"; color=$'\033[32m';; proud) face="(โ€ขฬ€แด—โ€ขฬ)ูˆ"; color=$'\033[1;32m';; thinking) face="(โŠ™.โŠ™)"; color=$'\033[36m';; alert) face="(ส˜แด—ส˜)"; color=$'\033[33m';; angry) face="(รฒ_รณ)"; color=$'\033[31m';; sad) face="(โ•ฅ๏นโ•ฅ)"; color=$'\033[34m';; sleep) face="(-.-)"; color=$'\033[2;37m';; *) face="(โ€ขแด—โ€ข)"; color=$'\033[37m';; esac stats="" [ "${rust_today:-0}" -gt 0 ] 2>/dev/null && stats+=" ๐Ÿฆ€${rust_today}" [ "${patents_today:-0}" -gt 0 ] 2>/dev/null && stats+=" ๐Ÿ“œ${patents_today}" [ "${violations:-0}" -gt 0 ] 2>/dev/null && stats+=" โš ${violations}" proj="${PWD##*/}"; [ -z "$proj" ] && proj="~" out="" if [ -n "${agents// }" ]; then out+="${agents# }${spend} " elif [ -n "$spend" ]; then out+="${spend# } "; fi [ -n "$plan" ] && out+="${plan} " out+="${color}${face}${reset}" [ -n "$message" ] && out+=" ${dim}${message}${reset}" out+="${stats}" [ -n "$lang" ] && out+=" ${lang}" out+=" ${dim}๐Ÿ“ ${proj}${reset}" printf '%s' "$out"