New: watch your coding agents work, step by step, on a live board. Try the demo, no account

Docs / Recipes / How-to

Show the current task in the Claude Code status line

Claude Code runs a command of your choice for its status line. This script asks Taskhold for the task in progress and prints one line: title, a ten-block bar, steps done and the step that's running. It caches the answer for 10 seconds.

Prefer one command with no script to maintain? The Taskhold CLI sets up the same line with taskhold-mcp statusline --install. This page is for building it into a status line of your own.

Before you begin

  • curl and jq on your PATH.
  • A Taskhold API key from Settings, saved where the script can read it:
mkdir -p ~/.config/taskhold && printf '%s' 'API_KEY' > ~/.config/taskhold/key && chmod 600 ~/.config/taskhold/key
Replace API_KEY with your atd_sk_ key, or export TASKHOLD_API_KEY instead.

Add the script

Save this as ~/.claude/taskhold-statusline.sh and make it executable (chmod +x):

#!/bin/bash
# ~/.claude/taskhold-statusline.sh: the task in progress, its bar and the running step.
# Needs curl and jq. Key from TASKHOLD_API_KEY or ~/.config/taskhold/key.
cat > /dev/null  # Claude Code sends session JSON on stdin; this script doesn't need it
key=${TASKHOLD_API_KEY:-$(cat ~/.config/taskhold/key 2>/dev/null)}
base=${TASKHOLD_API_URL:-https://taskhold.com/api}
cache="${TMPDIR:-/tmp}/taskhold-statusline.txt"
now=$(date +%s)
if [ -f "$cache" ]; then
  read -r stamp < "$cache"
  if [ $((now - stamp)) -lt 10 ]; then tail -n +2 "$cache"; exit 0; fi
fi
line=$(curl -s --max-time 2 "$base/tasks/current" -H "Authorization: Bearer $key" | jq -r '
  .task // empty
  | (.overall_progress // 0) as $p
  | (($p / 10) | floor) as $f
  | (([range(0; $f)] | map("█") | join("")) + ([range($f; 10)] | map("░") | join(""))) as $bar
  | (((.subtasks // []) | map(select(.status == "in_progress")) | .[0].title) // .progress_message // "") as $now
  | "\(.title)  \($bar) \($p)%"
    + (if (.subtask_counts.total // 0) > 0 then "  \(.subtask_counts.done)/\(.subtask_counts.total) steps" else "" end)
    + (if $now != "" then "  > \($now)" else "" end)' 2>/dev/null)
line=${line:-No task in progress}
printf '%s\n%s\n' "$now" "$line" > "$cache"
echo "$line"

Then point Claude Code at it in ~/.claude/settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/taskhold-statusline.sh",
    "refreshInterval": 10
  }
}
refreshInterval keeps the line current while the session is idle and another agent is working.

What you'll see

Deploy v2.4 to staging  ███░░░░░░░ 33%  1/3 steps  > Run migrations

With nothing in progress the line reads "No task in progress". To check the script by hand, run it with echo '{}' piped in.

Read next

Updated 2026-10-26 · Markdown for agents · Questions: hello@greatwork.company