SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

VPS-এ Claude Code statusline সেটআপ করার নিয়ম

statusLine একটি script চালিয়ে prompt-এর নিচে output দেখায়। hostname, directory, git branch ও model দেখিয়ে সঠিক server-এ কাজ করছেন কি না নিশ্চিত করুন।

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-এ যা লেখে তা প্রদর্শন করে।

এটাই সম্পূর্ণ contract। আপনার script standard input থেকে JSON পড়ে এবং standard output-এ text লেখে। এটি আপনার machine-এ চলে। এটি যা প্রদর্শন করে, তার কিছুই model-এ পাঠানো হয় না। তাই এর জন্য কোনো token খরচ হয় না।

একটি project থাকা laptop-এ এটি শুধু সাজসজ্জা। তিনটি server-এ এটি একটি safety rail। প্রতিটি terminal-এ প্রতিটি Claude Code session একই রকম দেখায়। তাই label ছাড়া চারটি SSH window থাকলে migration ভুল box-এ চালানোর ঝুঁকি থাকে। hostname দিয়ে শুরু হওয়া একটি statusline এই ধরনের ভুল বন্ধ করে।

settings.json-এ statusLine সেটিং কোথায় থাকে

এটি আপনার 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 অনুযায়ী 3টি optional key আছে। padding characters-এ horizontal spacing যোগ করে এবং এর default value 0। refreshInterval সাধারণ trigger-এর পাশাপাশি প্রতি N seconds পরপর command আবার চালায়। এর minimum হলো 1। এটি কেবল তখন ব্যবহার করুন, যখন line-এ clock বা session idle থাকা অবস্থায় পরিবর্তিত হয় এমন কোনো তথ্য দেখানো হয়। আপনার নিজের script যদি vim mode render করে, তাহলে hideVimModeIndicator built-in -- INSERT -- text দেখানো বন্ধ করে।

statusline script কোন data পায়?

এই পৃষ্ঠাসহ যেকোনো জায়গায় পড়া field list বিশ্বাস করবেন না। আপনার version যে প্রকৃত object পাঠায়, সেটি capture করুন। stdin একটি file-এ সংরক্ষণ করার জন্য একটি অস্থায়ী script লিখুন:

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-এ নির্দেশ করুন, একটি session শুরু করুন এবং একটি message পাঠান। bar-টি captured পড়ে। এখন কী এসেছে তা দেখুন:

jq . /tmp/statusline-input.json

আপনার build-এর জন্য সঠিক structure পেয়ে গেলেন। কোনো update কিছু পরিবর্তন করলে এই প্রক্রিয়া আবার করতে পারবেন।

August 2026-এ নথিভুক্ত স্থিতিশীল অংশগুলো flat key নয়, nested object। model-এর মধ্যে id এবং display_name থাকে। workspace-এর মধ্যে current_dir এবং project_dir থাকে: current_dir হলো session বর্তমানে যেখানে আছে, project_dir হলো session যেখান থেকে শুরু হয়েছিল, এবং session চলাকালে working directory পরিবর্তন হলে এই দুটির মান আলাদা হয়। top-level cwd-এ workspace.current_dir-এর একই মান থাকে। context_window-এ token count এবং আগে থেকে গণনা করা used_percentage থাকে। cost-এ total_cost_usd এবং duration counter থাকে। session চলাকালীন session_id অপরিবর্তিত থাকে এবং একাধিক session-এর মধ্যে unique হয়; পরে caching করার ক্ষেত্রে এটি গুরুত্বপূর্ণ।

Schema পরিবর্তনের পরেও script সচল রাখতে তিনটি নিয়ম অনুসরণ করুন।

কিছু key অনুপস্থিত থাকে, null নয়। সংশ্লিষ্ট feature সক্রিয় থাকলেই vim, agent, pr, worktree এবং effort দেখা যায়। vim mode বন্ধ থাকলে jq -r দিয়ে .vim.mode পড়লে আক্ষরিক null string মুদ্রিত হয়, এবং bar-এ পাঠকের কাছে null দেখা যায়। প্রতিটি selector-এর শেষে // empty যোগ করুন, যাতে key অনুপস্থিত থাকলে কিছুই মুদ্রিত না হয়।

কিছু value শুরুতে null থাকে। প্রথম API response আসার আগে context_window.used_percentage এবং context_window.current_usage null থাকে। /compact-এর পরে current_usage আবার null হয়ে যায় এবং পরবর্তী call এটি পুনরায় পূরণ করে। তাই bar-এ context percentage দেখাতে // 0 প্রয়োজন; নইলে প্রতিটি session-এর প্রথম কয়েক সেকেন্ডে null পড়া হবে। এই সংখ্যা bar-এ দেওয়ার আগে context window কীভাবে পূর্ণ হয় তা জানা সহায়ক।

git branch JSON-এ থাকে না। কোনো field এটি জানায় না। bar-এ দেখানো যেকোনো branch আপনার script নিজে 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 যোগ করে। ফলে কোনো key-এর নাম পরিবর্তন করা হলে বা key মুছে গেলে খালি string পাওয়া যায় এবং পরের line একটি default সরবরাহ করে। Directory-এর fallback ক্রম workspace.current_dir থেকে cwd, তারপর $PWD। Branch নেওয়া হয় git -C "$DIR" থেকে, সরাসরি git থেকে নয়। তাই bar-এ যে directory দেখানো হয়, branch সবসময় তার সঙ্গেই মেলে।

এটি সংরক্ষণ করুন, তারপর executable করুন:

chmod +x ~/.claude/statusline.sh

Execute bit ঐচ্ছিক নয়। Claude Code shell-এর মাধ্যমে command চালায়। তাই +x ছাড়া script Permission denied-এর কারণে ব্যর্থ হয়, কোনো stdout তৈরি করে না, এবং row-টি কোনো দৃশ্যমান error ছাড়াই খালি থাকে।

jq command line-এ JSON parse করে। নতুন Ubuntu server-এ এটি আগে থেকে ইনস্টল করা থাকে না:

sudo apt update && sudo apt install -y jq

এরপর setting-টিকে script-এর দিকে নির্দেশ করুন। উপরের প্রথম 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 test চালান। সাধারণত মানুষ এই পরীক্ষাটিই বাদ দেয়:

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

Schema পরিবর্তনের ফলে পাওয়া সম্ভব এমন সবচেয়ে খারাপ অবস্থা হলো একটি খালি object। তবুও লাইনটি প্রিন্ট হবে: hostname, $PWD থেকে বর্তমান directory, এবং model name-এর জায়গায় claude শব্দটি। কিছু crash করবে না এবং null-ও প্রিন্ট হবে না। এই পরীক্ষায় উত্তীর্ণ একটি স্ক্রিপ্ট কোনো field-এর নাম পরিবর্তিত হলেও কাজ করে, কারণ স্ক্রিপ্টের কাছে renamed field এবং missing field একই ঘটনা।

আপনি যা দেখতে পাবেন

statusline বিল্ট-ইন footer badge-এর উপরে নিজস্ব একটি সারিতে প্রদর্শিত হবে এবং সেগুলো প্রতিস্থাপন করবে না। কার্যকর সেটআপে এটি একটি সারি হবে: cyan রঙে সংক্ষিপ্ত 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-এ সারিটি আপনার script আবার চালাবে। Updates 300 ms-এ debounce করা হয়, তাই অল্প সময়ে একাধিক পরিবর্তন হলে script একবারই চলে। Autocomplete, help menu এবং permission prompt চলাকালে bar-টি লুকিয়ে থাকে, পরে আবার দেখা যায়।

হোস্টনাম কেন সবার আগে

একাধিক সার্ভারে agent চালু রাখলে আপনি কোথায় আছেন তা জানানোর একমাত্র জিনিস হয়ে দাঁড়ায় terminal, আর terminal ভুল তথ্য দিতে পারে। একটি tmux pane-এর ভেতর থেকে দ্বিতীয় ssh connection খুললে window title প্রায়ই পুরোনো নামই দেখায়, কারণ title সেট করে এমন shell জানেই না যে এটি অন্য জায়গায় চলে গেছে। VPS-এ detached tmux session-এ Claude Code চালু রেখে এক দিন পরে আবার সংযুক্ত হলে, স্ক্রিনে build server আর production box আলাদা করে চেনার কোনো উপায় থাকে না।

statusline আলাদা, কারণ Claude Code নিজেই প্রতিটি session-এর জন্য সেই session-এ থাকা data থেকে এটি render করে। এটি ভুল pane থেকে উত্তরাধিকারসূত্রে আসতে পারে না এবং refresh না হওয়া shell prompt-এর কারণে পুরোনোও থাকে না। statusline-এ যা দেখা যায়, সেটিই সেই box যেখানে agent ফাইল লিখছে।

প্রতিটি server-এর জন্য আলাদা রং নির্ধারণ করুন, যাতে পড়ার আগেই সেটি চিনতে পারেন। LINE= assignment-এর উপরে নিচের দুই লাইন যোগ করুন:

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

এরপর ${CYAN}-এর পরিবর্তে ${HOST_COLOR} ব্যবহার করুন। cksum hostname-এর checksum প্রিন্ট করে। ফলে একই নাম সব সময় 31 থেকে 36-এর মধ্যে একই রঙে map হয়; এই পরিসর red থেকে cyan পর্যন্ত। একই script প্রতিটি box-এ কপি করুন। তাহলে প্রতিটি box নিজেই নিজের পরিচয় দেখাবে।

একই কারণে directory-ও statusline-এ থাকা দরকার। একটি ssh command-এ /srv/api এবং /srv/api-staging-এর মধ্যে পার্থক্য মাত্র এক keystroke, কিন্তু ফলাফলের দিক থেকে তা একটি সম্পূর্ণ incident-এর সমান হতে পারে। Model এবং branch হলো প্রস্থ ব্যবহারের জন্য উপযোগী অন্য দুটি তথ্য। Model জানায় আপনি কোন session পুনরায় চালু করেছেন, আর branch জানায় agent main-এ commit করতে যাচ্ছে কি না।

ছোট স্ক্রিনে এই তথ্যগুলো আরও গুরুত্বপূর্ণ, কারণ সেখানে নির্ভর করার মতো window title থাকে না। আপনার setup এমন হলে ফোন থেকে Claude Code চালানো দেখুন।

স্ক্রিপ্ট দ্রুত রাখুন

আপনার স্ক্রিপ্ট প্রতিটি assistant message-এর সময় চলে, এবং নতুন update এলে Claude Code চলমান run বাতিল করে। তাই স্ক্রিপ্ট ধীর হলে পুরোনো text দেখা যায়, অথবা কোনো text দেখা যায় না।

প্রতিটি jq call চালাতে কয়েক মিলিসেকেন্ড লাগে। ধীর অংশটি হলো git: cold cache অবস্থায় বড় repository-তে git status চালাতে শত শত মিলিসেকেন্ড লাগে। আগের স্ক্রিপ্টটি ইচ্ছাকৃতভাবে git status ব্যবহার করে না। এর পরিবর্তে এটি git branch --show-current call করে, যা .git/HEAD পড়ে এবং সঙ্গে সঙ্গে ফল ফেরত দেয়।

আপনি ভারী কোনো কাজ যোগ করলে সেটির ফল file-এ cache করুন এবং প্রতি কয়েক সেকেন্ডে refresh করুন। file-টির cache key হিসেবে session ব্যবহার করুন:

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

$$ নয়, session_id ব্যবহার করুন। $$ হলো আপনার স্ক্রিপ্টের process ID। প্রতিটি invocation-এ এটি বদলে যায়। তাই এটিকে cache key হিসেবে ব্যবহার করলে cache কখনো hit করবে না এবং প্রতিবার পুরো খরচ দিতে হবে। session_id পুরো session জুড়ে স্থিতিশীল থাকে এবং session-ভেদে আলাদা হয়। তাই দুটি repository-তে চলা দুটি Claude Code session একে অপরের cached branch name পড়তে পারে না। নকশা অনুযায়ী session-গুলো এভাবেই বিচ্ছিন্ন থাকে। তাই একটি session থেকে অন্যটিকে কাজ দিতে হলে ইচ্ছাকৃতভাবে সেই কাজটি করতে হয়। একটি Claude Code session থেকে অন্যটিতে message পাঠানো এ কাজেই ব্যবহৃত হয়।

আরেকটি সীমাবদ্ধতা জানা দরকার: tput cols statusline script-এর ভিতরে কাজ করে না। Claude Code output capture করে, আপনার স্ক্রিপ্টকে terminal-এর সঙ্গে সংযুক্ত করে না। তাই width মাপার মতো কোনো terminal থাকে না। v2.1.153 এবং পরবর্তী সংস্করণে Claude Code command চালানোর আগে COLUMNS এবং LINES environment variable সেট করে। কতটুকু output দেখাবেন তা নির্ধারণ করতে হলে $COLUMNS পড়ুন।

স্ট্যাটাসলাইন ফাঁকা থাকে কেন

কিছুই দেখা যাচ্ছে না। ls -l ~/.claude/statusline.sh দিয়ে execute bit পরীক্ষা করুন। এরপর উপরের mock input ব্যবহার করে হাতে script চালান। Shell-এ একটি line দেখালেও 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 পুনরায় চালু করুন এবং dialog গ্রহণ করুন।

সবকিছু ফাঁকা এবং disableAllHooks সেট করা আছে। settings.json-এ "disableAllHooks": true statusline-ও নিষ্ক্রিয় করে, কারণ এটিও একই shell-execution gate। এটি সরিয়ে দিন অথবা false সেট করুন।

Row-তে null মুদ্রিত হচ্ছে। একটি jq selector এমন একটি key-তে পৌঁছেছে, যা অনুপস্থিত অথবা null। jq -r null-কে null এই চারটি অক্ষর হিসেবে মুদ্রণ করে। Text-এর জন্য // empty এবং সংখ্যার জন্য // 0 যোগ করুন।

Script সম্পাদনা করার পরই row ফাঁকা হয়ে যায়। কোনো command non-zero exit করলে অথবা কিছু মুদ্রণ না করলে row ফাঁকা হয়ে যায়। সাধারণ কারণ হলো [ -n "$BRANCH" ] && LINE="..."-এর মতো শেষ line। Branch ফাঁকা থাকলে এটি 1 exit করে এবং পুরো script-এর exit code-ও 1 হয়ে যায়। printf-কে শেষ command হিসেবে রাখুন অথবা exit 0 যোগ করুন।

Bar-এ \e]8;;-এর মতো escape code literal text হিসেবে দেখা যাচ্ছে। echo -e-এর পরিবর্তে printf '%b' ব্যবহার করুন। Clickable OSC 8 link-এর জন্যও এটি সমর্থন করে এমন terminal প্রয়োজন। tmux অথবা SSH sequence-গুলো বাদ দিতে পারে। তাই remote box-এ plain colour ব্যবহার করাই নিরাপদ।

Row-এর ডান পাশ কেটে যাচ্ছে। System notification এবং verbose-mode token counter—দুটিই ডান দিক থেকে ওই row-টি ব্যবহার করে। সরু terminal-এ এগুলো একে অপরের ওপর চলে যায়। Output সংক্ষিপ্ত রাখুন। Bar-এ দেখানো সংখ্যার বদলে usage-এর প্রকৃত হিসাবের জন্য Claude Code কীভাবে token গণনা করে দেখুন।

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 ফাঁকা কেন?

প্রায় সব ক্ষেত্রে 4টি কারণের একটি দায়ী। Script-এ execute bit নেই। তাই shell Permission denied ফেরত দেয় এবং stdout-এ কিছুই যায় না। Workspace trust dialog কখনও accept করা হয়নি। ফলে claude --debug-এ Status line command skipped: workspace trust not accepted log হয়। disableAllHooks হল true, যা একই gate-এর অধীনে statusline নিষ্ক্রিয় করে। অথবা script non-zero exit করে, ফলে row ফাঁকা থাকে। প্রথমে হাতে চালিয়ে পরীক্ষা করুন: echo '{}' | ~/.claude/statusline.sh-কে অবশ্যই কিছু output দিতে হবে।

Statusline JSON-এ কি git branch থাকে?

না। JSON-এ model, workspace directory, context window-এর সংখ্যা এবং cost-এর মতো session state থাকে। এতে git সম্পর্কে কোনো তথ্য থাকে না। আপনার bar-এ branch দেখাতে হলে নিজের script-এ git branch --show-current কল করতে হবে। JSON থেকে directory-টি git -C "$DIR" দিয়ে pass করুন, যাতে bar-এ দেখানো directory-র সঙ্গে branch সবসময় মেলে।

Statusline কি token খরচ করে বা session ধীর করে?

কোনো token খরচ হয় না। কারণ script লোকালিতে চলে এবং এর output model-এ পাঠানো হয় না। গতি বজায় রাখার দায়িত্ব আপনার। প্রতিটি assistant message-এর পরে 300 ms debounce সহ command-টি চলে। নতুন update এলে Claude Code চলমান run বাতিল করে। তাই script চালাতে পুরো এক second লাগলে stale text দেখা যায়। বড় repository-তে git status ব্যবহার এড়িয়ে চলুন এবং ধীর কাজের ফল session_id-এর ভিত্তিতে file-এ cache করুন।

প্রতিটি server-এ আলাদা statusline কীভাবে দেখাব?

একটি script রাখুন এবং সেটিকে মেশিনের তথ্য পড়তে দিন। উপরের script-টি fallback হিসেবে hostname -s সহ $HOSTNAME দেখায়। তাই একই file প্রতিটি box-এ copy করলেও প্রতিটি box সঠিক label পায়। Checksum colour trick-এর ফলে প্রতিটি hostname-এর নিজস্ব colour হয়। কোনো server-এ আলাদা layout দরকার হলে, ওই server-এ যে repository-তে কাজ করেন তার project settings-এ একটি statusLine block রাখুন। কারণ ওই directory-র জন্য project settings user settings-কে override করে।