Vytvořeno: 11.04.2026 | Aktualizováno: 09.08.2026 23:18
Claude Code umí podle 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.
model, které Claude Code předává do subagentStatusLine. Název subagent_type v datech samostatně není; pro přehled se proto zapisuje do description.
V ~/.claude/settings.json jsou zapojené dva skripty:
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline-command.sh"
},
"subagentStatusLine": {
"type": "command",
"command": "bash ~/.claude/subagent-statusline.sh"
}
Skripty čtou JSON ze standardního vstupu, parsují ho přes jq a vrací barevný výstup přes ANSI sekvence.
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.
Výstup hlavní status line vypadá zhruba takto:
~/project │ Sonnet 4.6 | sid:<id> │ ctx:55% │ 5h:4% ↺ 00:50 │ 7d:45% ↺ Po 08:00 │ 220k/400k
Barvy jsou rozdělené takto:
ctx, 5h a 7d → zelená pod 70 %, žlutá od 70 %, červená od 90 %XYZk/TOTALk → červeně a tučně při překročení 200k, jinak dim#!/usr/bin/env bash # Claude Code status line # Order: cwd | model | context used | 5h limit | 7d limit input=$(cat) # ── helpers ──────────────────────────────────────────────────────────────────── 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' # ── 1) cwd ───────────────────────────────────────────────────────────────────── cwd=$(echo "$input" | jq -r '.workspace.project_dir // .workspace.current_dir // .cwd // ""') # Show path relative to home dir home_dir="$HOME" if [[ "$cwd" == "$home_dir" ]]; then short_cwd="~" elif [[ "$cwd" == "$home_dir/"* ]]; then short_cwd="~/${cwd#$home_dir/}" else short_cwd="$cwd" fi [ "$short_cwd" = "/" ] && short_cwd="/" # ── 2) model ─────────────────────────────────────────────────────────────────── model_name=$(echo "$input" | jq -r '.model.display_name // .model.id // ""') session_id=$(echo "$input" | jq -r '.session_id // .conversation_id // empty') # ── rate limit helpers ───────────────────────────────────────────────────────── five_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty') five_rst=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty') week_pct=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty') week_rst=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty') fmt_reset_short() { local v="$1" [ -z "$v" ] && return # Try as epoch first, then as ISO-8601 string if [[ "$v" =~ ^[0-9]+$ ]]; then date -d "@$v" +%H:%M 2>/dev/null || date -r "$v" +%H:%M 2>/dev/null || echo "?" else date -d "$v" +%H:%M 2>/dev/null || echo "?" fi } fmt_reset_long() { local v="$1" [ -z "$v" ] && return if [[ "$v" =~ ^[0-9]+$ ]]; then date -d "@$v" +"%a %H:%M" 2>/dev/null || date -r "$v" +"%a %H:%M" 2>/dev/null || echo "?" else date -d "$v" +"%a %H:%M" 2>/dev/null || echo "?" fi } # Choose colour based on used % pct_color_used() { local used="$1" [ -z "$used" ] && echo "$WHITE" && return local u u=$(printf "%.0f" "$used") if [ "$u" -ge 90 ]; then echo "$RED" elif [ "$u" -ge 70 ]; then echo "$YELLOW" else echo "$GREEN" fi } # ── 3) context used ──────────────────────────────────────────────────────────── ctx_used_tokens=$(echo "$input" | jq -r '.context_window.total_input_tokens // empty') ctx_window_size=$(echo "$input" | jq -r '.context_window.context_window_size // empty') ctx_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty') ctx_str="" if [ -n "$ctx_pct" ]; then ctx_int=$(printf "%.0f" "$ctx_pct") if [ "$ctx_int" -ge 90 ]; then ctx_str="$(printf "${RED}${BOLD}ctx:%s%%!${RESET}" "$ctx_int")" elif [ "$ctx_int" -ge 70 ]; then ctx_str="$(printf "${YELLOW}ctx:%s%%${RESET}" "$ctx_int")" else ctx_str="$(printf "${GREEN}ctx:%s%%${RESET}" "$ctx_int")" fi fi # ── assemble line ────────────────────────────────────────────────────────────── parts=() # 1) cwd parts+=("$(printf "${CYAN}${BOLD}%s${RESET}" "$short_cwd")") # 2) model + session id if [ -n "$model_name" ] || [ -n "$session_id" ]; then parts+=("$(printf "${MAGENTA}%s${RESET}" "$model_name")${session_id:+ $(printf "${DIM}| sid:%s${RESET}" "$session_id")}") fi # 3) context used (always shown when data available) [ -n "$ctx_str" ] && parts+=("$ctx_str") # 4) 5h rate limit (only when data is available) if [ -n "$five_pct" ]; then five_int=$(printf "%.0f" "$five_pct") col=$(pct_color_used "$five_pct") rst=$(fmt_reset_short "$five_rst") parts+=("$(printf "${col}5h:%s%%%s${RESET}" "$five_int" "${rst:+ ↺ $rst}")") fi # 5) 7d rate limit (only when data is available) if [ -n "$week_pct" ]; then week_int=$(printf "%.0f" "$week_pct") col=$(pct_color_used "$week_pct") rst=$(fmt_reset_long "$week_rst") parts+=("$(printf "${col}7d:%s%%%s${RESET}" "$week_int" "${rst:+ ↺ $rst}")") fi # 6) token counter — červeně od 200k if [ -n "$ctx_used_tokens" ] && [ -n "$ctx_window_size" ] && [ "$ctx_window_size" -gt 0 ]; then ctx_used_k=$(python3 -c "print(round($ctx_used_tokens / 1000))") ctx_total_k=$(python3 -c "print(round($ctx_window_size / 1000))") if [ "$ctx_used_tokens" -gt 200000 ]; then parts+=("$(printf "${RED}${BOLD}%sk/%sk${RESET}" "$ctx_used_k" "$ctx_total_k")") else parts+=("$(printf "${DIM}%sk/%sk${RESET}" "$ctx_used_k" "$ctx_total_k")") fi fi # ── print ────────────────────────────────────────────────────────────────────── # Join with separator " │ " sep="$(printf "${DIM} │ ${RESET}")" out="" for p in "${parts[@]}"; do [ -z "$out" ] && out="$p" || out="${out}${sep}${p}" done printf "%b\n" "$out"
subagentStatusLine dostává pole tasks a pro každý task musí vypsat jeden JSON řádek ve tvaru:
{"id":"<task id>","content":"<řádek s ANSI>"}
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:
<subagent_type> · <short description>
Příklad:
elite-prompt-architect · rešerše pricing
Skript model přečte z model a popisek rozparsuje. Výsledek vypadá například takto:
elite-prompt-architect │ haiku │ rešerše pricing │ Reading subagent-statusline.sh │ running │ ctx:2% │ tok:8.1k ▁▄█ 579/s │ 14s
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.
## `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.
#!/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
statusLine a subagentStatusLine jsou oddělené. Hlavní řádek zůstává pro top-level session, subagenti se zobrazují v agent panelu.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>.label pro local_agent živá činnost, ne identita dispatche: odpovídá progress.summary || description. AgentSummary přibližně každých 30 sekund zapisuje do progress.summary krátké LLM-generované shrnutí činnosti. Identita se proto vždy čte z description, zatímco label se vypisuje jen jako samostatný sloupec s činností.<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.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í okna, ne kumulativní spotřeba.tokenSamples se používá pro sparkline trendu tokenů. Když vzorky neobsahují čas, rychlost se dopočítá jako průměr od startTime.columns se používá pro ořez popisku, aby se řádky v úzkém terminálu nelámaly.cwd se zobrazí jen tehdy, když se liší od hlavní session.SUBAGENT_SL_DEBUG_DIR na existující adresář. Skript do něj zapíše zachycené JSON vstupy do raw.jsonl.jq, python3 a běžné unixové date.