ai:platformy:claude-code:statusline

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
ai:platformy:claude-code:statusline [08.05.2026 21:45] – Zjednodušení: ctx% čteno přímo z used_percentage. Doplněny poznatky z oficiální dokumentace (total_input_tokens zahrnuje cache, used_percentage existuje). Petr Nosekai:platformy:claude-code:statusline [09.08.2026 23:18] (aktuální) – Aktualizace subagent status line pro aktuální chování label Petr Nosek
Řádek 1: Řádek 1:
 ====== Status line pro Claude Code ====== ====== Status line pro Claude Code ======
  
-//Vytvořeno: **** | Aktualizováno: **~~LASTMOD~~**//+//Vytvořeno: **11.04.2026** | Aktualizováno: **~~LASTMOD~~**//
  
-[[ai:platformy:claude-code:start|Claude Code]] umí vykreslovat vlastní status line spuštěný jako externí příkaz. Tohle je moje varianta, která drží stabilní pořadí polí a na jeden pohled ukazuje pracovní adresář, model, session ID, využití kontextu, 5h 7d limity i absolutní spotřebu tokenů context window se zvýrazněním nad hranicí 200k.+[[ai:platformy:claude-code:start|Claude Code]] umí podle [[https://code.claude.com/docs/en/statusline|oficiální dokumentace]] vykreslovat vlastní status line přes externí příkaz. Tohle je moje aktuální konfigurace: hlavní ''statusLine'' ukazuje stav top-level session a samostatná ''subagentStatusLine'' přidává přehled běžících subagentů v agent panelu.
  
 ===== Co z toho získám ===== ===== Co z toho získám =====
  
-  * Aktuální pracovní adresář projektu (rootkde byl Claude Code spuštěn) zkrácený relativně k ''$HOME''takže místo celé cesty vidím jen ''~'' nebo ''~/...''. Adresář se v průběhu session neměníi když shell přejde do podadresáře+  * Hlavní status line ukazuje pracovní adresář, model, session IDvyužití context window, 5h a 7d limity a absolutní spotřebu tokenů
-  * Použitý model a session ID ímo ve status line+  * Subagent status line ukazuje každého subagenta jako vlastní řádek: agent, model, krátký popis dispatche, živou činnost, stav, zaplnění jeho context window, tokeny, trend tokenů, rychlost tokenů za sekundu, běh od startu a případně pracovní adresář
-  * Využití context window v procentech, čtené přímo předpočítaného pole ''used_percentage''+  * Model subagenta se bere z pole ''model'', které Claude Code předává do ''subagentStatusLine''Název ''subagent_type'' v datech samostatně není; pro ehled se proto zapisuje do ''description''
-  * 5hodinový a 7denní limit, včetně času resetupokud je Claude Code pošle v JSONu. +  * Popisky subagentů jsou čitelné i při paralelním běhu více agentů.
-  * Absolutní spotřebu tokenů context window ve formátu ''XYZk/TOTALk''Hodnota celkového okna se čte dynamicky, takže funguje i pro 1M context window. Červeně se rozsvítí i překročení 200k tokenů+
-  * Barevné zvýraznění podle vytížení: zelená pod 70 %, žlutá od 70 %, červená od 90 %.+
  
 ===== Zapojení do konfigurace ===== ===== Zapojení do konfigurace =====
  
-V ''~/.claude/settings.json'' mám status line zapojený takto:+V ''~/.claude/settings.json'' jsou zapojené dva skripty:
  
 <code json> <code json>
 "statusLine": { "statusLine": {
   "type": "command",   "type": "command",
-  "command": "bash /home/ubuntu/.claude/statusline-command.sh"+  "command": "bash ~/.claude/statusline-command.sh" 
 +}, 
 +"subagentStatusLine":
 +  "type": "command", 
 +  "command": "bash ~/.claude/subagent-statusline.sh"
 } }
 </code> </code>
  
-Skript čte JSON ze standardního vstupu, parsuje ho přes ''jq''složí z něj jednu barevnou řádku.+Skripty čtou JSON ze standardního vstupu, parsují ho přes ''jq''vrací barevný výstup přes ANSI sekvence.
  
-===== Jak vypadá výstup =====+===== Hlavní status line =====
  
-Když Claude Code neposílá data o ''rate_limits'', výstup vypadá zhruba takto: +Hlavní ''statusLine'' je vázaná na top-level Claude Code session. Nepřepíná se podle aktivního subagenta a nedostává data o tom, který subagent zrovna běží. K tomu slouží samostatná ''subagentStatusLine''.
- +
-<code> +
-~/scratch │ Sonnet 4.6 | sid:<id> │ ctx:23% │ 92k/400k +
-</code>+
  
-Když jsou limity v JSONu k dispozici, řádka se rozšíří o 5h a 7d přehled:+Výstup hlavní status line vypadá zhruba takto:
  
 <code> <code>
-~/project-procesniaudit-website │ Sonnet 4.6 │ ctx:55% │ 5h:4% ↺ 00:50 │ 7d:45% ↺ Po 08:00 │ 220k/400k+~/project │ Sonnet 4.6 | sid:<id> │ ctx:55% │ 5h:4% ↺ 00:50 │ 7d:45% ↺ Po 08:00 │ 220k/400k
 </code> </code>
  
Řádek 49: Řádek 47:
   * token counter ''XYZk/TOTALk'' → červeně a tučně při překročení 200k, jinak dim   * token counter ''XYZk/TOTALk'' → červeně a tučně při překročení 200k, jinak dim
  
-===== Celý skript =====+==== Skript ''statusline-command.sh'' ====
  
 <code bash> <code bash>
Řádek 124: Řádek 122:
   fi   fi
 } }
- 
  
 # ── 3) context used ──────────────────────────────────────────────────────────── # ── 3) context used ────────────────────────────────────────────────────────────
Řádek 192: Řádek 189:
  
 printf "%b\n" "$out" printf "%b\n" "$out"
 +</code>
 +
 +===== Subagent status line =====
 +
 +''subagentStatusLine'' dostává pole ''tasks'' a pro každý task musí vypsat jeden JSON řádek ve tvaru:
 +
 +<code json>
 +{"id":"<task id>","content":"<řádek s ANSI>"}
 +</code>
 +
 +V reálných datech task obsahuje zejména pole ''cwd'', ''description'', ''id'', ''label'', ''startTime'', ''status'', ''tokenCount'', ''tokenSamples'', ''type'', ''model'' a ''contextWindowSize''. Pole ''type'' je jen obecná hodnota typu ''local_agent'', nikoli název použitého subagenta. Pole ''model'' obsahuje skutečně použitý model, například ''claude-haiku-4-5-20251001''.
 +
 +Pro název subagenta se používá konvence v ''description'':
 +
 +<code>
 +<subagent_type> · <short description>
 +</code>
 +
 +Příklad:
 +
 +<code>
 +elite-prompt-architect · rešerše pricing
 +</code>
 +
 +Skript model přečte z ''model'' a popisek rozparsuje. Výsledek vypadá například takto:
 +
 +<code>
 +elite-prompt-architect │ haiku │ rešerše pricing │ Reading subagent-statusline.sh │ running │ ctx:2% │ tok:8.1k ▁▄█ 579/s │ 14s
 +</code>
 +
 +==== Pravidlo ve skillu ''calling-subagents'' ====
 +
 +Pro pojmenování dispatchů v Claude Code je tato konvence uložená ve skillu ''calling-subagents''. ''description'' přenáší identitu subagenta, protože ''subagent_type'' není samostatnou součástí dat pro panel. Model se do ''description'' nepíše: Claude Code předává autoritativní hodnotu v poli ''model''.
 +
 +<code markdown>
 +## `description` naming convention — Claude Code only
 +
 +In **Claude Code**, format every dispatch `description` as:
 +
 +```
 +<subagent_type> · <short description>
 +```
 +
 +Example: `elite-prompt-architect · rešerše pricing`
 +
 +Why this exact shape: the task data behind the subagent status-line panel exposes
 +`model`, `status`, `tokenCount` and timings on its own, but it does **not** expose
 +`subagent_type` — `type` is just the coarse category `local_agent`. So the agent's
 +identity reaches the panel only through `description`. That visibility matters most
 +exactly when several subagents run in parallel and you need to tell them apart at a
 +glance.
 +
 +- Separator is a spaced middot ` · ` — the status line splits the label on it.
 +- The panel's `label` field is **not** the dispatch label. Claude Code computes it as
 +  `progress.summary || description`, and for `local_agent` it fills `progress.summary`
 +  every 30 s with an LLM-generated activity line ("Reading runAgent.ts"). A status-line
 +  script must therefore read identity from `description` and treat `label` as live
 +  activity only — never the other way round.
 +- **Never write the model into `description`.** Claude Code sends the real model in
 +  the task's `model` field and the status line renders it as a colored chip itself.
 +  Writing it by hand is redundant, and when the `model` param is omitted there is
 +  nothing truthful to write — placeholders like `session` or `inherit` used to leak
 +  into the visible label.
 +- Keep `<short description>` genuinely short — the panel truncates to terminal width.
 +
 +Legacy `<subagent_type> · <model> · <description>` labels still render correctly:
 +the status line detects a model-shaped middle segment and drops it in favour of the
 +real `model` field. No need to rewrite old agent definitions, but write new
 +dispatches in the two-part form.
 +
 +This is purely a Claude Code convenience: it relies on the `subagentStatusLine`
 +setting parsing the ` · ` format. **OpenCode** has no such status line, so use a
 +plain, natural `description` there — do **not** force this format.
 +</code>
 +
 +==== Skript ''subagent-statusline.sh'' ====
 +
 +<code bash>
 +#!/usr/bin/env bash
 +# Claude Code subagent status line
 +# Renders one custom row per active subagent in the agent panel.
 +# Row: <type> │ <status> │ tok:<n> <sparkline> <rate> │ <elapsed> │ [cwd] │ <label|desc>
 +# Input (stdin): { cwd, columns, tasks:[ {id,name,type,status,description,label,startTime,tokenCount,tokenSamples,cwd}, ... ] }
 +# Output (stdout): one JSON line per task -> {"id":"<id>","content":"<row w/ ANSI>"}
 +
 +input=$(cat)
 +
 +# ── DEBUG (volitelne): SUBAGENT_SL_DEBUG_DIR=/nejaka/slozka -> dump stdin ──────
 +if [ -n "$SUBAGENT_SL_DEBUG_DIR" ] && [ -d "$SUBAGENT_SL_DEBUG_DIR" ]; then
 +  printf '%s\n' "$input" >> "$SUBAGENT_SL_DEBUG_DIR/raw.jsonl" 2>/dev/null
 +fi
 +
 +# ── ANSI ────────────────────────────────────────────────────────────────────────
 +RESET='\033[0m'; BOLD='\033[1m'; DIM='\033[2m'
 +RED='\033[31m'; YELLOW='\033[33m'; GREEN='\033[32m'; CYAN='\033[36m'; MAGENTA='\033[35m'; WHITE='\033[37m'; BLUE='\033[34m'
 +
 +now=$(date +%s)
 +main_cwd=$(echo "$input" | jq -r '.cwd // .workspace.current_dir // empty')
 +columns=$(echo "$input" | jq -r '.columns // 0')
 +US=$'\x1f'   # interní oddělovač pro rozklad "agent · model · popis"
 +
 +status_color() {
 +  case "$1" in
 +    running|in_progress|active) echo "$CYAN" ;;
 +    completed|done|success)     echo "$GREEN" ;;
 +    failed|error)               echo "$RED" ;;
 +    pending|queued|waiting)     echo "$YELLOW" ;;
 +    *)                          echo "$WHITE" ;;
 +  esac
 +}
 +
 +# Rozpozná model v prefixu popisku (konvence "model · popis" / "model | popis").
 +# Vrací barvu, nebo prázdno když prefix není známý model.
 +model_color() {
 +  case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in
 +    haiku*)  echo "$GREEN"   ;;
 +    sonnet*) echo "$CYAN"    ;;
 +    opus*)   echo "$MAGENTA" ;;
 +    fable*)  echo "$BLUE"    ;;
 +    *)       echo ""         ;;
 +  esac
 +}
 +
 +# Model z pole `.model` (např. "claude-haiku-4-5-20251001") -> rodina "haiku".
 +# Toto je autoritativní zdroj; konvence v description je jen fallback.
 +model_family() {
 +  case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in
 +    *haiku*)  echo "haiku"  ;;
 +    *sonnet*) echo "sonnet" ;;
 +    *opus*)   echo "opus"   ;;
 +    *fable*)  echo "fable"  ;;
 +    *)        echo ""       ;;
 +  esac
 +}
 +
 +# Segment v description, který jen duplikuje/zastupuje model → zahodit,
 +# ať neteče do popisu ("session", "inherit", "dedeno" = model param vynechán).
 +is_model_slot() {
 +  [ -n "$(model_color "$1")" ] && return 0
 +  case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in
 +    session|inherit|dedeno|zdeděno|zdedeno|default) return 0 ;;
 +    *) return 1 ;;
 +  esac
 +}
 +
 +# elapsed seconds from startTime (epoch-s, epoch-ms, or ISO-8601) -> "2m10s"
 +elapsed_str() {
 +  local v="$1" start=""
 +  { [ -z "$v" ] || [ "$v" = "null" ]; } && return
 +  if [[ "$v" =~ ^[0-9]+$ ]]; then
 +    if [ "${#v}" -ge 13 ]; then start=$(( v / 1000 )); else start="$v"; fi
 +  else
 +    start=$(date -d "$v" +%s 2>/dev/null) || return
 +  fi
 +  local d=$(( now - start )); [ "$d" -lt 0 ] && d=0
 +  if   [ "$d" -ge 3600 ]; then printf "%dh%dm" $(( d/3600 )) $(( (d%3600)/60 ))
 +  elif [ "$d" -ge 60 ];   then printf "%dm%02ds" $(( d/60 )) $(( d%60 ))
 +  else printf "%ds" "$d"; fi
 +  return
 +}
 +elapsed_secs() {
 +  local v="$1" start=""
 +  { [ -z "$v" ] || [ "$v" = "null" ]; } && { echo 0; return; }
 +  if [[ "$v" =~ ^[0-9]+$ ]]; then
 +    if [ "${#v}" -ge 13 ]; then start=$(( v / 1000 )); else start="$v"; fi
 +  else
 +    start=$(date -d "$v" +%s 2>/dev/null) || { echo 0; return; }
 +  fi
 +  local d=$(( now - start )); [ "$d" -lt 0 ] && d=0; echo "$d"
 +}
 +
 +num_fmt() { # 39731 -> 39.7k
 +  local t="$1"
 +  [ "$t" -ge 1000 ] 2>/dev/null && python3 -c "print(f'{$t/1000:.1f}k')" 2>/dev/null || echo "$t"
 +}
 +
 +# sparkline + rate from tokenSamples (defensive: čísla i objekty)
 +# stdout: "<sparkline>\t<rate_per_s or empty>"
 +spark_and_rate() {
 +  python3 - "$1" 2>/dev/null <<'PY'
 +import sys, json
 +raw = sys.argv[1] if len(sys.argv) > 1 else "[]"
 +try:
 +    d = json.loads(raw)
 +except Exception:
 +    print("\t"); sys.exit(0)
 +vals, times = [], []
 +def num(x):
 +    if isinstance(x,(int,float)): return float(x)
 +    if isinstance(x,dict):
 +        for k in ('tokens','tokenCount','count','value','v','y'):
 +            if isinstance(x.get(k),(int,float)): return float(x[k])
 +    return None
 +def tim(x):
 +    if isinstance(x,dict):
 +        for k in ('t','time','ts','timestamp','at'):
 +            if isinstance(x.get(k),(int,float)): return float(x[k])
 +    return None
 +if isinstance(d, list):
 +    for x in d:
 +        v = num(x)
 +        if v is not None:
 +            vals.append(v); times.append(tim(x))
 +spark = ""
 +if len(vals) >= 2:
 +    blocks = "▁▂▃▄▅▆▇█"
 +    w = vals[-14:]
 +    lo, hi = min(w), max(w); rng = (hi - lo) or 1
 +    spark = "".join(blocks[min(7, int(round((v-lo)/rng*7)))] for v in w)
 +rate = ""
 +if len(vals) >= 2 and all(t is not None for t in times) and (times[-1]-times[0]) > 0:
 +    dt = times[-1]-times[0]
 +    if dt > 10_000_000_000: dt = dt/1000.0   # ms guard
 +    r = (vals[-1]-vals[0])/dt
 +    if r > 0:
 +        rate = f"{r/1000:.1f}k/s" if r >= 1000 else f"{r:.0f}/s"
 +print(f"{spark}\t{rate}")
 +PY
 +}
 +
 +short_dir() {
 +  local d="$1"
 +  { [ -z "$d" ] || [ "$d" = "null" ]; } && return
 +  if [ "$d" = "$HOME" ]; then echo "~";
 +  elif [[ "$d" == "$HOME/"* ]]; then echo "~/${d#$HOME/}";
 +  else echo "$d"; fi
 +}
 +
 +# ── build one row per task ───────────────────────────────────────────────────────
 +echo "$input" | jq -c '.tasks[]?' | while read -r task; do
 +  id=$(echo "$task" | jq -r '.id // empty'); [ -z "$id" ] && continue
 +  # Identita agenta se čte VÝHRADNĚ z `description` (konvence
 +  # "<subagent_type> · <popis>"); `subagent_type` ve schématu není.
 +  # POZOR: `label` NENÍ štítek dispatche. Claude Code ho počítá jako
 +  # `progress.summary || description` a pro `type == "local_agent"` do
 +  # `progress.summary` průběžně (à 30 s) zapisuje LLM-generované shrnutí
 +  # aktuální činnosti ("Reading runAgent.ts"). Jakmile se první shrnutí
 +  # objeví, `label` přepíše description a jméno agenta by z něj zmizelo.
 +  # Proto: description = identita, label = živá činnost. Nikdy naopak.
 +  descr=$(echo "$task"   | jq -r '.description // ""')
 +  label=$(echo "$task"   | jq -r '.label // ""')
 +  name=$(echo "$task"    | jq -r '.name // ""')
 +  primary="$descr"; [ -z "$primary" ] && primary="$name"
 +  activity=""
 +  if [ -n "$label" ] && [ "$label" != "$descr" ] && [ "$label" != "$name" ]; then
 +    activity="$label"
 +  fi
 +  # Typy bez description (local_bash: label = příkaz) → label slouží jako štítek.
 +  [ -z "$primary" ] && { primary="$activity"; activity=""; }
 +  [ -z "$primary" ] && primary="agent"
 +  # `type` je hrubá kategorie ("local_agent"); ukázat jen když nese info.
 +  type=$(echo "$task"    | jq -r '.type // ""')
 +  status=$(echo "$task"  | jq -r '.status // ""')
 +  tokens=$(echo "$task"  | jq -r '.tokenCount // ""')
 +  start=$(echo "$task"   | jq -r '.startTime // ""')
 +  tcwd=$(echo "$task"    | jq -r '.cwd // ""')
 +  samples=$(echo "$task" | jq -c '.tokenSamples // []')
 +  rawmodel=$(echo "$task" | jq -r '.model // ""')
 +  ctxsize=$(echo "$task" | jq -r '.contextWindowSize // ""')
 +
 +  sc=$(status_color "$status")
 +
 +  # Model: primárně z pole `.model` (Claude Code ho posílá), teprve pak z konvence.
 +  _model=$(model_family "$rawmodel")
 +
 +  # Konvence "agent · popis" (historicky i "agent · model · popis"; oddělovač
 +  # " · " nebo " | "). Model-slot v popisku se zahodí, když model už známe.
 +  agentseg=""; modelseg=""
 +  _tmp="${primary// · /$US}"; _tmp="${_tmp// | /$US}"
 +  IFS="$US" read -ra _segs <<< "$_tmp"
 +  _agent=""; _popis=""
 +  _n=${#_segs[@]}
 +  if [ "$_n" -ge 2 ]; then
 +    _agent="${_segs[0]}"; _start=1
 +    # druhý díl je model-slot ("haiku", "session", "inherit"…) → přeskoč ho,
 +    # ale jen když víme model odjinud nebo je to skutečně platný model
 +    if is_model_slot "${_segs[1]}"; then
 +      [ -z "$_model" ] && _model=$(model_family "${_segs[1]}")
 +      _start=2
 +    fi
 +    for ((i=_start; i<_n; i++)); do
 +      _popis="${_popis:+$_popis · }${_segs[$i]}"
 +    done
 +  else
 +    _popis="$primary"
 +  fi
 +  # jednodílný popisek, který je sám o sobě model → ber jako model, ne jako agenta
 +  if [ "$_n" -eq 1 ] && [ -z "$_model" ] && [ -n "$(model_color "$primary")" ]; then
 +    _model=$(model_family "$primary"); _popis=""
 +  fi
 +  if [ -n "$_model" ]; then
 +    _mcol=$(model_color "$_model")
 +    [ -n "$_mcol" ] && modelseg=$(printf "%b%b%s%b" "$_mcol" "$BOLD" "$_model" "$RESET")
 +  fi
 +  [ -n "$_agent" ] && agentseg=$(printf "%b%s%b" "$BOLD" "$_agent" "$RESET")
 +  primary="$_popis"
 +
 +  # tokens: count + zaplneni okna + sparkline + rate
 +  # ctx: zaplneni kontextoveho okna subagenta. `tokenCount` je aktualni obsazeni
 +  # okna (ne kumulativni utrata), takze procento je primo pomer k `contextWindowSize`.
 +  # Format i barvy zamerne shodne s hlavni statusLine (ctx:55% / ctx:93%!).
 +  ctxseg=""; ctxpct=""
 +  if [ -n "$tokens" ] && [ "$tokens" != "null" ] \
 +     && [ -n "$ctxsize" ] && [ "$ctxsize" != "null" ] && [ "$ctxsize" -gt 0 ] 2>/dev/null; then
 +    ctxpct=$(( tokens * 100 / ctxsize ))
 +    if   [ "$ctxpct" -ge 90 ]; then ctxseg=$(printf "%b%bctx:%s%%!%b" "$RED" "$BOLD" "$ctxpct" "$RESET")
 +    elif [ "$ctxpct" -ge 70 ]; then ctxseg=$(printf "%bctx:%s%%%b" "$YELLOW" "$ctxpct" "$RESET")
 +    else ctxseg=$(printf "%bctx:%s%%%b" "$GREEN" "$ctxpct" "$RESET")
 +    fi
 +  fi
 +
 +  tokseg=""
 +  if [ -n "$tokens" ] && [ "$tokens" != "null" ]; then
 +    disp=$(num_fmt "$tokens")
 +    # Varovnou roli nese ctx segment; tok zustava neutralni absolutni cislo.
 +    # Bez `contextWindowSize` (starsi Claude Code) plati puvodni pevny prah.
 +    if [ -n "$ctxpct" ]; then tcol="$DIM"
 +    elif [ "$tokens" -ge 100000 ] 2>/dev/null; then tcol="${RED}${BOLD}"
 +    else tcol="$DIM"; fi
 +    IFS=$'\t' read -r spark rate < <(spark_and_rate "$samples")
 +    # fallback rate: průměr od startu, když samples nenesou čas
 +    if [ -z "$rate" ]; then
 +      es=$(elapsed_secs "$start")
 +      [ "$es" -gt 0 ] 2>/dev/null && rate=$(python3 -c "r=$tokens/$es; print(f'{r/1000:.1f}k/s' if r>=1000 else f'{r:.0f}/s')" 2>/dev/null)
 +    fi
 +    tokseg=$(printf "%btok:%s%b" "$tcol" "$disp" "$RESET")
 +    [ -n "$spark" ] && tokseg="$tokseg $(printf "%b%s%b" "$CYAN" "$spark" "$RESET")"
 +    [ -n "$rate" ]  && tokseg="$tokseg $(printf "%b%s%b" "$DIM" "$rate" "$RESET")"
 +  fi
 +
 +  el=$(elapsed_str "$start")
 +
 +  # cwd jen když se liší od hlavní session
 +  dirseg=""
 +  if [ -n "$tcwd" ] && [ "$tcwd" != "null" ] && [ "$tcwd" != "$main_cwd" ]; then
 +    dirseg=$(printf "%b%s%b" "$YELLOW" "$(short_dir "$tcwd")" "$RESET")
 +  fi
 +
 +  # ořez popisku a živé činnosti podle columns (heuristika: fixní část ~ 55
 +  # sloupců — status + ctx + tok/sparkline/rate + elapsed). Popis dispatche má
 +  # přednost (odlišuje paralelní agenty téhož typu), činnost bere zbytek.
 +  if [ "$columns" -gt 0 ] 2>/dev/null; then
 +    budget=$(( columns - 55 )); [ "$budget" -lt 12 ] && budget=12
 +    if [ -n "$activity" ]; then
 +      pbudget=$(( budget * 2 / 5 )); [ "$pbudget" -lt 10 ] && pbudget=10
 +    else
 +      pbudget="$budget"
 +    fi
 +    if [ -n "$primary" ] && [ "${#primary}" -gt "$pbudget" ]; then primary="${primary:0:$((pbudget-1))}…"; fi
 +    if [ -n "$activity" ]; then
 +      abudget=$(( budget - ${#primary} - 3 )); [ "$abudget" -lt 8 ] && abudget=8
 +      if [ "${#activity}" -gt "$abudget" ]; then activity="${activity:0:$((abudget-1))}…"; fi
 +    fi
 +  fi
 +  actseg=""
 +  [ -n "$activity" ] && actseg=$(printf "%b%s%b" "$WHITE" "$activity" "$RESET")
 +
 +  # type badge jen když není běžná lokální kategorie
 +  typeseg=""
 +  case "$type" in
 +    ""|local_agent|agent) : ;;
 +    *) typeseg=$(printf "%b%s%b" "$DIM" "$type" "$RESET") ;;
 +  esac
 +
 +  parts=()
 +  if [ -n "$agentseg" ]; then
 +    parts+=("$agentseg")
 +    [ -n "$modelseg" ] && parts+=("$modelseg")
 +    [ -n "$primary" ] && parts+=("$(printf "%b%s%b" "$DIM" "$primary" "$RESET")")
 +  else
 +    [ -n "$modelseg" ] && parts+=("$modelseg")
 +    parts+=("$(printf "%b%b%s%b" "$MAGENTA" "$BOLD" "$primary" "$RESET")")
 +  fi
 +  [ -n "$actseg" ] && parts+=("$actseg")
 +  [ -n "$status" ]  && parts+=("$(printf "%b%s%b" "$sc" "$status" "$RESET")")
 +  [ -n "$ctxseg" ]  && parts+=("$ctxseg")
 +  [ -n "$tokseg" ]  && parts+=("$tokseg")
 +  [ -n "$el" ]      && parts+=("$(printf "%b%s%b" "$DIM" "$el" "$RESET")")
 +  [ -n "$dirseg" ]  && parts+=("$dirseg")
 +  [ -n "$typeseg" ] && parts+=("$typeseg")
 +
 +  sep="$(printf "%b │ %b" "$DIM" "$RESET")"
 +  content=""
 +  for p in "${parts[@]}"; do
 +    [ -z "$content" ] && content="$p" || content="${content}${sep}${p}"
 +  done
 +
 +  content_bytes=$(printf "%b" "$content")
 +  jq -cn --arg id "$id" --arg content "$content_bytes" '{id:$id, content:$content}'
 +done
 </code> </code>
  
 ===== Poznámky k chování ===== ===== Poznámky k chování =====
  
-  * Pole ''5h'' a ''7d'' se zobrazí jen když Claude Code skutečně pošle ''rate_limits''. +  * Hlavní ''statusLine'' a ''subagentStatusLine'' jsou oddělené. Hlavní řádek zůstává pro top-level session, subagenti se zobrazují v agent panelu. 
-  * Funkce ''fmt_reset_short()'' ''fmt_reset_long()'' zvládnou jak unix epoch, tak ISO-8601 string+  * ''subagentStatusLine'' dostává skutečný model v poli ''model'', ale nedostává ''subagent_type''Proto ''description'' používá dvoudílný tvar ''<subagent_type> · <short description>''
-  * Pro cwd se primárně čte ''.workspace.project_dir'' — pole, které Claude Code nastavuje na root projektu (kde byl spuštěn) a nemění se v průběhu session, i když shell přejde do podadresáře. Pole ''.workspace.current_dir'' ''.cwd'' jsou jen fallback. +  * V aktuálním Claude Code je ''label'' pro ''local_agent'' živá činnost, ne identita dispatche: odpovídá ''progress.summary || description''''AgentSummary'' ibližně každých 30 sekund zapisuje do ''progress.summary'' krátké LLM-generované shrnutí činnostiIdentita se proto vždy čte z ''description'', zatímco ''label'' se vypisuje jen jako samostatný sloupec s činností. 
-  * Procento využití context window se čte ímo z ''context_window.used_percentage'' — předpočítané pole, které Claude Code posílá od verze 2.1.132Pokrývá vstupní tokeny etně cache: ''used_percentage'' = (''input_tokens'' ''cache_creation_input_tokens'' ''cache_read_input_tokens'') / ''context_window_size''. Výstupní tokeny do procenta nezahrnuje, ale ani do ''XYZk'' v token counteru (tam se čte ''total_input_tokens'', které je součtem stejných tří složek). +  * Starší tříčlenné popisky ''<subagent_type> · <model> · <description>'' zůstávají podporované. Prostřední modelový segment se ignoruje ve prospěch hodnoty z ''model''; nově se ale zapisuje dvoudílný tvar. 
-  * ''total_input_tokens'' zahrnuje všechny vstupní tokeny včetně cache a od v2.1.132 reprezentuje aktuální stav context windownikoli kumulativní součet přes celou session+  * ''contextWindowSize'' spolu s ''tokenCount'' určuje ''ctx'' — procento obsazení context window subagenta. Pod 70 % je zelené, od 70 % žluté a od 90 % červené. ''tokenCount'' je aktuální obsazení oknane kumulativní spotřeba
-  * Skript záměrně nepoužívá příznak ''exceeds_200k_tokens'' — ten vychází z tokenů aktuálního API volání (input + output + cache) a má pevnou hranici 200k bez ohledu na skutečnou velikost oknaMísto toho skript ukazuje aktuální stav v segmentu ''XYZk/TOTALk''+  * ''tokenSamples'' se používá pro sparkline trendu tokenů. Když vzorky neobsahují čas, rychlost se dopočítá jako průměr od ''startTime''
-  * Když některé pole v JSONu chybískript se nerozbije a prostě ho přeskočí+  * ''columns'' se používá pro ořez popiskuaby se řádky v úzkém terminálu nelámaly
-  * Pořadí polí je pevné: ''cwd'' → ''model + sid'' → ''ctx'' → ''5h'' → ''7d'' → ''XYZk/TOTALk''.+  * ''cwd'' se zobrazí jen tehdy, když se liší od hlavní session. 
 +  * Pro diagnostiku lze nastavit proměnnou prostředí ''SUBAGENT_SL_DEBUG_DIR'' na existující adresář. Skript do něj zapíše zachycené JSON vstupy do ''raw.jsonl''
 +  * Skripty vyžadují ''jq''''python3'' a běžné unixové ''date''.
  
 ===== Zdroje ===== ===== Zdroje =====
  
   * [[https://code.claude.com/docs/en/statusline|Claude Code – Customize your status line (oficiální dokumentace)]]   * [[https://code.claude.com/docs/en/statusline|Claude Code – Customize your status line (oficiální dokumentace)]]
  • ai/platformy/claude-code/statusline.1778269505.txt.gz
  • Poslední úprava: 08.05.2026 21:45
  • autor: Petr Nosek