Files
AgentHub/docs/STATUSLINE.md
T
nntrivi2001 4a665da79e fix: a token-gated or LAN-bound dashboard works end to end (WSL mirrored)
- /ws-pty carries the dashboard token like /ws (the terminal never attached
  with DASHBOARD_TOKEN set), and so does everything that cannot send the
  header: images, downloads, exports, drops (withToken/tokenHeader). A
  refused upgrade answers 401/403 and is logged and counted by reason.
- The browser asks for a missing or wrong token (401 EUNAUTHORIZED) and takes
  ?token= from the link agenthub start prints, dropping it from the URL.
- The CLI sends the token (DASHBOARD_TOKEN, else the one the running server
  publishes 0600 in <data dir>/runtime/dashboard-token); MCP and statusline
  read the same file.
- DASHBOARD_HOST takes a list, and 127.0.0.1 is always listened on too, so a
  LAN-only bind keeps hooks and the CLI working.
- agenthub start --host/--allowed-hosts/--token are saved in
  <data dir>/network.json for every later start; a wide bind gets a token;
  every reachable URL is printed.
- tmux < 3.7 is an amber, once-per-version notice that says only the pane
  scrollbar is missing, with a ~/.local build instead of sudo make install.
- INSTALL: PATH belongs in ~/.profile for sudo -iu/ssh; WSL mirrored notes.
2026-11-06 14:59:48 +07:00

2.8 KiB

AgentHub statusline for Claude Code

statusline/statusline.js is a Claude Code statusline command. It prints one line under the prompt:

Opus 5.5 · main · ███░░░░░░░ 34% · $1.23 · today $45.68
Part Source
model model.display_name from Claude Code's statusline JSON
branch git symbolic-ref --short HEAD in the session's cwd (short sha when detached; 500 ms cap)
context bar context_window.used_percentage, else current_usage (input + cache) ÷ context_window_size; green < 50 %, yellow < 80 %, red above
$1.23 this session, Claude Code's own cost.total_cost_usd
today $… your sessions today, from the dashboard: GET /api/pricing/cost?tz_offset=<local>&mine=1 → today's daily_costs row (in server mode only the pane's workspace owner's sessions, even for an admin; locally every session)

Today's cost has a 1-second timeout and is cached for 30 s in <os tmpdir>/agenthub-statusline-<uid>.json — a failed fetch is cached too, so a stopped dashboard costs one timeout per 30 s, not one per prompt. When the dashboard is down the part is simply left out. The script never throws, stops itself after 2.5 s and always exits 0. The dashboard is found like the CLI finds it (AGENTHUB_URL, then CLAUDE_DASHBOARD_PORT/DASHBOARD_PORT, then ~/.claude/.agenthub.json); DASHBOARD_TOKEN (else the token the running dashboard publishes in <data dir>/runtime/dashboard-token) is sent when there is one.

Install / uninstall

Nothing is installed automatically. Run:

agenthub statusline install            # adds statusLine to ~/.claude/settings.json
agenthub statusline install --force    # also replaces a statusLine that is not AgentHub's
agenthub statusline uninstall          # removes AgentHub's statusLine only
agenthub statusline uninstall --force  # removes whatever statusLine is there
  • The file is $CLAUDE_HOME/settings.json (default ~/.claude/settings.json); every other key is kept.
  • A statusLine that is not AgentHub's is refused (exit 1) unless --force.
  • Before any write the old file is copied beside itself as settings.json.agenthub-backup-<timestamp>.
  • A plugin install registers "~/.local/bin/agenthub" statusline (absolute path) — the launcher the bootstrap repoints at every update, because the plugin cache directory is replaced on update. A checkout registers node "<checkout>/statusline/statusline.js".

agenthub statusline with no subcommand renders the line from stdin, which is what the plugin-install registration runs.

Tests

server/__tests__/statusline.test.js: the formatter, today's cost against a fake dashboard (cache, cached failure, timeout), the script end to end on stdin, and install/uninstall against a temp HOME.