mirror of
https://github.com/Andre-Bzk/claude-statusline-kit.git
synced 2026-11-15 15:43:03 +01:00
feat: add portable Claude Code statusline kit
Replicating the cship-based statusline across machines meant manually copying three files and hand-editing settings.json with per-user absolute paths — error-prone and slow. Bundling the assets with an idempotent installer that resolves the pwsh path at runtime and merges into an existing settings.json makes rollout a single command per PC.
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
# Local install artefacts / backups
|
||||
*.bak
|
||||
settings.json.bak
|
||||
@@ -0,0 +1,110 @@
|
||||
[English](#english) | [Deutsch](#deutsch)
|
||||
|
||||
---
|
||||
|
||||
## English
|
||||
|
||||
# Claude Code Statusline Kit
|
||||
|
||||
A portable, self-contained kit that installs a custom Claude Code statusline
|
||||
(built on the [`cship`](https://cship.dev) Starship fork) onto any Windows PC
|
||||
with a single command.
|
||||
|
||||
### What it installs
|
||||
|
||||
| Asset | Target location | Purpose |
|
||||
| ----------------------------- | -------------------------- | ----------------------------------------- |
|
||||
| `assets/cship.exe` | `~/.local/bin/` | Renders the statusline |
|
||||
| `assets/cship.toml` | `~/.config/` | Module config (colors, icons, bars) |
|
||||
| `assets/cship-statusline.ps1` | `~/.claude/` | Wrapper (progress bars, token formatting) |
|
||||
| `statusLine` block | `~/.claude/settings.json` | Wires everything into Claude Code |
|
||||
|
||||
### Requirements
|
||||
|
||||
- **PowerShell 7** (`pwsh`). Install: `winget install --id Microsoft.PowerShell -e`
|
||||
- A terminal font with **emoji / Nerd-Font glyphs** (e.g. Cascadia Code,
|
||||
JetBrainsMono Nerd Font) so `🤖 ⚡ 🧠 █░` render correctly.
|
||||
|
||||
### Install on a new PC
|
||||
|
||||
```powershell
|
||||
git clone <your-repo-url> Claude_Statusline
|
||||
cd Claude_Statusline
|
||||
.\install.ps1
|
||||
```
|
||||
|
||||
Then restart Claude Code (or start a new session).
|
||||
|
||||
The installer is **idempotent** — run it again anytime. It auto-detects the
|
||||
`pwsh` path on the target machine and merges the `statusLine` block into an
|
||||
existing `settings.json` **without** overwriting your other settings (a
|
||||
`.bak` backup is written first).
|
||||
|
||||
### Options
|
||||
|
||||
- `.\install.ps1 -Force` — also overwrite an existing `~/.config/cship.toml`
|
||||
(by default an existing config is kept, so local tweaks survive).
|
||||
|
||||
### Updating the kit
|
||||
|
||||
Edit the files under `assets/`, commit, `git push`. On another PC:
|
||||
|
||||
```powershell
|
||||
git pull
|
||||
.\install.ps1 -Force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deutsch
|
||||
|
||||
# Claude Code Statusline Kit
|
||||
|
||||
Ein portables, in sich geschlossenes Kit, das eine individuelle Claude-Code-
|
||||
Statusline (basierend auf dem Starship-Fork [`cship`](https://cship.dev)) mit
|
||||
einem einzigen Befehl auf jeden Windows-PC installiert.
|
||||
|
||||
### Was installiert wird
|
||||
|
||||
| Asset | Zielort | Zweck |
|
||||
| ----------------------------- | -------------------------- | ---------------------------------------- |
|
||||
| `assets/cship.exe` | `~/.local/bin/` | Rendert die Statusline |
|
||||
| `assets/cship.toml` | `~/.config/` | Modul-Konfiguration (Farben, Icons, Bars)|
|
||||
| `assets/cship-statusline.ps1` | `~/.claude/` | Wrapper (Progress-Bars, Token-Format) |
|
||||
| `statusLine`-Block | `~/.claude/settings.json` | Verdrahtet alles in Claude Code |
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
- **PowerShell 7** (`pwsh`). Installation: `winget install --id Microsoft.PowerShell -e`
|
||||
- Ein Terminal-Font mit **Emoji-/Nerd-Font-Glyphen** (z. B. Cascadia Code,
|
||||
JetBrainsMono Nerd Font), damit `🤖 ⚡ 🧠 █░` korrekt dargestellt werden.
|
||||
|
||||
### Installation auf einem neuen PC
|
||||
|
||||
```powershell
|
||||
git clone <deine-repo-url> Claude_Statusline
|
||||
cd Claude_Statusline
|
||||
.\install.ps1
|
||||
```
|
||||
|
||||
Danach Claude Code neu starten (oder eine neue Session öffnen).
|
||||
|
||||
Der Installer ist **idempotent** — jederzeit erneut ausführbar. Er erkennt den
|
||||
`pwsh`-Pfad auf dem Zielrechner automatisch und fügt den `statusLine`-Block in
|
||||
eine vorhandene `settings.json` ein, **ohne** deine anderen Einstellungen zu
|
||||
überschreiben (vorher wird ein `.bak`-Backup geschrieben).
|
||||
|
||||
### Optionen
|
||||
|
||||
- `.\install.ps1 -Force` — überschreibt zusätzlich eine vorhandene
|
||||
`~/.config/cship.toml` (standardmäßig wird eine bestehende Config behalten,
|
||||
damit lokale Anpassungen erhalten bleiben).
|
||||
|
||||
### Kit aktualisieren
|
||||
|
||||
Dateien unter `assets/` bearbeiten, committen, `git push`. Auf einem anderen PC:
|
||||
|
||||
```powershell
|
||||
git pull
|
||||
.\install.ps1 -Force
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
# cship statusline wrapper
|
||||
# Runs cship, then converts its usage_limits markers (§ 5|7 § pct § reset §)
|
||||
# into progress bars styled identically to the context_bar module.
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
[Console]::InputEncoding = New-Object System.Text.UTF8Encoding $false
|
||||
[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding $false
|
||||
$OutputEncoding = New-Object System.Text.UTF8Encoding $false
|
||||
|
||||
$cship = Join-Path $env:USERPROFILE '.local\bin\cship.exe'
|
||||
|
||||
# Read the full Claude Code session JSON from stdin, hand it to cship.
|
||||
$inp = [Console]::In.ReadToEnd()
|
||||
$out = $inp | & $cship
|
||||
# Starship's prompt carries a leading blank line (add_newline); drop leading/trailing
|
||||
# blank lines so the statusline doesn't waste a row.
|
||||
$text = ($out -join "`n").Trim("`r", "`n")
|
||||
|
||||
$S = [char]0x00A7
|
||||
$esc = [char]0x1B
|
||||
$rx = [regex]("$S([57])$S([0-9.]+)$S([^$S]*)$S")
|
||||
|
||||
$render = [System.Text.RegularExpressions.MatchEvaluator]{
|
||||
param($m)
|
||||
$type = $m.Groups[1].Value
|
||||
$pct = [double]$m.Groups[2].Value
|
||||
$reset = $m.Groups[3].Value
|
||||
|
||||
$width = 10
|
||||
$filled = [int][math]::Round($pct / 100.0 * $width)
|
||||
if ($filled -lt 0) { $filled = 0 }
|
||||
if ($filled -gt $width) { $filled = $width }
|
||||
$bar = ([string]([char]0x2588) * $filled) + ([string]([char]0x2591) * ($width - $filled))
|
||||
|
||||
# Same thresholds/colors as context_bar: warn >=40 (yellow), critical >=70 (bold red)
|
||||
if ($pct -ge 70) { $color = '1;31' }
|
||||
elseif ($pct -ge 40) { $color = '33' }
|
||||
else { $color = '38;2;125;207;255' }
|
||||
|
||||
if ($type -eq '5') { $label = '⏳ 5h' } else { $label = '📅 7d' }
|
||||
$pctTxt = '{0:0}%' -f $pct
|
||||
$resetTxt = if ([string]::IsNullOrWhiteSpace($reset)) { '' } else { " ($reset)" }
|
||||
|
||||
"$esc[${color}m$label $bar $pctTxt$resetTxt$esc[0m"
|
||||
}
|
||||
|
||||
# Compact the context_window token count marker (§T§<n>§) to K/M form, e.g.
|
||||
# 42329 -> 42.3K. cship has no native thousands formatting, so it's done here.
|
||||
$rxTok = [regex]("${S}T${S}([0-9]+)${S}")
|
||||
$renderTok = [System.Text.RegularExpressions.MatchEvaluator]{
|
||||
param($m)
|
||||
$n = [double]$m.Groups[1].Value
|
||||
$ic = [Globalization.CultureInfo]::InvariantCulture
|
||||
if ($n -ge 1000000) { $v = ($n / 1000000).ToString('0.0', $ic) + 'M' }
|
||||
elseif ($n -ge 1000) { $v = ($n / 1000).ToString('0.0', $ic) + 'K' }
|
||||
else { $v = $n.ToString('0', $ic) }
|
||||
$v -replace '\.0([KM]?)$', '$1'
|
||||
}
|
||||
$text = $rxTok.Replace($text, $renderTok)
|
||||
|
||||
[Console]::Out.Write($rx.Replace($text, $render))
|
||||
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
# cship — Claude Code statusline (Hero / Recommended + usage progress bars)
|
||||
# Reference: https://cship.dev
|
||||
[cship]
|
||||
lines = [
|
||||
"$starship_prompt",
|
||||
"$cship.model $cship.effort $cship.context_window.total_input_tokens $cship.context_bar $cship.peak_usage $cship.usage_limits",
|
||||
]
|
||||
|
||||
[cship.model]
|
||||
symbol = "🤖 "
|
||||
style = "bold cyan"
|
||||
|
||||
[cship.effort]
|
||||
symbol = "⚡ "
|
||||
style = "fg:#7dcfff"
|
||||
high_style = "fg:#e0af68"
|
||||
xhigh_style = "bold fg:#e0af68"
|
||||
max_style = "bold fg:#f7768e"
|
||||
|
||||
[cship.context_bar]
|
||||
symbol = "🧠 "
|
||||
filled_char = "█"
|
||||
empty_char = "░"
|
||||
format = "[$symbol$value]($style)"
|
||||
width = 10
|
||||
style = "fg:#7dcfff"
|
||||
warn_threshold = 40.0
|
||||
warn_style = "yellow"
|
||||
critical_threshold = 70.0
|
||||
critical_style = "bold red"
|
||||
|
||||
# $value is emitted inside a §T§…§ marker so the statusline wrapper can
|
||||
# compact the raw token count (e.g. 42329 → 42.3K) before display.
|
||||
[cship.context_window.total_input_tokens]
|
||||
symbol = "🔢 "
|
||||
style = "fg:#a9b1d6"
|
||||
format = "[$symbol§T§$value§]($style)"
|
||||
|
||||
# usage_limits emits machine markers (§TYPE§pct§reset§); the statusline wrapper
|
||||
# turns them into progress bars styled like context_bar. Thresholds >100 so cship
|
||||
# adds no ANSI of its own around the markers.
|
||||
[cship.usage_limits]
|
||||
style = ""
|
||||
separator = " "
|
||||
five_hour_format = "§5§{pct}§{reset}§"
|
||||
seven_day_format = "§7§{pct}§{reset}§"
|
||||
warn_threshold = 101
|
||||
critical_threshold = 101
|
||||
|
||||
[cship.peak_usage]
|
||||
symbol = "⏰ "
|
||||
style = "fg:#e0af68"
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
#requires -Version 5.1
|
||||
<#
|
||||
install.ps1 — Deploys the Claude Code "cship" statusline onto this machine.
|
||||
|
||||
Idempotent: safe to run repeatedly. Copies the three assets to their target
|
||||
locations, auto-detects the local pwsh path, and merges the statusLine block
|
||||
into an existing ~/.claude/settings.json without touching other settings.
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
# Overwrite an existing cship.toml even if one is already present.
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$assets = Join-Path $PSScriptRoot 'assets'
|
||||
|
||||
function Write-Step { param($m) Write-Host " $m" -ForegroundColor Cyan }
|
||||
function Write-Ok { param($m) Write-Host " OK $m" -ForegroundColor Green }
|
||||
function Write-Warn { param($m) Write-Host " !! $m" -ForegroundColor Yellow }
|
||||
|
||||
Write-Host "`nClaude Code statusline installer" -ForegroundColor White
|
||||
|
||||
# --- Target locations -------------------------------------------------------
|
||||
$localBin = Join-Path $env:USERPROFILE '.local\bin'
|
||||
$config = Join-Path $env:USERPROFILE '.config'
|
||||
$claude = Join-Path $env:USERPROFILE '.claude'
|
||||
foreach ($d in @($localBin, $config, $claude)) {
|
||||
New-Item -ItemType Directory -Force -Path $d | Out-Null
|
||||
}
|
||||
|
||||
# --- 1. cship.exe -----------------------------------------------------------
|
||||
Copy-Item (Join-Path $assets 'cship.exe') (Join-Path $localBin 'cship.exe') -Force
|
||||
Write-Ok "cship.exe -> $localBin"
|
||||
|
||||
# --- 2. cship.toml (do not clobber a customised config unless -Force) --------
|
||||
$tomlTarget = Join-Path $config 'cship.toml'
|
||||
if ((Test-Path $tomlTarget) -and -not $Force) {
|
||||
Write-Warn "cship.toml already exists, kept as-is (use -Force to overwrite)"
|
||||
} else {
|
||||
Copy-Item (Join-Path $assets 'cship.toml') $tomlTarget -Force
|
||||
Write-Ok "cship.toml -> $config"
|
||||
}
|
||||
|
||||
# --- 3. Wrapper script ------------------------------------------------------
|
||||
$wrapperTarget = Join-Path $claude 'cship-statusline.ps1'
|
||||
Copy-Item (Join-Path $assets 'cship-statusline.ps1') $wrapperTarget -Force
|
||||
Write-Ok "cship-statusline.ps1 -> $claude"
|
||||
|
||||
# --- 4. Locate pwsh ---------------------------------------------------------
|
||||
$pwsh = (Get-Command pwsh -ErrorAction SilentlyContinue).Source
|
||||
if (-not $pwsh) {
|
||||
$fallback = 'C:\Program Files\PowerShell\7\pwsh.exe'
|
||||
if (Test-Path $fallback) {
|
||||
$pwsh = $fallback
|
||||
} else {
|
||||
Write-Warn "PowerShell 7 (pwsh) not found. Install it, then re-run this script."
|
||||
Write-Warn " winget install --id Microsoft.PowerShell -e"
|
||||
$pwsh = $fallback # write the conventional path so it works once pwsh is installed
|
||||
}
|
||||
}
|
||||
$pwshFwd = $pwsh.Replace('\', '/')
|
||||
$wrapperFwd = $wrapperTarget.Replace('\', '/')
|
||||
$command = '"{0}" -NoProfile -ExecutionPolicy Bypass -File "{1}"' -f $pwshFwd, $wrapperFwd
|
||||
|
||||
# --- 5. Merge statusLine into settings.json ---------------------------------
|
||||
$settingsPath = Join-Path $claude 'settings.json'
|
||||
if (Test-Path $settingsPath) {
|
||||
Copy-Item $settingsPath "$settingsPath.bak" -Force
|
||||
$settings = Get-Content $settingsPath -Raw | ConvertFrom-Json
|
||||
} else {
|
||||
$settings = [PSCustomObject]@{}
|
||||
}
|
||||
|
||||
$statusLine = [PSCustomObject]@{ type = 'command'; command = $command }
|
||||
if ($settings.PSObject.Properties.Name -contains 'statusLine') {
|
||||
$settings.statusLine = $statusLine
|
||||
} else {
|
||||
$settings | Add-Member -MemberType NoteProperty -Name 'statusLine' -Value $statusLine
|
||||
}
|
||||
|
||||
$settings | ConvertTo-Json -Depth 20 | Set-Content $settingsPath -Encoding UTF8
|
||||
Write-Ok "settings.json statusLine wired to detected pwsh"
|
||||
|
||||
# --- Post-install notes -----------------------------------------------------
|
||||
Write-Host "`nDone." -ForegroundColor Green
|
||||
Write-Host "Notes:" -ForegroundColor White
|
||||
Write-Warn "Use a terminal font with emoji / Nerd-Font glyphs so the icons render (Cascadia Code, JetBrainsMono Nerd Font, ...)."
|
||||
Write-Host " Restart Claude Code (or start a new session) to see the statusline.`n"
|
||||
Reference in New Issue
Block a user