---
slug: "liuovo-pi-statusline"
source_type: "readme"
source_url: "https://cdn.jsdelivr.net/gh/liuc-c/pi-statusline@main/README.md"
repo: "https://github.com/liuc-c/pi-statusline"
source_file: "README.md"
branch: "main"
---
# pi-statusline

[![npm version](https://img.shields.io/npm/v/@liuovo/pi-statusline)](https://www.npmjs.com/package/@liuovo/pi-statusline)
[![CI](https://github.com/liuc-c/pi-statusline/actions/workflows/ci.yml/badge.svg)](https://github.com/liuc-c/pi-statusline/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

A [pi](https://github.com/badlogic/pi-mono) extension that replaces the built-in footer with a
colorful, segment-based status line.

![pi-statusline footer: model + thinking level, directory, git branch, context usage, session cost, cumulative tokens with cache hit rate, and output speed](https://raw.githubusercontent.com/liuc-c/pi-statusline/main/assets/statusline.png)

## Install

```bash
pi install npm:@liuovo/pi-statusline
```

Or try it without installing, for the current run only:

```bash
pi -e npm:@liuovo/pi-statusline
```

Upgrade an existing install (restart pi afterwards to load the new code):

```bash
pi update npm:@liuovo/pi-statusline
```

## Segments

| Segment | Content |
|---------|---------|
| `model` | Active model id + thinking level |
| `cwd` | Current directory (basename) |
| `branch` | Git branch; `*` marks uncommitted changes |
| `context` | Context window usage `percent (tokens/window)`; color shifts green → yellow (>70%) → red (>90%, with a warning icon). An autorenew icon appears while auto-compaction is enabled |
| `cost` | Cumulative session cost (adaptive precision: `$0.0042` for small amounts) |
| `usage` | Cumulative input/output tokens + latest-request cache hit rate (color-coded: ≥90% green, ≥70% yellow, below red) |
| `tps` | Output speed in tokens/sec, updated live while streaming; measured over pure LLM streaming time (tool execution excluded) |
| `statuses` | Texts from other extensions' `ctx.ui.setStatus()` (noise like `MCP:`/`Ready`/`Working` filtered out) |

Usage totals mirror pi's built-in footer: they accumulate over all session entries, including
compaction/branch summaries and nested tool-call usage, so they survive compaction.

When the terminal is too narrow for one line, segments wrap whole to a second line
(never cut mid-segment); the second line is truncated as a last resort.

## Customize

Run `/statusline` inside pi to toggle the footer and each segment individually
(Enter/Space toggles in place, Esc closes). Choices persist to
`~/.pi/agent/pi-statusline.json`:

```json
{
  "enabled": true,
  "segments": {
    "model": true,
    "cwd": true,
    "branch": true,
    "context": true,
    "cost": true,
    "usage": true,
    "tps": true,
    "statuses": true
  }
}
```

## Font requirements

Icons are [Nerd Font](https://www.nerdfonts.com/) glyphs (private-use-area codepoints).
Use a Nerd Font v3+ terminal font, or replace the entries in `ICONS` in
[src/statusline.ts](https://github.com/liuc-c/pi-statusline/blob/HEAD/src/statusline.ts) with plain text.

Colors use truecolor escape sequences when `COLORTERM` is `truecolor`/`24bit`,
and fall back to theme colors otherwise.

## Develop

```bash
git clone https://github.com/liuc-c/pi-statusline.git
cd pi-statusline
pnpm install

pnpm check        # type-check
pnpm test         # render smoke tests (Node >= 22.6, native type stripping)
```

pi loads extensions via jiti — no build step. Test changes against your local checkout with:

```bash
pi -e ./src/index.ts
```

### Structure

```
src/
├── index.ts        # Extension entry: event wiring, data collection, /statusline command
└── statusline.ts   # Pure rendering: segments, colors, two-line wrapping
scripts/
└── smoke.ts        # Framework-free render smoke tests
```

## Releasing

Releases are driven by git tags and run entirely in CI
([release.yml](https://github.com/liuc-c/pi-statusline/blob/HEAD/.github/workflows/release.yml)):

```bash
npm version patch   # bumps package.json, commits, creates tag vX.Y.Z
git push --follow-tags
```

The workflow verifies the tag matches `package.json`, runs checks, publishes to npm with
[provenance](https://docs.npmjs.com/generating-provenance-statements), and creates a GitHub
release with generated notes.

One-time setup on the repo:

- Add an `NPM_TOKEN` secret (npm granular access token with publish rights on `@liuovo`),
  **or** configure [trusted publishing](https://docs.npmjs.com/trusted-publishers) for the
  package and drop the token from the workflow — provenance works via OIDC either way.

## License

[MIT](https://github.com/liuc-c/pi-statusline/tree/HEAD/LICENSE)
