# Oh My Posh for GitHub Copilot CLI statusline - Catppuccin theme

> Source: <https://gist.github.com/cinnamon-msft/1f52589615967a3118f64c2291532df6>
> Published: 2026-05-13 14:10:03+00:00

|
$ErrorActionPreference = 'Stop' |
|
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() |
|
|
|
function Format-TokenCount { |
|
param([Nullable[double]]$Value) |
|
|
|
if ($null -eq $Value) { return '?' } |
|
if ($Value -ge 1000000) { return ('{0:0.0}m' -f ($Value / 1000000)) } |
|
if ($Value -ge 1000) { return ('{0:0}k' -f ($Value / 1000)) } |
|
return ([int][Math]::Round($Value)).ToString() |
|
} |
|
|
|
# Copilot sends the statusline payload as JSON on stdin. |
|
$payload = [Console]::In.ReadToEnd() |
|
|
|
try { |
|
$json = $payload | ConvertFrom-Json |
|
} catch { |
|
Write-Host -NoNewline 'Copilot status unavailable' |
|
exit 0 |
|
} |
|
|
|
$context = $json.context_window |
|
|
|
$currentTokens = if ($null -ne $context.current_context_tokens) { |
|
[double]$context.current_context_tokens |
|
} else { |
|
$null |
|
} |
|
|
|
$contextLimit = if ($null -ne $context.displayed_context_limit) { |
|
[double]$context.displayed_context_limit |
|
} else { |
|
$null |
|
} |
|
|
|
$cost = $json.cost |
|
$linesAdded = if ($null -ne $cost.total_lines_added) { [int]$cost.total_lines_added } else { 0 } |
|
$linesRemoved = if ($null -ne $cost.total_lines_removed) { [int]$cost.total_lines_removed } else { 0 } |
|
|
|
$theme = Join-Path $PSScriptRoot 'statusline.omp.json' |
|
$cwd = if ($json.cwd) { [string]$json.cwd } else { (Get-Location).Path } |
|
$folderName = Split-Path -Path $cwd -Leaf |
|
if ([string]::IsNullOrWhiteSpace($folderName)) { |
|
$folderName = $cwd |
|
} |
|
|
|
$branchName = '' |
|
# Only show a branch when the payload cwd is actually inside a git work tree. |
|
$isRepo = & git -C $cwd rev-parse --is-inside-work-tree 2>$null |
|
if ($LASTEXITCODE -eq 0 -and $isRepo -eq 'true') { |
|
$branchName = (& git -C $cwd branch --show-current 2>$null).Trim() |
|
if ([string]::IsNullOrWhiteSpace($branchName)) { |
|
$branchName = (& git -C $cwd rev-parse --short HEAD 2>$null).Trim() |
|
} |
|
} |
|
|
|
$env:COPILOT_STATUS_FOLDER = $folderName |
|
$env:COPILOT_STATUS_BRANCH = $branchName |
|
$env:COPILOT_STATUS_TOKENS = "$(Format-TokenCount $currentTokens)/$(Format-TokenCount $contextLimit)" |
|
$env:COPILOT_STATUS_CHANGES = if ($linesAdded -or $linesRemoved) { "+$linesAdded/-$linesRemoved" } else { '' } |
|
|
|
try { |
|
# Let Oh My Posh draw the final line; the script only prepares the data. |
|
$output = & oh-my-posh print primary --config $theme --pwd $cwd --force --escape=false 2>$null |
|
if ([string]::IsNullOrWhiteSpace($output)) { |
|
throw 'Oh My Posh returned no output.' |
|
} |
|
|
|
Write-Host -NoNewline $output.TrimEnd() |
|
} catch { |
|
# Fallback stays readable if the theme cannot render for any reason. |
|
$branch = if ($env:COPILOT_STATUS_BRANCH) { " | $($env:COPILOT_STATUS_BRANCH)" } else { '' } |
|
$changes = if ($env:COPILOT_STATUS_CHANGES) { " | $($env:COPILOT_STATUS_CHANGES)" } else { '' } |
|
Write-Host -NoNewline "$($env:COPILOT_STATUS_FOLDER)$branch | $($env:COPILOT_STATUS_TOKENS)$changes" |
|
} |
