npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kreeger/pi-statusbar

v0.2.0

Published

A configurable statusbar footer for the pi-coding-agent TUI.

Readme

pi-statusbar

A configurable statusbar footer for the pi-coding-agent TUI. It shows context about your current session: the working directory, model and provider, thinking level, git status, token usage, context window, cache reads and writes, and running cost.

It's powered by powerline-style segments with a Catppuccin Mocha theme. You can reorder, remove, or add sections, change the divider between them, or swap the whole colour theme.

How it looks

The statusbar sits at the bottom of the pi TUI. Each section is a coloured segment separated by powerline chevrons (or rounded caps between certain sections). Sections appear from left to right in the order you've configured.

pi-statusbar preview

How it works

flowchart LR
    subgraph pi["pi-coding-agent"]
        TUI["TUI (Footer slot)"]
        API["Extension API"]
    end

    subgraph statusbar["pi-statusbar extension"]
        CONFIG["~/.pi/agent/statusbar.json"]
        REGISTRY["Section registry"]
        THEME["Catppuccin theme<br/>(or custom JSON)"]
        FOOTER["Footer component"]
    end

    subgraph segments["Built-in segments"]
        DIR["directory"]
        PROV["provider"]
        MODEL["model"]
        THINK["thinking"]
        GIT["git"]
        COST["cost"]
        CTX["context"]
        TOKENS["token-flow"]
        CACHE["cache"]
    QUOTA["codex-quota"]
    end

    API -- session_start --> FOOTER
    FOOTER --> REGISTRY
    CONFIG --> FOOTER
    REGISTRY --> segments
    THEME --> FOOTER
    FOOTER -- render(width) --> TUI

On session_start, pi-statusbar registers a footer component with the pi TUI. Each render pass walks the configured section list, calls each section's render function with lazy accessors (no wasted computation for sections that never read the data), wraps the text in ANSI styling from the theme, and joins everything with powerline divider characters.

The git section runs a background poller — it checks git status every few seconds and caches the result so the render path doesn't block on a subprocess.

Install

pi-statusbar is available on npm. Install it using pi install:

pi install @kreeger/pi-statusbar

If you've cloned the repository locally, you can also install from the local path:

pi install /path/to/pi-statusbar

After installation, restart your pi session. Experimental codex-quota uses a private Codex usage endpoint with read-only local Codex auth from ~/.codex/auth.json. It shows only authenticated Codex used percentage for OpenAI/Codex models, hides unavailable or stale values, and never displays credentials or other quota data. The statusbar appears automatically — there's no activation step needed.

Verify it is installed

ls ~/.pi/agent/extensions/pi-statusbar/

You should see TypeScript source files. The pi agent loads extensions from this directory at startup.

Configuration

Section order

Create ~/.pi/agent/statusbar.json. The default configuration (used when this file doesn't exist) is:

{
  "divider": " | ",
  "sections": [
    "directory",
    "provider",
    "model",
    "thinking",
    "git",
    "cost",
    "codex-quota",
    "context",
    "token-flow",
    "cache"
  ]
}

The divider field is the text inserted between sections when powerline glyphs aren't available (not typically visible in the TUI). The sections array lists the built-in segment IDs in display order. Remove any you don't want, or reorder them.

Custom themes

Add a themePath field pointing to a JSON file with ANSI escape sequences for foreground and background colours:

{
  "sections": ["directory", "git", "cost"],
  "themePath": "/home/you/.pi/themes/my-theme.json"
}

The theme file merges over the built-in Catppuccin theme. Each section can override foreground (fg) and background (bg) as raw SGR escape sequences. A defaultSection catches any section without its own entry. Here's an example theme file:

{
  "defaultSection": {
    "fg": "\u001b[38;2;147;153;178m",
    "bg": ""
  },
  "sections": {
    "directory": {
      "fg": "\u001b[38;2;55;55;75m",
      "bg": "\u001b[48;2;249;226;175m"
    },
    "git": {
      "fg": "\u001b[38;2;250;179;135m",
      "bg": "\u001b[48;2;55;55;75m"
    }
  }
}

Only the keys you provide are replaced. Sections not mentioned keep their Catppuccin defaults.

Built-in segments

| ID | Shows | | ------------ | ------------------------------------------------------------------------------------------------------------- | | directory | Current working directory, abbreviated (e.g. ~/src/my-project becomes ~/s/my-project) | | provider | Model provider name (e.g. anthropic, openai) | | model | Model identifier, provider prefix stripped (e.g. claude-sonnet-4-20250514) | | thinking | Current thinking level setting | | git | Git branch, ahead/behind counts, and file change counts (+ added, ~ modified, - deleted, ? untracked) | | cost | Running session cost | | context | Context window usage percentage and total window size | | token-flow | Input and output token counts for the session | | cache | Cache reads and writes (prompt caching) |

Writing custom segments

External extensions can register custom sections with pi-statusbar's SectionRegistry. The registry is available on the global scope at __piStatusbarRegistry. Call register() with an object that has an id and a render(ctx) function.

Here's a complete extension that adds a section showing the current time:

import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import type { SectionAccessors } from "./types.js";

export default function (pi: ExtensionAPI) {
  pi.on("session_start", (_event, ctx) => {
    if (!ctx.hasUI) return;

    const registry = (globalThis as any).__piStatusbarRegistry;
    if (!registry) return; // pi-statusbar not installed

    registry.register({
      id: "clock",
      render(ctx: SectionAccessors) {
        return new Date().toLocaleTimeString([], {
          hour: "2-digit",
          minute: "2-digit",
        });
      },
    });
  });
}

After installing this extension, add "clock" to the sections array in statusbar.json:

{
  "sections": ["directory", "clock", "git", "cost"]
}

How custom segment registration works

  1. pi-statusbar creates a SectionRegistry on session start and exposes it as globalThis.__piStatusbarRegistry.
  2. External extensions access the registry in their own session_start handler (which runs after pi-statusbar's).
  3. register() accepts any object matching the StatusbarSection interface: { id: string; render(ctx: SectionAccessors): string | undefined }.
  4. If your id matches a built-in section, yours replaces it.
  5. Unknown IDs in statusbar.json are silently skipped, so you must list your custom ID in the sections array for it to appear.

Section accessors

The render function receives a SectionAccessors object. Each getter is lazy — it only computes when called, and caches the result for the current render pass. If your section doesn't call a getter, that data is never collected.

interface SectionAccessors {
  getCwd(): string;
  getModel(): StatusbarModel | undefined;
  getThinkingLevel(): string;
  getUsage(): StatusbarUsage;
  getContextUsage(): StatusbarContextUsage | undefined;
  getGit(): GitStatusSnapshot;
}

Type definitions

The pi-statusbar source includes full TypeScript types in types.ts. You can reference them from your extension by importing from the extension directory, or copy the types you need.

Development

Setup

Clone the repository and install dependencies:

git clone [email protected]:kreeger/pi-statusbar.git
cd pi-statusbar
npm install

Running tests

npm test

Tests live alongside source files (.test.ts). They run with Vitest. There are tests for the section registry, config parsing, theme loading, the ANSI styler, the git state poller, the format utilities, and the extension lifecycle.

Deploying your changes

The deploy script copies the source files (minus test files) to ~/.pi/agent/extensions/pi-statusbar/. Use it to push local changes into pi without publishing to npm:

npm run deploy

Restart your pi session to pick up changes.

Releasing

Releases use release-it with Conventional Commits. The release command runs the test suite, updates CHANGELOG.md, bumps the package version, creates a v${version} Git tag, pushes the commit and tag, and publishes the package to npm.

Ensure the working tree is clean and npm authentication is configured, then preview the release before running it:

npm run release -- --dry-run
npm run release

Use commit prefixes such as feat:, fix:, and docs: so the changelog can classify changes and determine the recommended version bump.

Architecture notes

  • index.ts — Extension entry point. Hooks into session lifecycle, wires up config, theme, registry, and git polling.
  • config.ts — Reads statusbar.json from disk. Falls back to defaults when the file is missing or invalid.
  • registry.ts — Holds the mapping of section IDs to render functions. External extensions push into this.
  • footer.ts — Creates the TUI Component. Each render pass collects data lazily then delegates to the styler.
  • styler.ts — Interface for all ANSI rendering. Keeps layout code free of escape codes.
  • themes/ — Theme loading and the built-in Catppuccin theme.
  • sections/ — Built-in section implementations.
  • git/ — Asynchronous git status polling.
  • format.ts — Shared number/string formatting utilities.

License

MIT