diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..b9040aa --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,88 @@ +name: Validate + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: LICENSE exists + run: test -s LICENSE || (echo "::error::LICENSE missing or empty" && exit 1) + + - name: CHANGELOG.md exists + run: test -s CHANGELOG.md || (echo "::error::CHANGELOG.md missing or empty" && exit 1) + + - name: Bash syntax check on all .sh files + run: | + set -e + fail=0 + for f in $(git ls-files '*.sh'); do + if ! bash -n "$f"; then + echo "::error file=$f::bash syntax error" + fail=1 + fi + done + exit $fail + + - name: ShellCheck + # Severity 'error' only — style warnings (SC1090 dynamic source, + # SC2034 unused vars, SC2155 declare-and-assign) are tracked + # separately and do not gate this workflow. + uses: ludeeus/action-shellcheck@master + with: + severity: error + scandir: '.' + continue-on-error: false + + - name: All docs/* assets referenced from README exist + run: | + set -e + fail=0 + for ref in $(grep -hoE 'docs/[a-zA-Z0-9_/-]+\.(svg|png|jpg|jpeg|gif)' README.md README.ru.md | sort -u); do + if [ ! -f "$ref" ]; then + echo "::error file=README.md::missing referenced asset $ref" + fail=1 + fi + done + exit $fail + + - name: Internal Markdown links resolve + run: | + set -e + fail=0 + for src in README.md README.ru.md CHANGELOG.md CONTRIBUTING.md CLAUDE.md; do + [ -f "$src" ] || continue + base="$(dirname "$src")" + for tgt in $(grep -hoE '\]\([^)]+\)' "$src" | sed 's/](\(.*\))/\1/' | sed 's/#.*$//'); do + case "$tgt" in + http*|mailto:*|"") continue ;; + esac + [ "$base" = "." ] && resolved="$tgt" || resolved="$base/$tgt" + if [ ! -e "$resolved" ] && [ ! -e "$tgt" ]; then + echo "::error file=$src::broken internal link → $tgt" + fail=1 + fi + done + done + exit $fail + + - name: SVG files are well-formed XML + run: | + set -e + fail=0 + for f in $(git ls-files 'docs/*.svg' '*.svg'); do + if ! python -c "import xml.etree.ElementTree as ET; ET.parse('$f')" 2>/dev/null; then + echo "::error file=$f::malformed SVG XML" + fail=1 + fi + done + exit $fail + + - name: statusline.conf is sourceable bash (no syntax errors) + run: bash -n statusline.conf diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..cf658e9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,50 @@ +# Changelog + +All notable changes to this project will be documented in this file. +Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · [SemVer](https://semver.org/spec/v2.0.0.html). + +## [0.2.0] — 2026-04-30 + +### Added + +- `docs/architecture.svg` — hand-rendered diagram of the cache-decoupling design (`vps-poller.sh` → `/tmp/vps-*.json` → `statusline.sh`, with the Claude Code transcript driving auto-focus). Renders inline in GitHub README. +- `docs/segments-annotated.svg` — explanatory diagram of every statusline segment with colour-coded labels above and below the rendered bar. +- `docs/screenshots/statusline-live.png` — embedded production screenshot from the [Habr article](https://habr.com/ru/articles/1013414/) (1560×256, 220 KB) showing a 100-hour Opus session with VPS auto-focus active. +- `CLAUDE.md` for this repository — a working Level 1 file documenting the architecture, key files, critical rules, commands, and patterns. Pairs with the [ai-context-hierarchy](https://github.com/CreatmanCEO/ai-context-hierarchy) sister repo. +- `CHANGELOG.md` (this file) +- `CONTRIBUTING.md` with a priority list for community submissions +- `.github/workflows/validate.yml` — CI checking `bash -n` syntax on all `.sh` files, `shellcheck -S warning` lint, internal Markdown link resolution, presence of `LICENSE` and `CHANGELOG.md`, and that every diagram referenced from README actually exists in `docs/` +- `Limitations` section in both READMEs covering the transcript-window heuristic, OS credential storage assumption, bash + jq requirement, global SSH timeout behaviour, lack of metric history, Windows-tmux unsupported, daemon being best-effort +- `Related` section cross-linking to [Claude Code Anti-Regression Setup](https://github.com/CreatmanCEO/claude-code-antiregression-setup) and [ai-context-hierarchy](https://github.com/CreatmanCEO/ai-context-hierarchy) (sister repos, same author) +- "Stars", "Validate", "Featured on Habr 9.3K reads", "Claude Code Opus 4.7" badges + +### Changed + +- README hero rewritten to lead with two social-proof signals (Habr article + 9.3K reads, Anthropic compatibility) and the one-line value proposition (`pure bash + jq, no Node.js`) — previously the value proposition was below the fold +- `What it shows` table renamed to `What every segment tells you` and is now anchored by the new annotated SVG diagram +- New `Architecture` section with the cache-decoupling diagram and a component-role table (was implicit in the configuration knobs only) +- `Configuration` table extended to include the previously undocumented `VPS_POLL_INTERVAL`, `VPS_SSH_TIMEOUT`, `VPS_STALE_SEC`, `COST_MODEL`, `TMUX_BRIDGE` knobs +- `Troubleshooting` section gained `VPS shows DOWN but server is fine` and `Auto-focus picks the wrong VPS` entries +- Author signature expanded with Habr / dev.to profile links + +### Notes + +- `screenshot.svg` (the original placeholder) is retained for backward-compat URLs; the README now references the live `statusline-live.png` and the annotated `segments-annotated.svg` instead. +- Topics on GitHub applied separately via `gh api` after merge. + +## [0.1.0] — 2026-03-22 + +### Added + +- Initial release accompanying the [Habr article](https://habr.com/ru/articles/1013414/) (9.3K reads as of writing) +- `statusline.sh` — model · git · lines · cost · usage limits · session duration · VPS health · context % +- `vps-poller.sh` — background SSH poller with atomic JSON cache writes +- `install.sh` — installer with `--vps` `--ru` `--tmux` `--minimal` `--uninstall` flags +- `statusline.conf` — full configuration schema with sensible defaults +- Auto-focus VPS detection via Claude Code transcript parsing (`ssh` / `scp` / `sftp` IP matching, with `VPS_MCP_MAP` fallback for MCP-only setups) +- 5-hour and weekly quota tracking via OAuth credential read from `~/.claude/.credentials.json` (inspired by [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline)) +- Automatic API-vs-subscription cost detection (cost = 0 → theoretical pricing; cost > 0 → real) +- tmux integration (`Prefix+y` popup) when running inside a tmux session +- Russian language pack (`LANG_RU=true`) — labels render as `стр / контекст / мин / etc.` +- Cross-platform support — Linux, macOS, Windows (via Git Bash / WSL) +- `LICENSE` (MIT) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2a6a492 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,57 @@ +# claude-statusline — CLAUDE.md (Level 1) + +## Status: ACTIVE +Public Claude Code statusline tool. Pure bash + jq. No Node.js. Cross-platform via Git Bash / WSL on Windows. + +## Architecture + +Three artefacts and one cache: + +- `vps-poller.sh` — background daemon. Runs `ssh root@host 'free / loadavg / df / uptime'` for each VPS every `VPS_POLL_INTERVAL` seconds (default 30 s). Writes one JSON file per VPS atomically via `mktemp + mv`. SSH timeout `VPS_SSH_TIMEOUT` seconds (default 5 s) → DOWN status. +- `/tmp/vps-.json` — cache. One file per VPS. Statusline reads these instead of blocking on SSH. +- `statusline.sh` — runs on every Claude Code prompt. Reads cache (~0 ms latency), parses transcript for active-VPS auto-focus, applies colour thresholds, prints one bash line. +- `~/.claude/projects/*.jsonl` — Claude Code transcript. Last 20 KB scanned for `ssh` / `scp` / `sftp` invocations to drive auto-focus. + +## Key Files + +- `statusline.sh` — main script (343 lines). Functions: `color_by_threshold`, `calc_api_cost` (model-specific token pricing), `get_usage_limits` (OAuth → 5h/weekly quota), `format_tokens`, `format_duration`, `get_vps_status`, `detect_active_vps`. +- `vps-poller.sh` — daemon (94 lines). Functions: `log`, `poll_server`, `poll_all`. Controls: `start` / `stop` / `restart` / `status`. +- `install.sh` — installer (108 lines). Flags: `--vps` `--ru` `--tmux` `--minimal` `--uninstall`. Idempotent — re-run safely. +- `statusline.conf` — config schema. All knobs commented with defaults. Gets copied to `~/.claude/statusline.conf` on install. + +## CRITICAL RULES — when editing this repo + +- **NEVER** break backward compatibility on `statusline.conf` keys without a `CHANGELOG.md` entry under "Breaking changes". Users have hand-edited configs in production. +- **ALWAYS** keep `statusline.sh` portable across `bash 4+ / 5+`, macOS BSD utilities, and Linux GNU utilities. No `awk` features specific to GNU awk only. No bash 5-only constructs (`${var//pattern/}` is fine; `wait -n -p` is not). +- **ALWAYS** maintain `set -euo pipefail` discipline in scripts. `source ~/.claude/statusline.conf` must not crash the line on a typo — wrap in `set +u; source; set -u` or guard with `|| true`. +- **NEVER** introduce a network call from `statusline.sh` itself. The whole design assumes statusline rendering is non-blocking (cache-only). All slow IO lives in `vps-poller.sh`. +- **ALWAYS** mirror `README.md` and `README.ru.md` when changing user-facing surface area. +- **ALWAYS** update `CHANGELOG.md` for any change visible to users (new config key, glyph change, behaviour change, breaking change). + +## Commands + +- `bash install.sh` — install to `~/.claude/` +- `bash install.sh --uninstall` — clean removal +- `~/claude-statusline/vps-poller.sh start | stop | status` — daemon control +- `tail -f /tmp/vps-poller.log` — watch poller +- `bash -n statusline.sh && bash -n vps-poller.sh && bash -n install.sh` — syntax check (CI runs this) +- `shellcheck statusline.sh vps-poller.sh install.sh` — lint (CI runs this with `-S warning`) + +## Key Patterns + +1. **Cache decoupling.** Slow side (SSH) writes; fast side (statusline) reads. The decoupling is what makes a statusline running every prompt feasible. +2. **Atomic writes.** `vps-poller.sh` writes via `mktemp` + `mv`. Statusline never reads a half-written cache. +3. **Auto-focus from transcript.** Parses last 20 KB of `~/.claude/projects/*.jsonl`. Two-strategy: `ssh`/`scp`/`sftp` IPs first, then `VPS_MCP_MAP` for MCP-only setups. +4. **Threshold colouring.** `color_by_threshold` is the single function that maps a numeric % to ANSI green/yellow/red based on warn/crit thresholds. Used for context, RAM, CPU, disk, quota. + +## Companion content + +- [Habr article](https://habr.com/ru/articles/1013414/) — 9.3K reads, describes design rationale and the auto-focus heuristic. + +## External validation + +- [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — original inspiration for the H/W limits feature. Credit kept in README and in this file. + +## Recent Changes + +See [CHANGELOG.md](CHANGELOG.md). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..dc71391 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing + +Thanks for considering a contribution. This is a focused tool, not a framework — the bar for new content is "real use case, portable bash, doesn't break the cache decoupling." + +## Priorities (highest impact first) + +1. **Per-distribution package targets** — `apt`, `brew`, `dnf`, `pacman` install paths. Currently install is `git clone` + `bash install.sh`; package targets would let people `brew install claude-statusline`. +2. **Additional language locales** — current set is English (default) and Russian (`LANG_RU=true`). New locales should follow the same pattern: a `LANG_XX=true` flag and a label dictionary at the top of `statusline.sh`. +3. **Alternative VPS metric backends** — currently `vps-poller.sh` runs `free / loadavg / df / uptime` over SSH. Sister backends welcome: + - **Netdata API** — local Netdata install on each VPS exposes `/api/v1/data?chart=…`. Faster, no SSH per poll. + - **Prometheus push** — VPS pushes metrics to a local Prometheus, statusline reads from `/api/v1/query`. + - **MCP `system_*` tools** — when MCP exposes a system-info tool, use it instead of SSH. +4. **Fish / Zsh shells** — `statusline.sh` works under bash. Sister scripts for fish (`statusline.fish`) and zsh (`statusline.zsh`) would let those users run natively without `bash` invocation. +5. **Per-glyph theming** — currently glyphs are hardcoded (`●` / `◉` / `✗` / `↻` / `▽`). A `GLYPH_*` config block would let users pick ASCII-only glyphs (`*` / `o` / `X` / `~` / `-`) for terminals without good Unicode rendering. +6. **systemd-user unit** — `vps-poller.sh start` is a detached process. A `systemd --user` unit file would survive reboots and integrate with `systemctl --user status vps-poller`. + +## What we will not merge + +- Changes that introduce a network call inside `statusline.sh`. The whole architecture rests on statusline being non-blocking; slow IO lives in the poller. +- Changes that break backward compatibility on `statusline.conf` keys without a `CHANGELOG.md` entry under "Breaking changes". Users have hand-edited configs in production. +- Changes that drop bash-portability (no `bash 5.1+`-only constructs, no GNU-only `awk`). +- New top-level scripts that duplicate `install.sh` / `statusline.sh` / `vps-poller.sh` responsibilities. Add an option to an existing script if possible. +- Pretty refactors with no user-visible benefit. This codebase fits in your head — keep it that way. + +## Pull request checklist + +- [ ] `bash -n` clean on every modified `.sh` file +- [ ] `shellcheck -S warning` clean (CI runs this) +- [ ] If `statusline.conf` schema changed: documented in README's `Configuration` table, listed in `CHANGELOG.md`, default kept backward-compatible +- [ ] If user-visible behaviour changed: `README.md` updated AND `README.ru.md` mirrored +- [ ] `CHANGELOG.md` entry under Unreleased or a new minor version +- [ ] `validate.yml` workflow passes locally + +## Style + +- Bash should look like bash, not Python. `[[` over `[`, `$()` over backticks, `local` for function variables, quoted variable expansions everywhere. +- Comment the *why*, never the *what*. `# poll every 30s — 5s SSH timeout × 3 servers must fit` is useful; `# loop 30 times` is not. +- Keep functions under 30 lines. If you need more, split. +- One feature per PR. Stack PRs if you have multiple. + +## Author / maintainer + +[@CreatmanCEO](https://github.com/CreatmanCEO) — Nick Podolyak. Open an issue first for anything larger than a config knob or a glyph. diff --git a/README.md b/README.md index 7d79b76..8d1c72c 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,49 @@ -
+# claude-statusline -🌐 **Language / Язык** +[![License: MIT](https://img.shields.io/github/license/CreatmanCEO/claude-statusline?color=yellow)](LICENSE) +[![Stars](https://img.shields.io/github/stars/CreatmanCEO/claude-statusline?style=flat&color=yellow)](https://github.com/CreatmanCEO/claude-statusline/stargazers) +[![Validate](https://github.com/CreatmanCEO/claude-statusline/actions/workflows/validate.yml/badge.svg)](https://github.com/CreatmanCEO/claude-statusline/actions/workflows/validate.yml) +[![Featured on Habr](https://img.shields.io/badge/Habr-9.3K%20reads-77a2b6)](https://habr.com/ru/articles/1013414/) +[![Claude Code](https://img.shields.io/badge/Claude%20Code-Opus%204.7%20%C2%B7%201M%20context-cc785c)](https://code.claude.com) +[![bash](https://img.shields.io/badge/bash-pure%20%2B%20jq-4EAA25?logo=gnubash&logoColor=white)](https://www.gnu.org/software/bash/) +[![platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-blue)](#platforms) -[![English](https://img.shields.io/badge/English-blue?style=flat-square)](README.md) [![Русский](https://img.shields.io/badge/Русский-red?style=flat-square)](README.ru.md) +🇬🇧 English · [🇷🇺 Русский](README.ru.md) -
+**Smart status line for [Claude Code](https://code.claude.com) — model, cost, context, usage limits, VPS health — all at a glance while you code. Pure bash + `jq`, no Node.js.** *Featured on [Habr (9.3K reads)](https://habr.com/ru/articles/1013414/) — describes the design and the auto-focus VPS feature.* -# claude-statusline +![Live status line during a 100-hour Claude Code session](docs/screenshots/statusline-live.png) + +> Above: live capture of a 100-hour Opus session — 8320 lines of code written, $40 of API cost saved by the Max subscription, RAM/disk health of three VPS at a glance. From the [Habr article](https://habr.com/ru/articles/1013414/). + +## What every segment tells you -Smart status line for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) — model, cost, context, usage limits, VPS health — all at a glance while you code. +![Segment breakdown](docs/segments-annotated.svg) + +| Segment | Example | What it means | +|---|---|---| +| Model | `Opus 4.7` | Current model | +| Git | `main*` | Branch + dirty indicator | +| Lines | `+47/-12` | Lines added/removed this session | +| Cost | `~$3.85(api)` | Theoretical API cost (subscribers) or real cost (API users) | +| 5-hour quota | `H:82% 3h12m` | Remaining 5-hour quota and time-to-reset | +| Weekly quota | `W:94%` | Remaining 7-day quota | +| Duration | `45m` | Session time | +| VPS | `▶ main● new◉(R:92%) sec●` | Server health with auto-focus on the VPS you are working with | +| Context | `22% ctx` | Context window — green → yellow (50%) → red (70%, time for `/compact`) | -![claude-statusline](screenshot.svg) +## Architecture -[![MIT](https://img.shields.io/github/license/CreatmanCEO/claude-statusline?style=flat-square&color=green)](LICENSE) [![bash](https://img.shields.io/badge/bash-script-4EAA25?style=flat-square&logo=gnubash&logoColor=white)]() [![platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-blue?style=flat-square)]() +The design is one decision: **decouple slow SSH polling from instant statusline rendering through a `/tmp` cache.** The statusline runs on every Claude Code prompt — it cannot afford to block on a 5-second SSH timeout. -**No Node.js. No npm. Pure bash + jq.** +![Architecture: vps-poller writes cache, statusline reads cache, transcript drives auto-focus](docs/architecture.svg) + +| Component | Role | +|---|---| +| `vps-poller.sh` | Background daemon. Loops every 30 s, opens one SSH per VPS, runs `free / loadavg / df / uptime`, atomically writes `/tmp/vps-.json`. 5 s SSH timeout → DOWN status. | +| `/tmp/vps-*.json` | Cache. One file per VPS. Stale-after-120 s marker. | +| `statusline.sh` | Runs on every Claude Code prompt. Reads cache files (~0 ms), parses the last 20 KB of `~/.claude/projects/*.jsonl` for `ssh`/`scp`/`sftp` commands to detect the active VPS, applies colour thresholds, prints one line of bash. | +| `~/.claude/projects/*.jsonl` | Claude Code transcript. Used for **auto-focus**: whichever VPS the agent has SSH'd into most recently gets the `▶` marker with expanded RAM/Disk metrics. | ## Installation @@ -24,7 +53,7 @@ Open Claude Code (`claude` in your terminal) and say: Clone https://github.com/CreatmanCEO/claude-statusline and install via install.sh ``` -Or run directly in Claude Code: +Or run directly: ```bash git clone https://github.com/CreatmanCEO/claude-statusline.git ~/claude-statusline && bash ~/claude-statusline/install.sh @@ -32,28 +61,27 @@ git clone https://github.com/CreatmanCEO/claude-statusline.git ~/claude-statusli Restart Claude Code. The status line appears automatically. -> **Windows:** Run from inside Claude Code, not from PowerShell/cmd directly (`.sh` files need bash). +> **Windows:** Run from inside Claude Code, not from PowerShell/cmd directly (`.sh` files need bash). See [Troubleshooting](#troubleshooting) below. -## What it shows +### Install options -| Segment | Example | Description | -|---------|---------|-------------| -| Model | `Opus 4.6` | Current model | -| Git | `main*` | Branch + dirty indicator | -| Lines | `+47/-12` | Lines added/removed this session | -| Cost | `~$3.85(api)` | Theoretical API cost for subscribers; real cost for API users | -| Limits | `H:82% 3h12m W:94%` | 5-hour and 7-day quota remaining | -| Duration | `45m` | Session time | -| VPS | `main● sec●(R:45% D:48%)` | Server health with auto-focus | -| Context | `22% ctx` | Context window usage (green → yellow → red) | +```bash +bash ~/claude-statusline/install.sh # basic — model, cost, context, lines, duration, git +bash ~/claude-statusline/install.sh --vps # + VPS monitoring +bash ~/claude-statusline/install.sh --ru # Russian labels (стр, контекст, мин) +bash ~/claude-statusline/install.sh --tmux # tmux integration (Prefix+y popup) +bash ~/claude-statusline/install.sh --minimal # just model + context +bash ~/claude-statusline/install.sh --uninstall +``` ## VPS Monitoring -For developers working with remote servers via MCP SSH — see your VPS health without switching context. +For developers working with remote servers via Bash SSH or MCP SSH — see VPS health without switching context. ### Step 1 — Add servers Tell Claude Code: + ``` Open ~/.claude/statusline.conf and add: @@ -66,26 +94,23 @@ VPS_SERVERS=( ### Step 2 — Start the poller -Tell Claude Code: ``` Run ~/claude-statusline/vps-poller.sh start ``` -The poller runs in background, polling servers every 30s via SSH. +The poller runs in background, polling servers every 30 s via SSH. Logs to `/tmp/vps-poller.log`. ### Step 3 — Auto-focus active server -The statusline automatically detects which VPS you're working on — no extra config needed. It parses the Claude Code transcript for `ssh`/`scp`/`sftp` commands and matches IPs against your `VPS_SERVERS`. - -The active server gets a `▶` marker with expanded RAM/Disk metrics: +The statusline automatically detects which VPS you are working on by parsing the Claude Code transcript for `ssh` / `scp` / `sftp` commands and matching IPs against your `VPS_SERVERS`. Active VPS gets the `▶` marker with expanded RAM/Disk metrics: ``` main● ▶ new●(R:58% D:68%) sec● ``` -This works with both Bash SSH (`ssh root@1.2.3.4`) and MCP SSH. For MCP-only setups, add an optional mapping: +This works with both Bash SSH (`ssh root@1.2.3.4`) and MCP SSH (when MCP servers reuse the same IPs). For MCP-only setups where IPs are not visible in the transcript, add an explicit mapping: -``` +```bash VPS_FOCUS=auto VPS_MCP_MAP=( "prod|my-mcp-prod" @@ -93,43 +118,64 @@ VPS_MCP_MAP=( ) ``` -**Statuses:** 🟢● OK | 🟠◉ WARN (>80%) | 🔴✗ DOWN | 🟣↻ BOOT +**Status glyphs:** 🟢 `●` OK · 🟠 `◉` WARN (>80%) · 🔴 `✗` DOWN · 🟣 `↻` BOOT · ⚪ `▽` STALE (cache > 120 s) ## Usage Limits (H/W) -Shows remaining 5-hour (`H:82% 3h12m`) and 7-day (`W:94%`) quotas for Max/Pro/Team subscribers. Color-coded: green >50%, yellow 20-50%, red <20%. +`H:82% 3h12m` shows remaining 5-hour quota; `W:94%` shows weekly quota. For Max / Pro / Team subscribers. Color-coded: green > 50%, yellow 20–50%, red < 20%. -Requires `claude login` authentication. Data cached for 2 minutes. +Reads OAuth token from `~/.claude/.credentials.json` after `claude login`. Cached for 2 minutes. -> Inspired by [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — thanks for the OAuth API documentation! +> Inspired by [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — thanks for documenting the OAuth API. If you only need quota tracking without VPS monitoring, his version is leaner. ## Configuration -All settings in `~/.claude/statusline.conf`. Changes apply automatically — no restart needed. - -Tell Claude Code: `Show my ~/.claude/statusline.conf` +All settings in `~/.claude/statusline.conf`. Changes apply on the next Claude Code response — no restart needed. | Parameter | Values | Description | -|-----------|--------|-------------| -| `SHOW_MODEL` | true/false | Model name | -| `SHOW_COST` | true/false | API cost | -| `SHOW_LIMITS` | true/false | H/W quotas | -| `SHOW_CONTEXT` | true/false | Context % | -| `SHOW_LINES` | true/false | Lines changed | -| `SHOW_DURATION` | true/false | Session time | -| `SHOW_GIT` | true/false | Git branch | -| `SHOW_TOKENS` | true/false | Token counts | -| `SHOW_VPS` | false/remote/local | VPS monitoring | -| `VPS_FOCUS` | auto/none/name | Auto-detect active VPS from transcript | -| `LANG_RU` | true/false | Russian labels | -| `CONTEXT_WARN` | 50 | Yellow threshold | -| `CONTEXT_CRIT` | 70 | Red threshold | +|---|---|---| +| `SHOW_MODEL` | true / false | Model name | +| `SHOW_COST` | true / false | API cost | +| `SHOW_LIMITS` | true / false | H/W quotas | +| `SHOW_CONTEXT` | true / false | Context % | +| `SHOW_LINES` | true / false | Lines changed | +| `SHOW_DURATION` | true / false | Session time | +| `SHOW_GIT` | true / false | Git branch | +| `SHOW_TOKENS` | true / false | Raw token counts | +| `SHOW_VPS` | false / remote / local | VPS monitoring mode | +| `VPS_FOCUS` | auto / none / `` | Auto-detect active VPS from transcript | +| `LANG_RU` | true / false | Russian labels | +| `CONTEXT_WARN` | 50 | % context → yellow | +| `CONTEXT_CRIT` | 70 | % context → red | +| `VPS_POLL_INTERVAL` | 30 | Poller interval (s) | +| `VPS_SSH_TIMEOUT` | 5 | SSH timeout — DOWN if exceeded | +| `VPS_STALE_SEC` | 120 | Cache older than this = stale `▽` | +| `COST_MODEL` | auto / opus / sonnet / haiku | Cost calc model selector | +| `TMUX_BRIDGE` | auto / on / off | tmux integration | + +Full list with defaults — see [`statusline.conf`](statusline.conf). + +## Useful Claude Code commands + +- `/cost` — session cost and tokens +- `/context` — detailed context window breakdown +- `/compact` — compress context (when status line turns red) +- `/model sonnet` — switch model + +## Platforms + +| | Status | Metrics | tmux | +|---|---|---|---| +| **Linux** | ✅ | ✅ | ✅ | +| **macOS** | ✅ | ✅ | ✅ | +| **Windows** (via Claude Code in Git Bash / WSL) | ✅ | ✅ | — | ## Troubleshooting ### Status line disappeared after install (Windows) -On Windows, `.sh` files don't execute directly. Tell Claude Code: +`.sh` files do not execute from cmd / PowerShell. Tell Claude Code: + ``` In ~/.claude/settings.json set statusLine.command to: bash /c/Users/YOUR_NAME/.claude/statusline.sh ``` @@ -137,38 +183,55 @@ In ~/.claude/settings.json set statusLine.command to: bash /c/Users/YOUR_NAME/.c ### H/W limits not showing 1. Run `claude login` if not authenticated -2. Tell Claude Code: `Check if ~/.claude/.credentials.json exists` -3. If not found — limits are silently skipped, everything else works +2. Check that `~/.claude/.credentials.json` exists +3. If not — limits are silently skipped, the rest of the statusline keeps working -## Install options +### VPS shows DOWN but the server is fine -```bash -bash ~/claude-statusline/install.sh # basic -bash ~/claude-statusline/install.sh --ru # Russian labels -bash ~/claude-statusline/install.sh --tmux # tmux integration (Prefix+y popup) -bash ~/claude-statusline/install.sh --minimal # model + context only -bash ~/claude-statusline/install.sh --uninstall -``` +- SSH timeout (5 s by default) too aggressive on slow networks → raise `VPS_SSH_TIMEOUT` +- SSH key not loaded → `ssh-add ~/.ssh/my_key` +- Firewall / ufw blocking outbound from your machine → check `/tmp/vps-poller.log` -## Useful Claude Code commands +### Auto-focus picks the wrong VPS -- `/cost` — session cost and tokens -- `/context` — detailed context window breakdown -- `/compact` — compress context (when status line turns red) -- `/model sonnet` — switch model +- Transcript parser only scans the last 20 KB. After many tool calls, the relevant `ssh` invocation can scroll out → manually pin via `VPS_FOCUS=` until the next session +- For MCP-only SSH where IPs are hidden, configure `VPS_MCP_MAP` -## Platforms +## Limitations -| | Status | Metrics | tmux | -|---|---|---|---| -| **Linux** | ✅ | ✅ | ✅ | -| **macOS** | ✅ | ✅ | ✅ | -| **Windows** (via Claude Code) | ✅ | ✅ | — | +This is a personal-tool, not a managed service. Honest constraints: + +- **Transcript parsing is heuristic.** The auto-focus reads the last 20 KB of the Claude Code transcript JSONL. In long sessions with heavy MCP traffic, the relevant `ssh` invocation can scroll out of that window. Workaround: pin manually via `VPS_FOCUS=`. +- **OS credential storage assumption.** Usage limits are read from `~/.claude/.credentials.json`. If Anthropic changes the credential storage format, limits will silently fail to render until the script is updated. +- **Bash + jq required.** The script will not run on systems without `bash` (4+) and `jq`. PowerShell / fish / dash are not supported. WSL is fine. +- **SSH timeout is global.** A single slow VPS does not slow down the statusline (poller is async), but a uniformly slow network can cause all VPS to flicker DOWN/UP. Raise `VPS_SSH_TIMEOUT` in this case. +- **No metric history.** Statusline only shows current snapshot. For trend graphs use Grafana, Netdata, or Prometheus — this tool answers "is anything on fire **right now**", not "how was load yesterday". +- **Windows tmux integration is unsupported.** tmux on Windows is fragile in general; the `--tmux` flag is Linux/macOS-only. +- **Daemon is best-effort.** `vps-poller.sh start` runs as a detached process — it does not register a systemd unit. If the host reboots, restart the poller manually (or wrap it in your own `systemctl --user` unit). + +## Related + +- [Claude Code Anti-Regression Setup](https://github.com/CreatmanCEO/claude-code-antiregression-setup) — sister repo, same author. Complementary purpose: this statusline tells you where context is *now*; the anti-regression setup keeps Claude from corrupting it. +- [ai-context-hierarchy](https://github.com/CreatmanCEO/ai-context-hierarchy) — sister repo. Three-level context system that pairs naturally with the auto-focus VPS feature here (Level 0 lists your servers, statusline tells you which one is hot). +- [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — original inspiration for the H/W limits feature; leaner if you only need quota tracking. +- [awesome-claude-code](https://github.com/hesreallyhim/awesome-claude-code) — curated skills, hooks, agents. + +## Companion article + +- [Habr (RU) — Как я собрал statusline для Claude Code с мониторингом VPS за одну сессию](https://habr.com/ru/articles/1013414/) — 9.3K reads. Covers the cache decoupling, auto-focus heuristic, and cost-calculation logic. + +## Contributing + +PRs welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Current priorities: per-distribution package targets (`apt`, `brew`, `dnf`), additional language locales, alternative VPS metric backends (Netdata API, Prometheus push, MCP `system_*` tools), Fish/Zsh shells. + +## Author -## Credits +**Nick Podolyak** — Python developer and digital architect at [CREATMAN](https://creatman.site) -H/W usage limits feature inspired by [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — thank you for the idea and OAuth API documentation! If you only need limits without VPS monitoring, check out his version. +- GitHub: [@CreatmanCEO](https://github.com/CreatmanCEO) +- Habr: [creatman](https://habr.com/ru/users/creatman/) +- dev.to: [@creatman](https://dev.to/creatman) ## License -MIT — [Nick Podolyak](https://github.com/CreatmanCEO) / CREATMAN Studio +[MIT](LICENSE) · Nick Podolyak diff --git a/README.ru.md b/README.ru.md index 51c7741..5e66c6d 100644 --- a/README.ru.md +++ b/README.ru.md @@ -1,180 +1,237 @@ -
+# claude-statusline -🌐 **Language / Язык** +[![License: MIT](https://img.shields.io/github/license/CreatmanCEO/claude-statusline?color=yellow)](LICENSE) +[![Stars](https://img.shields.io/github/stars/CreatmanCEO/claude-statusline?style=flat&color=yellow)](https://github.com/CreatmanCEO/claude-statusline/stargazers) +[![Validate](https://github.com/CreatmanCEO/claude-statusline/actions/workflows/validate.yml/badge.svg)](https://github.com/CreatmanCEO/claude-statusline/actions/workflows/validate.yml) +[![Habr](https://img.shields.io/badge/Habr-9.3K%20%D1%87%D1%82%D0%B5%D0%BD%D0%B8%D0%B9-77a2b6)](https://habr.com/ru/articles/1013414/) +[![Claude Code](https://img.shields.io/badge/Claude%20Code-Opus%204.7%20%C2%B7%201M%20context-cc785c)](https://code.claude.com) +[![bash](https://img.shields.io/badge/bash-pure%20%2B%20jq-4EAA25?logo=gnubash&logoColor=white)](https://www.gnu.org/software/bash/) +[![platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-blue)](#платформы) -[![English](https://img.shields.io/badge/English-blue?style=flat-square)](README.md) [![Русский](https://img.shields.io/badge/Русский-red?style=flat-square)](README.ru.md) +🇷🇺 Русский · [🇬🇧 English](README.md) -
+**Умная статус-строка для [Claude Code](https://code.claude.com) — модель, стоимость, контекст, лимиты, здоровье VPS — всё одним взглядом, не выходя из потока. Чистый bash + `jq`, без Node.js.** *Описание дизайна и фичи авто-фокуса — в [статье на Хабре (9.3K чтений)](https://habr.com/ru/articles/1013414/).* -# claude-statusline +![Живая статус-строка во время 100-часовой сессии Claude Code](docs/screenshots/statusline-live.png) + +> Выше: реальный кадр 100-часовой сессии Opus — 8320 строк кода, $40 «сэкономлено» подпиской Max, RAM/диск трёх VPS одним взглядом. Скриншот из [статьи на Хабре](https://habr.com/ru/articles/1013414/). + +## Что значит каждый сегмент + +![Разбор сегментов](docs/segments-annotated.svg) + +| Сегмент | Пример | Что значит | +|---|---|---| +| Модель | `Opus 4.7` | Текущая модель | +| Git | `main*` | Ветка + индикатор «грязного» дерева | +| Строки | `+47/-12` | Добавлено/удалено за сессию | +| Стоимость | `~$3.85(api)` | Теоретическая API-цена (для подписчиков) или реальная (для API-юзеров) | +| 5-часовая квота | `H:82% 3h12m` | Остаток + время до сброса | +| Недельная квота | `W:94%` | Остаток 7-дневной квоты | +| Длительность | `45m` | Время сессии | +| VPS | `▶ main● new◉(R:92%) sec●` | Здоровье серверов с авто-фокусом на активный | +| Контекст | `22% ctx` | Зелёный → жёлтый (50%) → красный (70%, время `/compact`) | -Умный status line для [Claude Code](https://docs.anthropic.com/en/docs/claude-code) — модель, стоимость, контекст, лимиты, состояние VPS — всё перед глазами прямо во время работы. +## Архитектура -![claude-statusline](screenshot.svg) +Главное архитектурное решение — **развязать медленный SSH-опрос и мгновенный рендеринг статус-строки через кэш в `/tmp`.** Statusline запускается на каждом промпте Claude Code — он не может позволить себе блокировку на 5-секундном SSH-таймауте. -[![MIT](https://img.shields.io/github/license/CreatmanCEO/claude-statusline?style=flat-square&color=green)](LICENSE) [![bash](https://img.shields.io/badge/bash-script-4EAA25?style=flat-square&logo=gnubash&logoColor=white)]() [![platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-blue?style=flat-square)]() +![Архитектура: vps-poller пишет кэш, statusline читает кэш, transcript управляет авто-фокусом](docs/architecture.svg) -**Без Node.js. Без npm. Чистый bash + jq.** +| Компонент | Роль | +|---|---| +| `vps-poller.sh` | Фоновый демон. Цикл каждые 30 с, один SSH на сервер, выполняет `free / loadavg / df / uptime`, атомарно пишет `/tmp/vps-.json`. SSH-таймаут 5 с → DOWN. | +| `/tmp/vps-*.json` | Кэш. По одному файлу на VPS. Маркер «устаревшее > 120 с». | +| `statusline.sh` | Запускается на каждом промпте Claude Code. Читает кэш (~0 мс), парсит последние 20 КБ `~/.claude/projects/*.jsonl` для `ssh`/`scp`/`sftp`-команд (определяет активный VPS), применяет цветовые пороги, печатает одну строку bash. | +| `~/.claude/projects/*.jsonl` | Transcript Claude Code. Используется для **авто-фокуса**: тот VPS, в который агент только что подключался, получает маркер `▶` с расширенными метриками RAM/Disk. | ## Установка -Запусти Claude Code (`claude` в терминале) и скажи: +Открой Claude Code (`claude` в терминале) и скажи: ``` -Клонируй https://github.com/CreatmanCEO/claude-statusline и установи через install.sh --ru +Клонируй https://github.com/CreatmanCEO/claude-statusline и установи через install.sh ``` -Или выполни прямо в Claude Code: +Или напрямую: ```bash -git clone https://github.com/CreatmanCEO/claude-statusline.git ~/claude-statusline && bash ~/claude-statusline/install.sh --ru +git clone https://github.com/CreatmanCEO/claude-statusline.git ~/claude-statusline && bash ~/claude-statusline/install.sh ``` -Перезапусти Claude Code. Статус-линия появится автоматически. +Перезапусти Claude Code. Статус-строка появится автоматически. -> **Windows (PowerShell/cmd):** Запускай из Claude Code, не из PowerShell напрямую (`.sh` файлы требуют bash). +> **Windows:** запускай из Claude Code, не из cmd/PowerShell (`.sh` нужен bash). См. [Troubleshooting](#troubleshooting) ниже. -## Что показывает +### Опции установки -| Сегмент | Пример | Описание | -|---------|--------|----------| -| Модель | `Opus 4.6` | Текущая модель | -| Git | `main*` | Ветка + незакоммиченные изменения | -| Строки | `+47/-12 стр` | Добавлено/удалено за сессию | -| Стоимость | `~$3.85(api)` | Теоретическая для подписки; реальная для API | -| Лимиты | `H:82% 3h12m W:94%` | Остаток 5-часовой и 7-дневной квоты | -| Время | `45мин` | Длительность сессии | -| VPS | `main● sec●(R:45% D:48%)` | Состояние серверов с авто-фокусом | -| Контекст | `22% контекст` | Заполнение контекста (зелёный → жёлтый → красный) | +```bash +bash ~/claude-statusline/install.sh # базовая +bash ~/claude-statusline/install.sh --vps # + VPS-мониторинг +bash ~/claude-statusline/install.sh --ru # русские подписи +bash ~/claude-statusline/install.sh --tmux # tmux-интеграция (Prefix+y popup) +bash ~/claude-statusline/install.sh --minimal # только модель + контекст +bash ~/claude-statusline/install.sh --uninstall +``` ## VPS-мониторинг -Для разработчиков, работающих с серверами через MCP SSH — состояние VPS не отвлекаясь от кода. +Для тех, кто работает с удалёнными серверами через Bash SSH или MCP SSH — видишь здоровье VPS не переключаясь. -### Шаг 1 — Добавить серверы +### Шаг 1 — добавить серверы Скажи Claude Code: + ``` Открой ~/.claude/statusline.conf и добавь: SHOW_VPS=remote VPS_SERVERS=( - "main|95.85.234.200|22|root|~/.ssh/claude_vps" - "new|95.85.235.189|22|root|~/.ssh/claude_vps" - "sec|178.17.50.45|22|root|~/.ssh/claude_vps_key" + "prod|1.2.3.4|22|root|~/.ssh/my_key" + "staging|5.6.7.8|22|root|~/.ssh/my_key" ) ``` -Замени IP, юзеров и пути к ключам на свои. +### Шаг 2 — запустить поллер -### Шаг 2 — Запустить поллер - -Скажи Claude Code: ``` Запусти ~/claude-statusline/vps-poller.sh start ``` -Поллер работает в фоне, опрашивает серверы каждые 30 секунд по SSH. +Поллер крутится в фоне, опрашивает серверы каждые 30 с по SSH. Логи — в `/tmp/vps-poller.log`. -### Шаг 3 — Авто-фокус активного VPS +### Шаг 3 — авто-фокус активного сервера -Статуслайн автоматически определяет, с каким VPS ты сейчас работаешь — никакой дополнительной настройки не нужно. Он парсит transcript Claude Code на наличие команд `ssh`/`scp`/`sftp` и сопоставляет IP с `VPS_SERVERS`. - -Активный сервер получает маркер `▶` с развёрнутыми метриками RAM/Disk: +Statusline сам определяет, с каким VPS ты сейчас работаешь, парся последние 20 КБ Claude Code transcript на `ssh`/`scp`/`sftp` и сопоставляя IP с `VPS_SERVERS`. Активный VPS получает маркер `▶` с расширенными метриками RAM/Disk: ``` main● ▶ new●(R:58% D:68%) sec● ``` -Работает и с Bash SSH (`ssh root@1.2.3.4`), и с MCP SSH. Для MCP-only конфигураций добавь опциональный маппинг: +Работает и с Bash SSH (`ssh root@1.2.3.4`), и с MCP SSH (если MCP-серверы используют те же IP). Для MCP-only сетапов, где IP не виден в transcript, добавь явный маппинг: -``` +```bash VPS_FOCUS=auto VPS_MCP_MAP=( - "main|vps-main" - "new|vps-new" - "sec|vps-secondary" + "prod|my-mcp-prod" + "staging|my-mcp-staging" ) ``` -Переключился на другой сервер → метрики переключились автоматически. - -**Статусы:** 🟢● ОК | 🟠◉ WARN (>80%) | 🔴✗ DOWN | 🟣↻ BOOT +**Глифы статусов:** 🟢 `●` OK · 🟠 `◉` WARN (>80%) · 🔴 `✗` DOWN · 🟣 `↻` BOOT · ⚪ `▽` STALE (кэш > 120 с) ## Лимиты использования (H/W) -Показывает остаток 5-часовой (`H:82% 3h12m`) и 7-дневной (`W:94%`) квоты для подписчиков Max/Pro/Team. Цвета: зелёный >50%, жёлтый 20-50%, красный <20%. +`H:82% 3h12m` — остаток 5-часовой квоты + время до сброса; `W:94%` — недельной. Для подписчиков Max / Pro / Team. Цвет: зелёный > 50%, жёлтый 20–50%, красный < 20%. + +Читает OAuth-токен из `~/.claude/.credentials.json` после `claude login`. Кэш 2 минуты. -Требуется авторизация через `claude login`. Данные кэшируются на 2 минуты. +> Идею взял у [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — спасибо за документацию OAuth API. Если нужны только лимиты без VPS-мониторинга — его версия легче. -> Вдохновлено проектом [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — спасибо за идею и документацию OAuth API! +## Конфигурация -## Настройка +Все настройки в `~/.claude/statusline.conf`. Изменения применяются при следующем ответе Claude Code — перезапуск не нужен. + +| Параметр | Значения | Описание | +|---|---|---| +| `SHOW_MODEL` | true / false | Имя модели | +| `SHOW_COST` | true / false | API-стоимость | +| `SHOW_LIMITS` | true / false | Квоты H/W | +| `SHOW_CONTEXT` | true / false | % контекста | +| `SHOW_LINES` | true / false | Изменённые строки | +| `SHOW_DURATION` | true / false | Время сессии | +| `SHOW_GIT` | true / false | Git-ветка | +| `SHOW_TOKENS` | true / false | Сырые счётчики токенов | +| `SHOW_VPS` | false / remote / local | Режим VPS-мониторинга | +| `VPS_FOCUS` | auto / none / `<имя>` | Авто-определение активного VPS | +| `LANG_RU` | true / false | Русские подписи | +| `CONTEXT_WARN` | 50 | % контекста → жёлтый | +| `CONTEXT_CRIT` | 70 | % контекста → красный | +| `VPS_POLL_INTERVAL` | 30 | Интервал опроса (с) | +| `VPS_SSH_TIMEOUT` | 5 | Таймаут SSH — DOWN если превышен | +| `VPS_STALE_SEC` | 120 | Кэш старше — stale `▽` | +| `COST_MODEL` | auto / opus / sonnet / haiku | Селектор модели для расчёта | +| `TMUX_BRIDGE` | auto / on / off | tmux-интеграция | + +Полный список с дефолтами — см. [`statusline.conf`](statusline.conf). + +## Полезные команды Claude Code + +- `/cost` — стоимость и токены сессии +- `/context` — детальный разбор контекстного окна +- `/compact` — сжать контекст (когда статус-строка покраснела) +- `/model sonnet` — переключить модель -Все параметры в `~/.claude/statusline.conf`. Изменения подхватываются автоматически — перезапуск не нужен. +## Платформы -Скажи Claude Code: `Покажи мой ~/.claude/statusline.conf` +| | Статус | Метрики | tmux | +|---|---|---|---| +| **Linux** | ✅ | ✅ | ✅ | +| **macOS** | ✅ | ✅ | ✅ | +| **Windows** (через Claude Code в Git Bash / WSL) | ✅ | ✅ | — | -| Параметр | Значения | Что делает | -|----------|----------|------------| -| `SHOW_MODEL` | true/false | Имя модели | -| `SHOW_COST` | true/false | Стоимость | -| `SHOW_LIMITS` | true/false | Лимиты H/W | -| `SHOW_CONTEXT` | true/false | Процент контекста | -| `SHOW_LINES` | true/false | +/- строки | -| `SHOW_DURATION` | true/false | Время сессии | -| `SHOW_GIT` | true/false | Git branch | -| `SHOW_TOKENS` | true/false | Токены | -| `SHOW_VPS` | false/remote/local | VPS-мониторинг | -| `VPS_FOCUS` | auto/none/имя | Авто-определение активного VPS из transcript | -| `LANG_RU` | true/false | Русские подписи | -| `CONTEXT_WARN` | 50 | Жёлтый порог | -| `CONTEXT_CRIT` | 70 | Красный порог | +## Troubleshooting -## Решение проблем +### После установки статус-строка пропала (Windows) -### Статуслайн пропал после установки (Windows) +`.sh`-файлы не выполняются из cmd / PowerShell. Скажи Claude Code: -На Windows `.sh` файлы не запускаются напрямую. Скажи Claude Code: ``` -В ~/.claude/settings.json замени statusLine.command на: bash /c/Users/ТВОЁ_ИМЯ/.claude/statusline.sh +В ~/.claude/settings.json установи statusLine.command в: bash /c/Users/YOUR_NAME/.claude/statusline.sh ``` -### Не отображаются лимиты H/W +### Лимиты H/W не отображаются -1. Выполни `claude login` если ещё не делал -2. Скажи Claude Code: `Проверь есть ли файл ~/.claude/.credentials.json` -3. Если не найден — лимиты тихо пропускаются, остальное работает +1. Запусти `claude login` если не залогинен +2. Проверь что `~/.claude/.credentials.json` существует +3. Если нет — лимиты тихо пропускаются, остальное работает -## Варианты установки +### VPS показывает DOWN, хотя сервер в порядке -В Claude Code: -```bash -bash ~/claude-statusline/install.sh --ru # базовая + русский -bash ~/claude-statusline/install.sh --ru --tmux # + tmux (popup по Prefix+y) -bash ~/claude-statusline/install.sh --minimal # только модель + контекст -bash ~/claude-statusline/install.sh --uninstall # удалить -``` +- Слишком жёсткий SSH-таймаут (5 с по умолчанию) на медленной сети → подними `VPS_SSH_TIMEOUT` +- Не загружен SSH-ключ → `ssh-add ~/.ssh/my_key` +- Firewall / ufw блокирует исходящие → проверь `/tmp/vps-poller.log` -## Полезные slash-команды Claude Code +### Авто-фокус выбирает не тот VPS -- `/cost` — стоимость сессии и токены -- `/context` — детальная разбивка контекстного окна -- `/compact` — сжать контекст (когда статус-линия красная) -- `/model sonnet` — переключить модель +- Парсер смотрит последние 20 КБ transcript. После многих tool-call'ов нужный `ssh` может уйти из окна → пин вручную через `VPS_FOCUS=<имя>` +- Для MCP-only SSH (IP скрыты) → настрой `VPS_MCP_MAP` -## Платформы +## Ограничения -| | Статус | Метрики | tmux | -|---|---|---|---| -| **Linux** | ✅ | ✅ | ✅ | -| **macOS** | ✅ | ✅ | ✅ | -| **Windows** (через Claude Code) | ✅ | ✅ | — | +Это персональный инструмент, не managed-сервис. Честные ограничения: + +- **Парсинг transcript эвристический.** Авто-фокус читает последние 20 КБ JSONL Claude Code. В длинных сессиях с интенсивным MCP-трафиком нужный `ssh`-вызов может уйти из окна. Workaround: пин через `VPS_FOCUS=<имя>`. +- **Допущение про OS credential storage.** Лимиты читаются из `~/.claude/.credentials.json`. Если Anthropic меняет формат — лимиты тихо ломаются до апдейта скрипта. +- **Требуется bash + jq.** Скрипт не запустится без `bash` (4+) и `jq`. PowerShell / fish / dash не поддерживаются. WSL — норм. +- **Глобальный SSH-таймаут.** Один медленный VPS не тормозит statusline (поллер асинхронен), но равномерно медленная сеть может вызывать мерцание DOWN/UP. Подними `VPS_SSH_TIMEOUT`. +- **Нет истории метрик.** Только текущий снимок. Для графиков — Grafana / Netdata / Prometheus. Этот инструмент отвечает «горит ли что-то **прямо сейчас**», а не «как было вчера». +- **tmux на Windows не поддерживается.** tmux под Windows в принципе хрупкий, флаг `--tmux` — только Linux/macOS. +- **Демон best-effort.** `vps-poller.sh start` — detached процесс, не systemd-юнит. После reboot хоста запускай поллер вручную (или оберни в свой `systemctl --user` юнит). + +## Связанные проекты + +- [Claude Code Anti-Regression Setup](https://github.com/CreatmanCEO/claude-code-antiregression-setup) — sister-репо, тот же автор. Дополняет: statusline показывает где контекст *сейчас*; anti-regression configs не дают Claude его испортить. +- [ai-context-hierarchy](https://github.com/CreatmanCEO/ai-context-hierarchy) — sister-репо. Трёхуровневая система контекста, которая натурально парится с авто-фокусом VPS (Level 0 — список серверов, statusline — кто из них горячий). +- [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — оригинальное вдохновение для фичи H/W лимитов; легче если нужны только квоты. +- [awesome-claude-code](https://github.com/hesreallyhim/awesome-claude-code) — кураторская подборка skills, hooks, agents. + +## Сопровождающая статья + +- [Habr — Как я собрал statusline для Claude Code с мониторингом VPS за одну сессию](https://habr.com/ru/articles/1013414/) — 9.3K чтений. Покрывает развязку через кэш, эвристику авто-фокуса и логику расчёта стоимости. + +## Контрибьют + +PR приветствуются — см. [CONTRIBUTING.md](CONTRIBUTING.md). Текущие приоритеты: пакеты для дистрибутивов (`apt`, `brew`, `dnf`), новые языковые локали, альтернативные backend'ы метрик VPS (Netdata API, Prometheus push, MCP `system_*` tools), Fish/Zsh. + +## Автор -## Благодарности +**Николай Подоляк (Nick Podolyak)** — Python-разработчик и цифровой архитектор в [CREATMAN](https://creatman.site) -Фича лимитов H/W вдохновлена проектом [@AndyShaman/claude-statusline](https://github.com/AndyShaman/claude-statusline) — спасибо за идею и документацию OAuth API! Если нужны только лимиты без VPS-мониторинга — рекомендуем его версию. +- GitHub: [@CreatmanCEO](https://github.com/CreatmanCEO) +- Habr: [creatman](https://habr.com/ru/users/creatman/) +- dev.to: [@creatman](https://dev.to/creatman) ## Лицензия -MIT — [Nick Podolyak](https://github.com/CreatmanCEO) / CREATMAN Studio +[MIT](LICENSE) · Николай Подоляк diff --git a/docs/architecture.svg b/docs/architecture.svg new file mode 100644 index 0000000..541f35e --- /dev/null +++ b/docs/architecture.svg @@ -0,0 +1,72 @@ + + + claude-statusline architecture — poller writes cache, statusline reads cache + Architecture: vps-poller.sh runs as a background daemon, polling each VPS over SSH every 30 seconds and writing JSON cache files to /tmp/vps-*.json. The statusline.sh script reads these cache files instantly on every Claude Code prompt — zero latency, zero blocking on SSH. The statusline also parses the Claude Code transcript to detect which VPS the user is currently working with via auto-focus. + + + + + claude-statusline architecture + cache decouples slow SSH polling from instant statusline rendering + + + + vps-poller.sh + background daemon + • loops every 30 s + • ssh root@host one-shot + • free / loadavg / df / uptime + • 5 s timeout → DOWN + + + + + writes + + + + /tmp/vps-*.json + cache files + • one file per VPS + • {ram, cpu, disk, uptime} + • stale > 120 s = ▽ + • atomic write via mktemp + + + + + reads + + + + statusline.sh + runs on every prompt + • reads cache (0 ms) + • parses transcript JSONL + • applies thresholds → colour + • prints one line of bash + + + + ~/.claude/projects/*.jsonl + Claude Code transcript + • last 20 KB scanned + • ssh / scp / sftp grep + + + + auto-focus VPS detection + + + + terminal status line + Opus 4.7 + main* + +47/-12 + ~$3.85 + H:82% + ▶ main● + new◉(R:92%) + 22% + model · git · lines · cost · limits · auto-focused VPS · context + diff --git a/docs/screenshots/statusline-live.png b/docs/screenshots/statusline-live.png new file mode 100644 index 0000000..bfbe0c0 Binary files /dev/null and b/docs/screenshots/statusline-live.png differ diff --git a/docs/segments-annotated.svg b/docs/segments-annotated.svg new file mode 100644 index 0000000..eea1a90 --- /dev/null +++ b/docs/segments-annotated.svg @@ -0,0 +1,93 @@ + + + claude-statusline — segments annotated + Annotated breakdown of the claude-statusline output: each segment shows model, git branch, lines added/removed, theoretical or real cost, 5-hour and weekly usage limits, session duration, VPS health with auto-focus marker, and context window percentage. + + + + + What every segment of claude-statusline tells you + + + + + + + Opus 4.7 + main* + +47/-12 + ~$3.85(api) + H:82% 3h12m + W:94% + 45m + ▶ main● + new◉(R:92%) + sec● + 22% ctx + + + + + + + model + + + + git + + + + lines + + + + cost + + + + 5-hour quota + + + + + + + weekly quota + + + + duration + + + + ▶ auto-focused VPS + + + + VPS over threshold + + + + VPS healthy + + + + context % + + + + + VPS status glyphs + ● ok + ◉ warn (>80%) + ✗ down + ↻ booting + ▽ stale (>120s) + + Auto-focus + ▶ marker = the VPS this Claude Code session has been actively SSH-ing into recently + + detection: parses last 20 KB of ~/.claude/projects/*.jsonl for ssh/scp/sftp commands and matches against VPS_SERVERS + +