VPS वर Claude Code statusline कशी सेट करायची
Claude Code ची statusLine script prompt खाली hostname, directory, git branch आणि model दाखवते. योग्य server ओळखण्यासाठी settings.json मध्ये ती कशी जोडायची ते जाणून घ्या.
Claude Code statusline काय दाखवते
Claude Code statusline ही prompt खाली दिसणारी एक ओळ आहे. त्यात तुम्ही लिहिलेल्या script चे output दिसते. statusLine block settings.json मध्ये जोडा आणि त्यात command द्या. Claude Code ती command चालवते, session state JSON स्वरूपात standard input वर पाठवते आणि command ने standard output वर लिहिलेली सामग्री दाखवते.
हा संपूर्ण करार आहे. तुमची script standard input वरील JSON वाचते आणि standard output वर text लिहिते. ती तुमच्या मशीनवर चालते. ती जे काही छापते ते model कडे पाठवले जात नाही. त्यामुळे त्यासाठी tokens खर्च होत नाहीत.
एका project असलेल्या laptop वर हे केवळ सजावटीचे आहे. तीन servers वर ते सुरक्षिततेसाठी महत्त्वाचे ठरते. प्रत्येक terminal मध्ये प्रत्येक Claude Code session सारखाच दिसतो. त्यामुळे labels नसलेल्या चार SSH windows मुळे migration चुकीच्या server वर लागू होऊ शकते. hostname ने सुरू होणारी statusline या प्रकारची चूक टाळते.
settings.json मध्ये statusLine setting कुठे ठेवायची
ते तुमच्या user settings मध्ये ~/.claude/settings.json येथे ठेवा. हे त्या मशीनवरील प्रत्येक 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 value 0 आहे. refreshInterval नेहमीच्या triggers व्यतिरिक्त command दर N seconds ने पुन्हा चालवते. यासाठी किमान मूल्य 1 आहे. Session idle असताना line मध्ये clock किंवा बदलणारी अन्य माहिती दाखवायची असल्यासच हे वापरा. तुमची स्वतःची script vim mode आधीच render करत असल्यास hideVimModeIndicator अंगभूत -- INSERT -- text लपवते.
स्टेटसलाइन स्क्रिप्टला कोणता डेटा मिळतो?
या पृष्ठासह, तुम्ही कुठेही वाचलेल्या field list वर विश्वास ठेवू नका. तुमची आवृत्ती प्रत्यक्षात पाठवणारा object capture करा. stdin फाइलमध्ये जतन करणारी तात्पुरती स्क्रिप्ट लिहा:
cat > ~/.claude/statusline-capture.sh <<'EOF'
#!/bin/bash
cat > /tmp/statusline-input.json
echo "captured"
EOF
chmod +x ~/.claude/statusline-capture.shstatusLine.command ला त्या फाइलकडे निर्देशित करा, session सुरू करा आणि एक message पाठवा. bar captured वाचतो. आता आलेला डेटा पहा:
jq . /tmp/statusline-input.jsonतुमच्या build साठी अचूक रचना तुमच्याकडे आहे. एखाद्या update मुळे काही बदलल्यास तुम्ही ही प्रक्रिया पुन्हा करू शकता.
August 2026 मध्ये documented असलेले स्थिर भाग flat keys ऐवजी nested objects आहेत. model मध्ये id आणि display_name असतात. workspace मध्ये current_dir आणि project_dir असतात: current_dir मध्ये session सध्या कुठे आहे, project_dir मध्ये तो कुठून सुरू केला गेला, आणि session दरम्यान working directory बदलल्यावर ही दोन्ही मूल्ये वेगळी होतात. Top-level cwd मध्ये workspace.current_dir सारखेच मूल्य असते. context_window मध्ये token counts आणि आधीच मोजलेले used_percentage असते. cost मध्ये total_cost_usd आणि duration counters असतात. session_id हे session च्या संपूर्ण कालावधीत स्थिर राहते आणि sessions मध्ये unique असते. पुढील caching साठी हे महत्त्वाचे आहे.
Schema बदलल्यानंतरही स्क्रिप्ट चालू ठेवण्यासाठी तीन नियम पाळा.
काही keys null नसून अनुपस्थित असतात. Matching feature सक्रिय असतानाच vim, agent, pr, worktree आणि effort दिसतात. vim mode बंद असताना jq -r सह .vim.mode वाचल्यास literal string null छापली जाते आणि bar मध्ये वाचकाला null दिसते. प्रत्येक selector च्या शेवटी // empty जोडा, म्हणजे missing key असल्यास काहीही छापले जाणार नाही.
काही values सुरुवातीला null असतात. पहिला API response येण्यापूर्वी context_window.used_percentage आणि context_window.current_usage null असतात. /compact नंतर पुढील call त्यात पुन्हा मूल्य भरेपर्यंत current_usage पुन्हा null होते. त्यामुळे bar वरील context percentage साठी // 0 आवश्यक आहे; अन्यथा प्रत्येक session च्या पहिल्या काही seconds मध्ये ते null वाचते. ही संख्या bar वर दाखवण्यापूर्वी context window प्रत्यक्षात कशी भरते हे समजून घेणे उपयुक्त ठरते.
git branch JSON मध्ये नसते. कोणतेही field ते दर्शवत नाही. तुमच्या bar वरील branch तुमची स्क्रिप्ट स्वतः git चालवल्यामुळे येते.
तुटण्याऐवजी मर्यादित स्वरूपात कार्यरत राहणारी statusline script
ही copy-paste करण्यासाठी तयार आवृत्ती आहे. ती 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 जोडते. त्यामुळे rename केलेली किंवा काढलेली key रिकामी string देते आणि पुढील line default value देते. Directory साठी workspace.current_dir नंतर cwd आणि त्यानंतर $PWD असा fallback क्रम आहे. Branch साठी साध्या git ऐवजी git -C "$DIR" वापरले आहे. त्यामुळे bar मध्ये दाखवली जाणारी directory आणि branch नेहमी जुळतात.
ही file save करा आणि executable करा:
chmod +x ~/.claude/statusline.shExecute bit आवश्यक आहे. Claude Code ही command shell मार्फत चालवते. त्यामुळे +x नसलेली script Permission denied मुळे fail होते, stdout मध्ये काहीही देत नाही आणि कोणतीही दृश्यमान error न दाखवता row रिकामी राहते.
jq command line वर JSON parse करते. Fresh Ubuntu server वर ती installed नसते:
sudo apt update && sudo apt install -y jqत्यानंतर setting ला script कडे point करा आणि वरच्या पहिल्या settings.json block चा वापर करा.
स्क्रिप्टवर विश्वास ठेवण्यापूर्वी तिची चाचणी घ्या
ती हाताने दोनदा चालवा. प्रथम सामान्य session object सह:
echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/srv/api"},"session_id":"t1"}' | ~/.claude/statusline.shतुम्हाला hostname, त्यानंतर /srv/api आणि मग Opus मिळेल. कोणतीही branch दिसत नाही, कारण तुमच्या मशीनवरील /srv/api बहुधा git repository नाही.
दुसरी चाचणी degradation ची आहे. हीच चाचणी लोक वगळतात:
echo '{}' | ~/.claude/statusline.shSchema change मुळे मिळू शकणारी सर्वात खराब स्थिती म्हणजे रिक्त object. ओळ तरीही hostname, $PWD मधील current directory आणि model name च्या जागी claude हा शब्द छापते. काहीही crash होत नाही आणि null छापले जात नाही. ही चाचणी उत्तीर्ण होणारी स्क्रिप्ट एखादे field rename झाले तरी कार्यरत राहते, कारण तुमच्या स्क्रिप्टसाठी renamed field आणि missing field ही एकच घटना असते.
तुम्हाला काय दिसले पाहिजे
statusline अंगभूत footer badges च्या वर स्वतःच्या ओळीत दिसते आणि त्या badges ची जागा घेत नाही. कार्यरत सेटअपमध्ये ती एकाच ओळीत दिसते: cyan रंगात short hostname, त्यानंतर home directory ला ~ असे संक्षिप्त करून दाखवणारी working 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 केल्यावर आणि तुम्ही refreshInterval tick सेट केला असल्यास त्या tick वर ही ओळ तुमची script पुन्हा चालवते. Updates साठी 300 ms debounce लागू आहे. त्यामुळे बदलांचा burst झाल्यास script एकदाच चालते. Autocomplete, help menu आणि permission prompts दरम्यान bar लपते आणि त्यानंतर पुन्हा दिसते.
होस्टनाव सर्वप्रथम का आवश्यक आहे
तुम्ही एकापेक्षा जास्त सर्व्हरवर agents चालू ठेवत असाल, तर तुम्ही सध्या कुठे आहात हे सांगणारी एकमेव गोष्ट terminal असते; पण terminal नेहमी अचूक माहिती देत नाही. tmux pane मधून दुसरे ssh connection उघडल्यावर window title अनेकदा जुने नावच ठेवते, कारण title अशा shell ने सेट केलेले असते ज्याला आपण दुसरीकडे हललो आहोत हे कळलेले नसते. detached tmux session मध्ये VPS वर Claude Code चालू ठेवले आणि एका दिवसानंतर पुन्हा attach केले, तर स्क्रीनवर build server आणि production box यांच्यात फरक ओळखण्यासाठी काहीही दिसत नाही.
statusline वेगळी असते, कारण ती Claude Code स्वतः प्रत्येक session साठी त्या session कडे असलेल्या डेटावरून render करते. ती चुकीच्या pane कडून वारसा घेत नाही आणि refresh न झालेल्या shell prompt मुळे जुनीही राहत नाही. statusline मध्ये दिसणारे नाव म्हणजे agent ज्या box वर files लिहित आहे तो box असतो.
प्रत्येक सर्व्हरसाठी स्वतंत्र 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 करते. त्यामुळे एखादे hostname नेहमी 31 ते 36 या range मधील त्याच colour शी map होते. ही range red ते cyan पर्यंत असते. हीच script प्रत्येक box वर copy करा. प्रत्येक box स्वतःचे label दाखवेल.
directory सुद्धा याच कारणामुळे महत्त्वाची ठरते. /srv/api आणि /srv/api-staging हे ssh command मध्ये एका keystroke इतकेच अंतर असलेले पर्याय आहेत; पण त्यांच्या परिणामांमध्ये संपूर्ण incident इतका फरक असू शकतो. उरलेल्या दोन गोष्टींना statusline मध्ये जागा देणे उपयुक्त ठरते: model आणि branch. model मुळे तुम्ही कोणते session resume केले आहे हे कळते, तर branch मुळे agent main वर commit करणार आहे का हे समजते.
लहान screen वापरताना हे सर्व आणखी स्पष्ट दिसते, कारण window title वर अवलंबून राहता येत नाही. तुमची रचना अशी असल्यास फोनवरून Claude Code चालवणे पहा.
स्क्रिप्ट जलद ठेवा
तुमची स्क्रिप्ट प्रत्येक assistant message वर चालते. नवीन update आल्यावर Claude Code सुरू असलेली प्रक्रिया रद्द करते. त्यामुळे स्क्रिप्ट धीमी असल्यास जुन्या माहितीचा मजकूर दिसतो किंवा काहीही दिसत नाही.
प्रत्येक jq call ला काही milliseconds लागतात. git हा धीमा भाग आहे: cache रिकामा असताना मोठ्या repository मध्ये git status ला शेकडो milliseconds लागतात. वरील स्क्रिप्ट जाणीवपूर्वक git status टाळते आणि git branch --show-current call करते. हे .git/HEAD वाचते आणि लगेच परत येते.
तुम्ही अधिक वेळ घेणारी प्रक्रिया जोडल्यास, तिचे परिणाम file मध्ये cache करा आणि दर काही seconds ने refresh करा. ही file session वर आधारित ठेवा:
CACHE="/tmp/statusline-$(field '.session_id')"session_id वापरा, $$ नाही. $$ हा तुमच्या स्क्रिप्टचा process ID आहे. प्रत्येक invocation मध्ये तो वेगळा असतो. त्यामुळे त्यावर आधारित cache कधीही hit होत नाही आणि प्रत्येक वेळी पूर्ण खर्च होतो. session_id संपूर्ण session मध्ये स्थिर असते आणि वेगवेगळ्या sessions मध्ये वेगळी असते. त्यामुळे दोन repositories मधील दोन Claude Code sessions एकमेकांचे cached branch name वाचू शकत नाहीत.
आणखी एक मर्यादा लक्षात ठेवा: statusline script मध्ये tput cols कार्यरत नाही. Claude Code output capture करते आणि तुमची स्क्रिप्ट terminal शी जोडत नाही. त्यामुळे width मोजण्यासाठी काहीही उपलब्ध नसते. Claude Code command चालवण्यापूर्वी COLUMNS आणि LINES environment variables सेट करते. हे v2.1.153 आणि त्यानंतरच्या versions मध्ये लागू आहे. त्यामुळे किती मजकूर print करायचा हे ठरवताना $COLUMNS वाचा.
स्थितीची ओळ रिकामी का राहते
काहीही दिसत नाही. ls -l ~/.claude/statusline.sh वापरून execute bit तपासा. त्यानंतर वरील mock input वापरून script स्वतः चालवा. Shell मध्ये ओळ छापली जात असेल, पण Claude Code मध्ये दिसत नसेल, तर claude --debug पासून सुरुवात करा. हे session मध्ये statusline प्रथम चालवल्यावरचा exit code आणि stderr नोंदवते.
Debug log मध्ये Status line command skipped: workspace trust not accepted दिसते. statusline एक shell command चालवते. त्यामुळे hooks प्रमाणेच ती workspace trust gate मागे चालते. त्या directory साठी trust dialog स्वीकारेपर्यंत command चालत नाही. VPS वर हे नेहमी घडते, कारण प्रत्येक नवीन clone ही Claude Code ने अद्याप पाहिलेली नसलेली directory असते. त्या directory मध्ये Claude Code पुन्हा सुरू करा आणि dialog स्वीकारा.
सगळे रिकामे आहे आणि disableAllHooks सेट आहे. settings.json मधील "disableAllHooks": true statusline देखील disable करते, कारण तेच shell-execution gate आहे. ते काढून टाका किंवा false वर सेट करा.
ओळ null छापते. jq selector अशा key पर्यंत पोहोचला आहे जी उपलब्ध नाही किंवा null आहे. jq -r null ला null या चार अक्षरांप्रमाणे छापते. मजकुरासाठी // empty आणि संख्यांसाठी // 0 जोडा.
तुम्ही script संपादित केल्यानंतर लगेच ओळ रिकामी होते. non-zero exit होणारी किंवा काहीही न छापणारी command ओळ रिकामी करते. सामान्य कारण म्हणजे [ -n "$BRANCH" ] && LINE="..." सारखी शेवटची ओळ. branch रिकामी असताना ती 1 exit करते आणि त्यामुळे संपूर्ण script चा exit code 1 होतो. शेवटी printf ठेवा किंवा exit 0 जोडा.
Escape codes bar वर literal text म्हणून दिसतात, उदाहरणार्थ \e]8;;. echo -e ऐवजी printf '%b' वापरा. Clickable OSC 8 links साठी ते समर्थित करणारे terminal देखील आवश्यक आहे. tmux किंवा SSH ही sequences काढून टाकू शकतात. त्यामुळे remote box वर साधा रंग अधिक सुरक्षित पर्याय आहे.
ओळीची उजवी बाजू कापली जाते. System notifications आणि verbose-mode token counter हीच ओळ उजवीकडून सामायिक करतात. अरुंद terminal मध्ये त्यांचा overlap दिसत नाही. Output लहान ठेवा. Bar वर दिसणाऱ्या संख्येऐवजी वापराचे अचूक accounting पाहण्यासाठी Claude Code tokens कसे मोजते हे पहा.
FAQ
Claude Code statusline ची setting कुठे असते?
ती settings.json मध्ये असते. तिथे statusLine block मध्ये type ची किंमत "command" आणि command ची किंमत script path किंवा shell command अशी असते. User settings ~/.claude/settings.json येथे असतात आणि त्या मशीनवरील प्रत्येक 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 बंद होते. किंवा script non-zero exit करते. त्यामुळे row रिकामी राहते. प्रथम ती हाताने तपासा: echo '{}' | ~/.claude/statusline.sh ने काहीतरी print केले पाहिजे.
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" ने द्या. त्यामुळे bar मध्ये दाखवली जाणारी directory आणि branch नेहमी जुळतील.
Statusline मुळे tokens खर्च होतात का किंवा session धीमे होते का?
यासाठी tokens खर्च होत नाहीत, कारण script स्थानिक पातळीवर चालते आणि त्याचे output model कडे पाठवले जात नाही. मात्र speed ची जबाबदारी तुमची आहे. प्रत्येक assistant message वर command चालते आणि त्याला 300 ms debounce असतो. नवीन update आल्यावर Claude Code चालू असलेली run रद्द करते. त्यामुळे script ला पूर्ण एक second लागत असल्यास जुना text दिसतो. मोठ्या repositories मध्ये git status टाळा. Slow असलेली कोणतीही माहिती session_id वर आधारित नाव असलेल्या file मध्ये cache करा.
प्रत्येक server वर वेगळी statusline कशी दाखवू?
एकच script ठेवा आणि त्याला machine वाचू द्या. वरील script fallback म्हणून hostname -s वापरून $HOSTNAME print करते. त्यामुळे प्रत्येक box वर copy केलेली तीच file योग्य label दाखवते. Checksum colour trick मुळे प्रत्येक hostname ला स्वतःचा colour मिळतो. एखाद्या server वर वेगळा layout आवश्यक असल्यास, त्या box वर तुम्ही वापरत असलेल्या repository च्या project settings मध्ये statusLine block ठेवा. त्या directory साठी project settings user settings वर प्राधान्य घेतात.