SSD Nodes Learn 🎉 VPS $4.99/माह से
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-03

VPS पर Claude Code statusline कैसे सेट करें

statusLine script का stdout prompt के नीचे दिखाता है। hostname, directory, git branch और model जोड़कर सही server पहचानें और गलत SSH session में काम करने से बचें।

Claude Code statusline क्या दिखाती है

Claude Code statusline prompt के नीचे एक पंक्ति होती है, जो आपके लिखे script का output दिखाती है। आप settings.json में statusLine block जोड़कर उसे किसी command से जोड़ते हैं। Claude Code उस command को चलाता है, session state को JSON के रूप में standard input पर भेजता है, और command के standard output पर लिखे गए text को दिखाता है।

यही पूरा contract है। आपका script stdin से JSON पढ़ता है और stdout पर text लिखता है। यह आपके machine पर चलता है और इसके output का कुछ भी model को नहीं भेजा जाता, इसलिए इसके लिए कोई token खर्च नहीं होता।

एक project वाले laptop पर यह केवल सजावटी जानकारी है। तीन servers पर यह safety rail का काम करती है। हर terminal में Claude Code session एक जैसा दिखता है, इसलिए बिना labels वाली चार SSH windows में migration का गलत box पर चल जाना आसान है। Hostname से शुरू होने वाली statusline इस तरह की गलती को रोकती है।

settings.json में statusLine setting कहाँ रहती है

इसे ~/.claude/settings.json पर अपनी user settings में रखें। यह उस मशीन के हर project पर लागू होती है। Repository के अंदर .claude/settings.json पर दी गई project settings भी काम करती हैं और उस directory के लिए प्राथमिकता रखती हैं।

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}

type हमेशा "command" होता है। command value shell के माध्यम से चलती है, इसलिए यह script path या साधारण command हो सकती है। कोई script लिखने से पहले यह सुनिश्चित करें कि wiring काम कर रही है:

{
  "statusLine": {
    "type": "command",
    "command": "hostname -s"
  }
}

Claude Code शुरू करें और एक message भेजें। अब prompt के नीचे की bar में server का short hostname दिखेगा। यदि यह खाली रहती है, तो समस्या setting या trust dialog में है, आपकी script में नहीं। नीचे दिया गया "statusline खाली क्यों रहती है" पढ़ें।

August 2026 तक तीन optional keys उपलब्ध हैं। padding characters में horizontal spacing जोड़ता है और इसका default 0 है। refreshInterval सामान्य triggers के अतिरिक्त command को हर N seconds पर फिर से चलाता है। इसका minimum 1 है। इसका उपयोग केवल तब करें जब line में clock या session के idle रहने के दौरान बदलने वाली कोई जानकारी दिखाई जाती हो। hideVimModeIndicator अंतर्निहित -- INSERT -- text को छिपाता है, जब आपकी अपनी script vim mode पहले से render करती हो।

statusline script को कौन-सा data मिलता है?

इस पेज सहित कहीं भी पढ़ी गई field list पर भरोसा न करें। आपके version द्वारा भेजे जाने वाले वास्तविक object को capture करें। ऐसी अस्थायी script लिखें, जो stdin को किसी file में save करे:

cat > ~/.claude/statusline-capture.sh <<'EOF'
#!/bin/bash
cat > /tmp/statusline-input.json
echo "captured"
EOF
chmod +x ~/.claude/statusline-capture.sh

statusLine.command को उस file पर point करें, session शुरू करें और एक message भेजें। bar captured को पढ़ता है। अब देखें कि क्या प्राप्त हुआ:

jq . /tmp/statusline-input.json

अब आपके build के लिए exact structure उपलब्ध है। किसी update से कुछ बदलने पर आप इसे फिर से चला सकते हैं।

August 2026 में documented stable हिस्से flat keys के बजाय nested objects हैं। model में id और display_name होते हैं। workspace में current_dir और project_dir होते हैं: current_dir बताता है कि session अभी कहाँ है, project_dir बताता है कि उसे कहाँ launch किया गया था, और working directory session के दौरान बदलने पर दोनों अलग हो जाते हैं। Top-level cwd में workspace.current_dir के समान value होती है। context_window में token counts और पहले से calculated used_percentage होता है। cost में total_cost_usd और duration counters होते हैं। session_id पूरे session के दौरान स्थिर रहता है और sessions के बीच unique होता है। बाद में caching के लिए यह महत्वपूर्ण है।

Schema में बदलाव के बाद भी script को काम करते रखने के लिए ये 3 rules अपनाएँ।

कुछ keys मौजूद नहीं होतीं, null नहीं होतीं। vim, agent, pr, worktree और effort केवल तब दिखाई देती हैं, जब संबंधित feature active हो। vim mode बंद होने पर .vim.mode को jq -r से पढ़ने पर literal string null print होती है, और आपकी bar reader को null दिखाती है। हर selector के अंत में // empty जोड़ें, ताकि missing key पर कुछ भी print न हो।

कुछ values शुरुआत में null होती हैं। पहली API response से पहले context_window.used_percentage और context_window.current_usage null होते हैं। /compact के बाद current_usage फिर null हो जाता है, जब तक अगली call उसे दोबारा populate नहीं करती। इसलिए bar पर context percentage दिखाने के लिए // 0 आवश्यक है। अन्यथा हर session के शुरुआती seconds में यह null पढ़ेगा। उस number को bar पर रखने से पहले यह समझना उपयोगी है कि context window वास्तव में कैसे भरती है

git branch JSON में नहीं होती। कोई भी field इसे report नहीं करती। आपकी bar पर दिखाई देने वाली branch आपकी script द्वारा स्वयं git चलाने से आती है।

टूटने के बजाय fallback देने वाली statusline script

यह copy-paste करने योग्य version है। यह hostname, working directory, git branch और model name दिखाता है। प्रत्येक field के लिए fallback है, इसलिए खाली JSON object होने पर भी उपयोगी line बनती है।

#!/bin/bash
# ~/.claude/statusline.sh
input=$(cat)

# Read one field. Prints nothing when the key is missing or null.
field() { printf '%s' "$input" | jq -r "$1 // empty" 2>/dev/null; }

HOST=$(hostname -s 2>/dev/null)
[ -z "$HOST" ] && HOST="host"

DIR=$(field '.workspace.current_dir')
[ -z "$DIR" ] && DIR=$(field '.cwd')
[ -z "$DIR" ] && DIR="$PWD"

MODEL=$(field '.model.display_name')
[ -z "$MODEL" ] && MODEL="claude"

SHORT="$DIR"
if [ -n "$HOME" ]; then
  case "$DIR" in
    "$HOME") SHORT="~" ;;
    "$HOME"/*) SHORT="~/${DIR#"$HOME"/}" ;;
  esac
fi

BRANCH=""
if git -C "$DIR" rev-parse --git-dir >/dev/null 2>&1; then
  BRANCH=$(git -C "$DIR" branch --show-current 2>/dev/null)
  [ -z "$BRANCH" ] && BRANCH="detached"
fi

CYAN=$'\033[36m'
YELLOW=$'\033[33m'
DIM=$'\033[2m'
RESET=$'\033[0m'

LINE="${CYAN}${HOST}${RESET} ${SHORT}"
[ -n "$BRANCH" ] && LINE="${LINE} ${YELLOW}${BRANCH}${RESET}"
LINE="${LINE} ${DIM}${MODEL}${RESET}"

printf '%s\n' "$LINE"

हर read field के माध्यम से होती है। यह // empty जोड़ता है, इसलिए renamed या removed key empty string देती है और अगली line default उपलब्ध कराती है। Directory के लिए क्रमशः workspace.current_dir, cwd और $PWD fallback हैं। Branch bare git के बजाय git -C "$DIR" से मिलती है, इसलिए branch हमेशा उसी directory से संबंधित रहती है जिसे bar दिखा रहा है।

इसे save करें, फिर executable बनाएं:

chmod +x ~/.claude/statusline.sh

Execute bit वैकल्पिक नहीं है। Claude Code command को shell के माध्यम से चलाता है, इसलिए +x के बिना script Permission denied के साथ fail होती है, कोई stdout नहीं देती और row बिना किसी visible error के blank रहती है।

jq command line पर JSON parse करता है और fresh Ubuntu server पर installed नहीं होता:

sudo apt update && sudo apt install -y jq

फिर setting को script पर point करें और ऊपर दिए गए पहले settings.json block का उपयोग करें।

Script पर भरोसा करने से पहले उसका परीक्षण करें

इसे हाथ से दो बार चलाएँ। पहली बार सामान्य session object के साथ:

echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/srv/api"},"session_id":"t1"}' | ~/.claude/statusline.sh

आपको hostname, फिर /srv/api और फिर Opus मिलता है। कोई branch दिखाई नहीं देती, क्योंकि आपकी machine पर /srv/api शायद git repository नहीं है।

दूसरा degradation test चलाएँ। लोग अक्सर यही test छोड़ देते हैं:

echo '{}' | ~/.claude/statusline.sh

Schema change आपको जो सबसे खराब स्थिति दे सकता है, वह खाली object है। Line फिर भी hostname, $PWD से current directory और model name की जगह claude शब्द print करती है। कुछ crash नहीं होता और null भी print नहीं होता। जो script यह test पास कर लेती है, वह किसी field का नाम बदले जाने के बाद भी काम करती है, क्योंकि आपकी script के लिए renamed field और missing field एक ही घटना हैं।

आपको क्या दिखाई देना चाहिए

statusline अपने अलग row में built-in footer badges के ऊपर render होती है और उन्हें replace नहीं करती। सही setup में यह एक row होती है: cyan रंग में short hostname, फिर working directory जिसमें आपकी home directory को ~ से संक्षिप्त किया गया है, फिर directory के git repository होने पर yellow रंग में branch name, और अंत में dimmed model name। चारों हिस्सों के रंगों के साथ यह web-01 ~/api main Opus के लगभग समान दिखाई देनी चाहिए।

Session शुरू होने पर, resume सहित, नया assistant message आने पर, /compact पूरा होने के बाद, permission mode बदलने पर, vim mode toggle होने पर और यदि आपने interval सेट किया है तो refreshInterval tick पर row आपकी script फिर चलाती है। Updates को 300 ms तक debounce किया जाता है, इसलिए बदलावों की तेज़ श्रृंखला में script केवल एक बार चलती है। Autocomplete, help menu और permission prompts के दौरान bar छिप जाती है और फिर दिखाई देती है।

hostname पहले क्यों होना चाहिए

जब आप एक से अधिक servers पर agents चलाते हैं, तो terminal ही यह बताता है कि आप कहाँ हैं, और terminals गलत जानकारी दे सकते हैं। tmux pane के भीतर से दूसरा ssh connection खोलने पर window title अक्सर पुराना नाम ही दिखाता है, क्योंकि title उस shell ने set किया होता है जिसे उसके स्थानांतरण का पता ही नहीं चला। VPS पर detached tmux session में Claude Code चलाकर एक दिन बाद फिर attach करें, तो screen पर build server और production box के बीच अंतर बताने वाली कोई चीज़ नहीं रहती।

Statusline अलग होती है, क्योंकि इसे Claude Code स्वयं, प्रत्येक session के लिए, उस session में मौजूद data से render करता है। यह गलत pane से inherit नहीं हो सकती और न ही ऐसे shell prompt के कारण stale रह सकती है जो refresh नहीं हुआ। इसमें वही box दिखता है जिस पर agent files लिख रहा है।

हर server को अपना colour दें, ताकि पढ़ने से पहले ही आप उसे पहचान सकें। LINE= assignment के ऊपर ये दो lines जोड़ें:

CODE=$(printf '%s' "$HOST" | cksum | cut -d' ' -f1)
HOST_COLOR=$(printf '\033[%dm' "$((31 + CODE % 6))")

इसके बाद ${CYAN} की जगह ${HOST_COLOR} का उपयोग करें। cksum hostname का checksum print करता है, इसलिए कोई नाम हमेशा 31 से 36 की range में उसी colour पर map होता है। यह range red से cyan तक होती है। यही script हर box पर copy करें, और हर box अपना label स्वयं दिखाएगा।

Directory को शामिल करने का कारण भी यही है। /srv/api और /srv/api-staging किसी ssh command में केवल एक keystroke की दूरी पर होते हैं, लेकिन उनके प्रभाव में पूरी incident का अंतर हो सकता है। Model और branch वे अन्य दो fields हैं जिनके लिए जगह रखना उचित है। Model बताता है कि आपने कौन-सा session resume किया है, और branch बताती है कि agent main पर commit करने वाला है या नहीं।

छोटी screen पर यह जानकारी और अधिक महत्वपूर्ण हो जाती है, क्योंकि वहाँ window title पर निर्भर करने का विकल्प नहीं होता। यदि आपका setup ऐसा है, तो फोन से Claude Code चलाना देखें।

स्क्रिप्ट को तेज रखें

आपकी स्क्रिप्ट हर assistant message पर चलती है, और नया update आने पर Claude Code चल रहे execution को रद्द कर देता है। इसलिए धीमी स्क्रिप्ट पुराना text दिखा सकती है या कोई text नहीं दिखा सकती।

हर jq call में कुछ milliseconds लगते हैं। धीमा भाग git है: cold cache के साथ बड़े repository में git status को पूरा होने में hundreds of milliseconds लग सकते हैं। ऊपर दी गई स्क्रिप्ट जानबूझकर git status से बचती है और git branch --show-current को call करती है, जो .git/HEAD पढ़कर तुरंत लौट आती है।

यदि आप कोई अधिक भारी कार्य जोड़ते हैं, तो उसका output किसी file में cache करें और उसे हर कुछ seconds में refresh करें। File को session के आधार पर key करें:

CACHE="/tmp/statusline-$(field '.session_id')"

session_id का उपयोग करें, $$ का नहीं। $$ आपकी स्क्रिप्ट का process ID है। यह हर invocation पर बदलता है, इसलिए इस पर आधारित cache कभी hit नहीं होगा और आपको हर बार पूरा cost देना पड़ेगा। session_id पूरे session के दौरान स्थिर रहता है और अलग-अलग sessions में अलग होता है। इसलिए अलग repositories में चल रहे दो Claude Code sessions एक-दूसरे का cached branch name नहीं पढ़ सकते।

एक और सीमा ध्यान में रखें: statusline script के अंदर tput cols काम नहीं करता। Claude Code output capture करता है, आपकी स्क्रिप्ट को terminal से attach नहीं करता। इसलिए width detection के लिए मापने योग्य terminal उपलब्ध नहीं होता। Claude Code command चलाने से पहले, v2.1.153 और बाद के versions में, COLUMNS और LINES environment variables set करता है। इसलिए यह तय करते समय $COLUMNS पढ़ें कि कितना output print करना है।

statusline खाली क्यों रहती है

कुछ भी दिखाई नहीं देता। ls -l ~/.claude/statusline.sh से execute bit जाँचें, फिर ऊपर दिए गए mock input के साथ script को हाथ से चलाएँ। यदि shell में एक पंक्ति दिखाई देती है, लेकिन Claude Code में नहीं, तो claude --debug से शुरू करें। यह session में statusline के पहले run का exit code और stderr log करता है।

Debug log में Status line command skipped: workspace trust not accepted दिखाई देता है। statusline एक shell command चलाती है, इसलिए यह hooks के समान workspace trust gate के पीछे रहती है। जब तक आप उस directory के लिए trust dialog स्वीकार नहीं करते, command नहीं चलेगी। VPS पर ऐसा अक्सर होता है, क्योंकि हर नया clone ऐसी directory होता है जिसे Claude Code ने पहले नहीं देखा है। उस directory में Claude Code को restart करें और dialog स्वीकार करें।

सब कुछ खाली है और disableAllHooks set है। settings.json में "disableAllHooks": true statusline को भी disable करता है, क्योंकि यह वही shell-execution gate है। इसे हटाएँ या false पर set करें।

Row में null print होता है। jq selector ऐसी key तक पहुँच गया जो missing या null है, और jq -r null को null के चार characters के रूप में print करता है। Text के लिए // empty और numbers के लिए // 0 जोड़ें।

Script edit करने के तुरंत बाद row खाली हो जाती है। Non-zero exit करने वाली command या कुछ भी print न करने वाली command row को blank कर देती है। सामान्य कारण अंतिम line जैसी [ -n "$BRANCH" ] && LINE="..." होती है। Branch खाली होने पर यह 1 exit करती है और पूरे script का exit code भी यही हो जाता है। printf को आखिरी रखें या exit 0 जोड़ें।

Escape codes bar पर literal text के रूप में दिखाई देते हैं, जैसे \e]8;;echo -e के बजाय printf '%b' का उपयोग करें। Clickable OSC 8 links के लिए भी ऐसा terminal चाहिए जो उन्हें support करता हो। tmux या SSH इन sequences को हटा सकते हैं, इसलिए remote box पर plain colour अधिक सुरक्षित विकल्प है।

Row का दायाँ हिस्सा कट जाता है। System notifications और verbose-mode token counter उसी row में दाईं ओर से जगह साझा करते हैं, और संकरे terminal में overlap दिखाई नहीं देता। Output छोटा रखें। Bar पर दिखाई देने वाली संख्या के बजाय usage का वास्तविक हिसाब देखने के लिए Claude Code tokens कैसे गिनता है देखें।

FAQ

Claude Code statusline setting कहाँ रहता है?

यह settings.json में statusLine block के रूप में रहता है, जिसमें type का मान "command" और command का मान किसी script path या shell command पर सेट होता है। User settings ~/.claude/settings.json में होती हैं और उस machine के प्रत्येक project पर लागू होती हैं। Project settings repository के अंदर .claude/settings.json में होती हैं और उस directory के लिए प्राथमिकता रखती हैं। Settings अपने-आप reload होती हैं, लेकिन बदलाव अगले update trigger तक दिखाई नहीं देता, जैसे आपके अगले message पर।

मेरा Claude Code statusline खाली क्यों है?

लगभग सभी मामलों में इसके चार कारण होते हैं। Script में execute bit नहीं है, इसलिए shell Permission denied लौटाता है और stdout तक कुछ नहीं पहुँचता। Workspace trust dialog स्वीकार नहीं किया गया है और claude --debug, Status line command skipped: workspace trust not accepted log करता है। disableAllHooks का मान true है, जिससे उसी gate के तहत statusline disable हो जाती है। या script non-zero exit करती है, जिससे row खाली हो जाती है। पहले इसे manually test करें: echo '{}' | ~/.claude/statusline.sh को कुछ output करना चाहिए।

क्या statusline JSON में git branch शामिल होती है?

नहीं। JSON में model, workspace directories, context window numbers और cost जैसी session state होती है। इसमें git की कोई जानकारी नहीं होती। आपके bar में दिखाई देने वाली branch आपकी script द्वारा git branch --show-current चलाने से आती है। JSON से directory को git -C "$DIR" के साथ pass करें, ताकि branch हमेशा उस directory से मेल खाए जिसे bar दिखा रहा है।

क्या statusline tokens खर्च करती है या session को धीमा करती है?

इसमें कोई tokens खर्च नहीं होते, क्योंकि script locally चलती है और उसका output model को कभी नहीं भेजा जाता। Speed की जिम्मेदारी आपकी है। Command प्रत्येक assistant message पर 300 ms debounce के साथ चलती है। जब नया update आता है, Claude Code चल रहे execution को cancel कर देता है। इसलिए यदि script को पूरा होने में 1 second लगता है, तो stale text दिखाई देता है। बड़े repositories में git status से बचें और धीमी प्रक्रिया के परिणाम को session_id पर आधारित file में cache करें।

प्रत्येक server पर अलग statusline कैसे दिखाएँ?

एक ही script रखें और उसे machine की जानकारी पढ़ने दें। ऊपर दी गई script $HOSTNAME को hostname -s के fallback के साथ print करती है। इसलिए हर box पर copy की गई वही file प्रत्येक machine को सही label देती है। Checksum colour trick से प्रत्येक hostname को अपना colour भी मिलता है। यदि किसी server पर अलग layout चाहिए, तो उस box पर जिस repository में आप काम करते हैं, उसकी project settings में statusLine block रखें। उस directory के लिए project settings, user settings को override करती हैं।