# 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' } # Emoji are built from codepoints (not string literals) so the label renders # correctly regardless of how this .ps1 is read from disk. Windows PowerShell # 5.1 decodes a BOM-less script as the ANSI codepage, which would turn literal # UTF-8 emoji bytes into mojibake (e.g. ⏳ -> â³, 📅 -> 📅). $hourglass = [char]0x23F3 # ⏳ (BMP) $calendar = [char]::ConvertFromUtf32(0x1F4C5) # 📅 (astral, needs surrogate pair) if ($type -eq '5') { $label = "$hourglass 5h" } else { $label = "$calendar 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§§) 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))