SSD Nodes Learn 🎉 VPS $4.99/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-07

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

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

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

এটাই সম্পূর্ণ 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 মানটি একটি shell-এর মাধ্যমে চালানো হয়। তাই এখানে script path বা সরাসরি command দেওয়া যায়। কোনো script লেখার আগে wiring কাজ করছে কি না যাচাই করুন:

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

Claude Code চালু করে একটি message পাঠান। Prompt-এর নিচের bar-এ এখন server-এর সংক্ষিপ্ত hostname দেখা যাবে। এটি ফাঁকা থাকলে সমস্যা setting বা trust dialog-এ; আপনার script-এ নয়। নিচের “statusline ফাঁকা থাকে কেন” অংশটি পড়ুন।

August 2026 অনুযায়ী 3টি optional key আছে। padding অক্ষরে horizontal spacing যোগ করে এবং এর default মান 0refreshInterval স্বাভাবিক trigger-এর পাশাপাশি প্রতি N সেকেন্ডে command পুনরায় চালায়। এর সর্বনিম্ন মান 1। Line-এ clock বা session idle থাকা অবস্থায় পরিবর্তিত হয় এমন কোনো তথ্য দেখালে কেবল এটি ব্যবহার করুন। আপনার নিজের script যদি vim mode দেখায়, তাহলে 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-এর জন্য exact structure পেয়ে যাবেন। কোনো update-এ কিছু পরিবর্তন হলে একই পদ্ধতি আবার ব্যবহার করতে পারবেন।

August 2026-এ documented stable অংশগুলো 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-এর একই value থাকে। context_window-এ token count এবং আগে থেকে গণনা করা used_percentage থাকে। cost-এ total_cost_usd এবং duration counter থাকে। session চলাকালীন session_id অপরিবর্তিত থাকে এবং প্রতিটি session-এর জন্য unique হয়, যা পরে caching-এর ক্ষেত্রে গুরুত্বপূর্ণ।

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

কিছু key null নয়, অনুপস্থিত থাকে। matching feature সক্রিয় থাকলেই vim, agent, pr, worktree এবং effort দেখা যায়। vim mode বন্ধ থাকা অবস্থায় jq -r দিয়ে .vim.mode পড়লে literal string null প্রদর্শিত হয়, এবং bar-এ পাঠকের কাছে null দেখা যায়। প্রতিটি selector-এর শেষে // empty যোগ করুন, যাতে missing 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 command-টি shell-এর মাধ্যমে চালায়। তাই +x ছাড়া script Permission denied-সহ ব্যর্থ হয়, কোনো stdout তৈরি করে না, এবং কোনো দৃশ্যমান error ছাড়াই row খালি থাকে।

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

sudo apt update && sudo apt install -y jq

এরপর setting-এ script-টির path দিন। উপরের প্রথম settings.json block ব্যবহার করুন।

বিশ্বাস করার আগে script পরীক্ষা করুন

script-টি হাতে দুবার চালান। প্রথমবার একটি সাধারণ 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-ও কিছু print হয় না। এই পরীক্ষায় উত্তীর্ণ script কোনো field-এর নাম পরিবর্তন হলেও কাজ করে, কারণ script-এর কাছে renamed field এবং missing field একই ঘটনা।

আপনার যা দেখা উচিত

statusline built-in footer badge-এর উপরে নিজস্ব একটি সারিতে প্রদর্শিত হবে এবং সেগুলো প্রতিস্থাপন করবে না। সঠিকভাবে কাজ করলে এটি একটি সারি হবে: cyan রঙে short hostname, এরপর working directory; আপনার home directory ~-এ সংক্ষিপ্তভাবে দেখানো হবে। Directory-টি git repository হলে এরপর yellow রঙে branch name দেখা যাবে। সবশেষে model name dimmed অবস্থায় থাকবে। মোটামুটি web-01 ~/api main Opus-এর মতো হবে, যেখানে এই চারটি অংশের রং আলাদা থাকবে।

Session শুরু হলে, resume-সহ, নতুন assistant message এলে, /compact শেষ হলে, permission mode পরিবর্তিত হলে, vim mode toggle হলে এবং আপনি interval নির্ধারণ করলে প্রতি refreshInterval tick-এ row-টি আপনার script আবার চালাবে। Update 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 চালু রেখে এক দিন পরে আবার সংযুক্ত হলে, screen-এ build server এবং production box আলাদা করে চেনার মতো কিছু থাকে না।

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

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

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

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

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

ছোট screen হলে এগুলো আরও গুরুত্বপূর্ণ, কারণ তখন window title-এর ওপর নির্ভর করার সুযোগ থাকে না। আপনার setup এমন হলে phone থেকে 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 করুন। session অনুযায়ী file-টির key নির্ধারণ করুন:

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

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

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

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

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

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

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

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

Escape code bar-এ \e]8;;-এর মতো 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-তে ডান দিক থেকে জায়গা ভাগ করে নেয়। Narrow terminal-এ এগুলো overlap করে। Output সংক্ষিপ্ত রাখুন। Bar-এ দেখানো সংখ্যার বদলে ব্যবহারের প্রকৃত হিসাব জানতে Claude Code কীভাবে token গণনা করে দেখুন।

FAQ

Claude Code statusline সেটিং কোথায় থাকে?

settings.json-এ এটি statusLine ব্লক হিসেবে থাকে। সেখানে type-এর মান "command" এবং command-এর মান একটি script path বা shell command হতে হয়। User settings থাকে ~/.claude/settings.json-এ এবং ওই মেশিনের প্রতিটি project-এ প্রযোজ্য হয়। Project settings repository-র ভেতরের .claude/settings.json-এ থাকে এবং ওই directory-র ক্ষেত্রে user settings-এর ওপর অগ্রাধিকার পায়। Settings স্বয়ংক্রিয়ভাবে reload হয়। তবে কোনো পরিবর্তন পরবর্তী update trigger না আসা পর্যন্ত দেখা যায় না, যেমন আপনার পরবর্তী message-এ।

আমার Claude Code statusline ফাঁকা কেন?

প্রায় সব ক্ষেত্রে 4টি কারণের একটি দায়ী। 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 status-এ 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-টিও সবসময় সেই directory-র হয়।

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 রাখুন এবং সেটিকে machine-এর তথ্য পড়তে দিন। ওপরের script-টি fallback হিসেবে hostname -s ব্যবহার করে $HOSTNAME print করে। তাই একই file প্রতিটি box-এ copy করলেও প্রতিটি box-এর label সঠিক থাকে। Checksum-এর colour কৌশল প্রতিটি hostname-এর জন্য আলাদা colour দেয়। কোনো server-এ আলাদা layout প্রয়োজন হলে, ওই server-এ যে repository-তে কাজ করেন তার project settings-এ একটি statusLine block রাখুন। কারণ ওই directory-র ক্ষেত্রে project settings user settings-এর ওপর অগ্রাধিকার পায়।