Skip to content

Repository files navigation

 _ _ _ _ _ _ _
___ ___ _ __ (_) | ___ | |_ ___| |_ __ _| |_ _ _ ___| (_)_ __ ___
/ __/ _ \| '_ \| | |/ _ \| __| / __| __/ _` | __| | | / __| | | '_ \ / _ \
| (_| (_) | |_) | | | (_) | |_ \__ \ || (_| | |_| |_| \__ \ | | | | | __/
\___\___/| .__/|_|_|\___/ \__| |___/\__\__,_|\__|\__,_|___/_|_|_| |_|\___|
|_|

copilot-statusline

🎨 A highly customizable status line formatter for GitHub Copilot CLIDisplay model info, git branch, token usage, AI Credits, and other metrics in your terminal

npm versionnpm downloadsLicense: MITNode.js VersionMade with Bun

Based on ccstatusline by @sirmalloc — the excellent customizable statusline for Claude Code CLI. This project adapts its architecture, TUI, and rendering engine for the GitHub Copilot CLI payload format. Huge thanks to Matthew Breedlove for the original work.

Requirements: GitHub Copilot CLI ≥ 1.0.35 for live context widgets (Context %, Context Bar, Context Length, Remaining Tokens). Older versions miss the underlying current_context_tokens / displayed_context_limit fields and these widgets render blank.


📚 Table of Contents


✨ Features

  • 📊 Real-time Metrics — Model name, git branch, token usage, AI Credits, session duration, and more
  • 🎨 Fully Customizable — Choose what to display and customize colors for each widget
  • ⚡ Powerline Support — Beautiful Powerline-style rendering with arrow separators, caps, and custom themes
  • 📐 Multi-line Support — Configure any number of independent status lines
  • 🖥️ Interactive TUI — Built-in configuration interface using React/Ink
  • 🔎 Fast Widget Picker — Add/change widgets by category with search and ranked matching
  • ⚙️ Global Options — Apply consistent formatting across all widgets (padding, separators, bold, background)
  • 🚀 Cross-platform — Works seamlessly on macOS, Linux, and Windows with both Bun and Node.js
  • 📏 Smart Width Detection — Automatically adapts to terminal width with flex separators
  • ⚡ Zero Config — Sensible defaults that work out of the box
  • 🔒 Fully Independent — Completely separate from ccstatusline (different config paths, different npm package)

🚀 Quick Start

No installation needed! Use directly with npx or bunx:

# Run the configuration TUI with npm
npx -y copilot-statusline@latest
# Or with Bun (faster)
bunx -y copilot-statusline@latest

Configure copilot-statusline

The interactive configuration tool provides a terminal UI where you can:

  • Configure multiple separate status lines
  • Add/remove/reorder status line widgets
  • Customize colors for each widget (foreground, background, bold)
  • Configure Powerline mode with themes
  • Set global overrides (padding, separators, color overrides)
  • Install/uninstall to Copilot CLI settings
  • Preview your status line in real-time

💡 Tip: Your settings are automatically saved to ~/.config/copilot-statusline/settings.json

Copilot CLI Integration

When you install from the TUI, copilot-statusline creates a launcher script at ~/.copilot/statusline.sh that uses bunx/npx to always run the latest version — no manual upgrades needed. The installer also enables footer.showCustom while preserving your other Copilot footer settings.

It also writes to your Copilot CLI config:

// ~/.copilot/settings.json
{
"statusLine": {
"type": "command",
"command": "/Users/you/.copilot/statusline.sh",
"padding": 0
}
}

💡 Auto-upgrade: The launcher script runs bunx -y copilot-statusline@latest (or npx if you used npm to run the TUI) under the hood, so you always get the latest version automatically.

Settings location:~/.copilot/settings.json (or set COPILOT_HOME to change the Copilot home directory)


🪟 Windows Support

copilot-statusline works on Windows with full feature compatibility across PowerShell (5.1+ and 7+), Command Prompt, and WSL.

Installation on Windows

Option 1: Using Bun (Recommended)

# Install Bun for Windows
irm bun.sh/install.ps1 | iex
# Run copilot-statusline
bunx -y copilot-statusline@latest

Option 2: Using Node.js

# Using npm
npx -y copilot-statusline@latest# Using Yarn
yarn dlx copilot-statusline@latest# Using pnpm
pnpm dlx copilot-statusline@latest

Powerline Font Support on Windows

For optimal Powerline rendering on Windows:

Windows Terminal (Recommended):

PowerShell/Command Prompt:

# Install JetBrains Mono Nerd Font via winget
winget install DEVCOM.JetBrainsMonoNerdFont
# Or download manually from: https://www.nerdfonts.com/font-downloads

Windows Terminal Configuration

For the best experience:

{
"profiles": {
"defaults": {
"font": {
"face": "JetBrainsMono Nerd Font",
"size": 12
}
}
}
}

Windows Copilot CLI Integration

Config location:%USERPROFILE%\.copilot\settings.json

{
"statusLine": {
"type": "command",
"command": "npx -y copilot-statusline@latest",
"padding": 0
}
}

WSL (Windows Subsystem for Linux)

copilot-statusline works natively in WSL:

curl -fsSL https://bun.sh/install | bash
source~/.bashrc
bunx -y copilot-statusline@latest

Windows Troubleshooting

Powerline symbols showing as boxes:

winget install DEVCOM.JetBrainsMonoNerdFont
# Then set the font in your terminal settings

Git commands not recognized:

winget install Git.Git

Execution Policy errors:

Set-ExecutionPolicy-ExecutionPolicy RemoteSigned -Scope CurrentUser

📖 Usage

Once configured, copilot-statusline automatically formats your Copilot CLI status line. The status line appears below the input during Copilot CLI sessions.

Runtime Modes

  • Interactive mode (TUI) — Launches when there is no stdin input
  • Piped mode (renderer) — Parses Copilot CLI JSON from stdin and prints formatted lines
# Interactive TUI
copilot-statusline
# Print package version
copilot-statusline --version
# Piped mode with example payload
bun run example

How It Works

Copilot CLI spawns your status line command on every state change, passing session JSON via stdin. copilot-statusline parses the payload, renders the configured widgets, and outputs ANSI-colored text to stdout.


📊 Available Widgets

Core

WidgetTypeDescription
ModelmodelCopilot model name (e.g., claude-opus-4.6)
VersionversionCopilot CLI version number
Thinking Effortthinking-effortThinking effort level from payload fields or display_name (minimal/low/medium/high/xhigh/max)
Model Multipliermodel-multiplierLegacy/request-based premium multiplier when present (e.g., 3x)
Allow Allallow-allShows YOLO while Copilot allow-all mode is enabled

Session

WidgetTypeDescription
Session Namesession-nameCopilot conversation title
Session IDsession-idShort session identifier
Remote Control Statusremote-control-statusWhether Copilot remote control is connected
Remote Sessionremote-sessionConnected remote task/repository and PR number, with a clickable task link when available
Session Clocksession-clockElapsed session time (from total_duration_ms)
AI Creditsai-creditsGitHub AI Credits used this session (from ai_used.formatted)
Premium Requestspremium-requestsLegacy premium request counter when the active billing path still reports it
API Callsapi-callsRough legacy estimate (premium_requests / current multiplier); not reliable across model switches
Premium Ratepremium-rateLegacy premium request average per elapsed session minute

Tokens

WidgetTypeDescription
Tokens Inputtokens-inputNon-cached input tokens
Tokens Outputtokens-outputTotal output tokens
Tokens Cachedtokens-cachedCached input tokens (total_cache_read_tokens + total_cache_write_tokens; rendered as Cached:)
Tokens Reasoningtokens-reasoningTotal reasoning (thinking) tokens consumed
Tokens Totaltokens-totalTotal tokens
Last Call Inputlast-call-inputBest-effort dedicated last-call input; some 1.0.70 model/tier paths leave it zero or stale
Last Call Outputlast-call-outputBest-effort dedicated last-call output; some 1.0.70 model/tier paths leave it zero or stale
Cache Read Tokenscache-read-tokensTotal cache read tokens
Cache Write Tokenscache-write-tokensTotal cache write tokens
Cache Hit Ratecache-hit-rateCache reads ÷ (reads + writes); this is not cached share of total input

Context

WidgetTypeDescription
Context Lengthcontext-lengthCurrent context length in tokens (live, from current_context_tokens)
Context Windowcontext-windowActive context limit reported by Copilot (displayed_context_limit, falling back to context_window_size)
Context %context-percentageLive context % from Copilot (current_context_used_percentage)
Context Barcontext-barVisual progress bar for live context usage
Remaining Tokensremaining-tokensLive remaining tokens for the active reported context limit

Git

WidgetTypeDescription
Git Branchgit-branchCurrent branch name (with optional GitHub link)
Git Changesgit-changesInsertions and deletions count (+42,-10)
Git Insertionsgit-insertionsUncommitted insertions only
Git Deletionsgit-deletionsUncommitted deletions only
Git Statusgit-statusStaged/unstaged/untracked/conflicts indicators
Git Stagedgit-stagedStaged changes indicator
Git Staged Filesgit-staged-filesCount of staged files (S:3, raw: 3)
Git Unstagedgit-unstagedUnstaged changes indicator
Git Unstaged Filesgit-unstaged-filesCount of unstaged tracked files (M:2, raw: 2)
Git Untrackedgit-untrackedUntracked files indicator
Git Untracked Filesgit-untracked-filesCount of untracked files (?:1, raw: 1)
Git Clean Statusgit-clean-statusWorking tree clean/dirty status (/, raw: clean/dirty)
Git Conflictsgit-conflictsMerge conflict count
Git Ahead/Behindgit-ahead-behindCommits ahead/behind upstream
Git SHAgit-shaShort commit hash
Git PRgit-prCurrent pull request number, status, and title from a non-blocking background cache
Git CI Statusgit-ci-statusGitHub PR checks as failing, pending, and successful counts (//)
Git Root Dirgit-root-dirRepository root directory name
Git Origin Ownergit-origin-ownerRemote origin owner
Git Origin Repogit-origin-repoRemote origin repo name
Git Origin Owner/Repogit-origin-owner-repoRemote origin owner/repo
Git Upstream Ownergit-upstream-ownerUpstream remote owner
Git Upstream Repogit-upstream-repoUpstream remote repo name
Git Upstream Owner/Repogit-upstream-owner-repoUpstream owner/repo
Git Is Forkgit-is-forkFork detection indicator
Git Worktreegit-worktreeCurrent git worktree name (probes git rev-parse --git-dir)
Git Worktree Modegit-worktree-mode indicator when current dir is a linked worktree

System

WidgetTypeDescription
Current Working Dircurrent-working-dirCurrent directory with configurable segment display and ~ abbreviation
Terminal Widthterminal-widthTerminal width in columns
Free Memoryfree-memorySystem free memory

Custom

WidgetTypeDescription
Custom Textcustom-textUser-defined static text (supports emoji)
Custom Commandcustom-commandShell command output (refreshes on each state change)
Custom Symbolcustom-symbolCustom Unicode symbol
LinklinkClickable terminal hyperlink (OSC 8)

Layout

WidgetTypeDescription
SeparatorseparatorVisual divider between widgets
Flex Separatorflex-separatorExpands to fill available terminal width

🆕 Copilot-Unique Widgets

These widgets are exclusive to copilot-statusline and not available in ccstatusline:

WidgetTypeDescription
Model Multipliermodel-multiplierLegacy premium multiplier parsed from display_name (e.g., 3x, 6x)
Allow Allallow-allSafety indicator shown while allow-all mode is active
AI Creditsai-creditsGitHub AI Credits used this session (ai_used.formatted, fallback from total_nano_aiu)
Premium Requestspremium-requestsLegacy premium request counter when reported
API Callsapi-callsRough legacy estimate: total_premium_requests / current multiplier
Premium Ratepremium-rateLegacy requests per elapsed session minute
Last Call Inputlast-call-inputBest-effort upstream last-call input; may be unavailable or stale
Last Call Outputlast-call-outputBest-effort upstream last-call output; may be unavailable or stale
Remaining Tokensremaining-tokensLive remaining tokens (displayed_context_limit − current_context_tokens)
Tokens Reasoningtokens-reasoningTotal reasoning (thinking) tokens consumed
Remote Sessionremote-sessionConnected Copilot remote task and PR metadata, with a safe clickable task URL

⌨️ Widget Editor Keybinds

Common controls in the line editor:

KeyAction
Select widget
Open widget picker to change type
aAdd widget via picker
iInsert widget before current
dDelete selected widget
mToggle move mode (reorder with )
rToggle raw value mode (supported widgets)
cClear all widgets (with confirmation)
SpaceEdit separator character

Widget-specific shortcuts:

WidgetKeyAction
Git widgetshToggle hide no git output
Count widgetszToggle hide when rendered value is zero
Git BranchlToggle GitHub link
Context % widgetsuToggle used/remaining display
Context % widgetspCycle numeric/short bar display
Context BarpCycle bar style (medium/full/short/short-only)
Current Working DirhToggle ~ home abbreviation
Current Working DirsEdit segment limit
Current Working DirfToggle fish-style path
Custom CommandeEdit command
Custom CommandwSet max width
Custom CommandtSet timeout
Custom CommandpToggle preserve ANSI colors
LinkuEdit URL
LinkeEdit link text

🔤 Raw Value Mode

Some widgets support raw mode which displays just the value without a label:

  • Normal: Model: claude-opus-4.6 → Raw: claude-opus-4.6
  • Normal: Reqs: 15 → Raw: 15
  • Normal: Session: 2hr 15m → Raw: 2hr 15m
  • Normal: Ctx: 18.0% → Raw: 18.0%

🔧 Custom Widgets

Custom Text Widget

Add static text to your status line. Supports emoji. Perfect for:

  • Project identifiers
  • Environment indicators (dev/prod)
  • Personal labels

Custom Command Widget

Execute shell commands and display their output dynamically:

  • Refreshes whenever the Copilot CLI updates the status line
  • Receives the full Copilot JSON payload via stdin
  • Configurable timeout (default: 1000ms)
  • Optional max-width truncation
  • Optional ANSI color preservation

Examples:

  • pwd | xargs basename — Show current directory name
  • node -v — Display Node.js version
  • git rev-parse --short HEAD — Show current commit hash
  • date +%H:%M — Display current time

⚠️ Commands should complete quickly to avoid delays. Long-running commands will be killed after the configured timeout.

Link Widget

Create clickable links in terminals that support OSC 8 hyperlinks:

  • Configure URL and display text in the editor
  • Falls back to plain text when URL is missing

⚙️ Global Options

Configure global formatting preferences that apply to all widgets:

KeyOptionDescription
pDefault PaddingAdd consistent padding around each widget
sDefault SeparatorAuto-insert separator between all widgets
iInherit ColorsSeparators inherit colors from preceding widget
oGlobal BoldApply bold to all text
fOverride ForegroundForce all widgets to use the same text color
bOverride BackgroundForce all widgets to use the same background color
mMinimalist ModeShow raw values only (no labels)

⚠️VSCode Users: If colors appear incorrect in the integrated terminal, adjust terminal.integrated.minimumContrastRatio to 1 in settings to disable contrast enforcement.


📏 Terminal Width Options

These settings control line truncation and flex separator behavior:

ModeDescription
Full widthUses full terminal width (may wrap with long content)
Full width minus 40 (default)Reserves 40 characters on the right to prevent wrapping
Full width until compactDynamic — switches based on context usage threshold (configurable, default 60%)

✂️ Smart Truncation

When terminal width is detected, status lines automatically truncate with ellipsis (...) if they exceed the available width. Truncation is ANSI-aware, so color codes and OSC 8 hyperlinks remain well-formed.


⚙️ Configuration

Configuration Files

FilePurpose
~/.config/copilot-statusline/settings.jsoncopilot-statusline widget/render settings
~/.copilot/settings.jsonCopilot CLI settings (statusLine command object)

Example Configuration

{
"version": 1,
"lines": [
[
{ "id": "1", "type": "model", "color": "cyan" },
{ "id": "2", "type": "separator" },
{ "id": "3", "type": "thinking-effort", "color": "yellow" },
{ "id": "4", "type": "separator" },
{ "id": "5", "type": "context-percentage", "color": "blue" },
{ "id": "6", "type": "separator" },
{ "id": "7", "type": "ai-credits", "color": "green" },
{ "id": "8", "type": "separator" },
{ "id": "9", "type": "session-clock", "color": "yellow" },
{ "id": "10", "type": "flex-separator" },
{ "id": "11", "type": "git-branch", "color": "magenta" }
],
[],
[]
],
"colorLevel": 2
}

Renders as:

Model: gpt-5.6-sol | Thinking: low | Ctx Used: 6.0% | AIC: 13.3 | Session: 2m ⎇ main

Color Levels

LevelModeDescription
0No ColorPlain text only
1Basic16 ANSI colors
2256 Color256 ANSI colors with custom codes (default)
3Truecolor16 million colors with hex codes

🛠️ Development

Prerequisites

  • Bun (v1.0+)
  • Git
  • Node.js 14+ (optional, for running built binary)

Setup

git clone https://github.com/EncodeTS/copilot-statusline.git
cd copilot-statusline
bun install

Development Commands

bun run start # Run TUI mode
bun run example # Test with example payload
bun test# Run tests
bun run lint # Type check + ESLint
bun run lint:fix # Auto-fix lint issues
bun run build # Build for npm distribution

Build Notes

  • Build target is Node.js 14+ (dist/copilot-statusline.js)
  • During install, ink@6.2.0 is patched to fix backspace handling on macOS terminals
  • A bash launcher (dist/launcher.sh) buffers stdin before passing to Node.js — this is needed because Copilot CLI closes the stdin pipe very quickly after writing

Project Structure

copilot-statusline/
├── src/
│ ├── copilot-statusline.ts # Main entry point (piped + TUI dual mode)
│ ├── types/ # TypeScript type definitions
│ │ ├── CopilotPayload.ts # Zod schema for Copilot stdin JSON
│ │ ├── Settings.ts # Configuration schema
│ │ ├── Widget.ts # Widget interface
│ │ └── RenderContext.ts # Render context type
│ ├── widgets/ # Widget implementations
│ │ ├── Model.ts
│ │ ├── PremiumRequests.ts
│ │ ├── GitBranch.ts
│ │ └── ...
│ ├── tui/ # React/Ink configuration UI
│ │ ├── App.tsx # Root TUI component
│ │ └── components/ # UI components
│ └── utils/ # Utility functions
│ ├── config.ts # Settings management
│ ├── renderer.ts # Core rendering logic
│ ├── copilot-settings.ts # Copilot CLI integration
│ └── ...
├── scripts/ # Build scripts and example payloads
├── dist/ # Built output (generated)
├── package.json
├── tsconfig.json
└── vitest.config.ts

🔄 Differences from ccstatusline

copilot-statusline and ccstatusline are fully independent — they use separate config directories, separate npm packages, and can be installed side-by-side without interference.

Aspectccstatuslinecopilot-statusline
TargetClaude Code CLIGitHub Copilot CLI
Input formatClaude Code StatusJSONCopilot JSON payload
Config path~/.config/ccstatusline/~/.config/copilot-statusline/
CLI integration~/.claude/settings.json~/.copilot/settings.json
npm packageccstatuslinecopilot-statusline
Cost trackingUSD session costGitHub AI Credits / premium requests counter
Speed metricsInput/output/total token speedNot available (no per-request timing data)
Session durationParsed from transcript JSONLDirect from cost.total_duration_ms
Rate limits5-hour blocks, weekly resetsAI Credits and premium request tracking
Copilot-exclusiveAI Credits, allow-all state, model multiplier, legacy premium metrics, reasoning and last-call tokens
ccstatusline-exclusiveVim mode, output style, skills, block/usage timers, voice, compaction, speed widgets

🙏 Acknowledgments

This project is built on the foundation of ccstatusline by Matthew Breedlove (@sirmalloc). The widget system, rendering engine, TUI configuration interface, Powerline support, and overall architecture are derived from ccstatusline's excellent codebase.

If you use Claude Code, check out the original — it's a fantastic tool:

ccstatusline

Additional thanks to:

  • Ink for the terminal UI framework
  • Zod for runtime schema validation
  • The GitHub Copilot CLI team for the statusline API

📄 License

MIT

This project includes substantial portions of code from ccstatusline (MIT licensed, Copyright 2025 Matthew Breedlove). See the LICENSE file for full details.


npm versionnpm downloadsLicense: MIT

About

A customizable status line formatter for GitHub Copilot CLI

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages