@0xkahi/pi-qol
v0.0.4
Published
quality of life pi extensions
Readme
pi-qol
Quality-of-life extensions for pi.
A small collection of opt-in extensions that smooth out everyday pi usage. Today
it ships auto_session_name — automatic, opencode-style session titling,
model_select — an interactive model picker, and custom_footer — a
compact configurable interactive footer.
Installation
Install the package from npm:
pi install npm:@0xkahi/pi-qolThen register it in your pi configuration so pi loads ./src/index.ts as an
extension (see the pi.extensions field in package.json).
Features
auto_session_name
Automatically generates a short, human-readable title for a brand-new session from its first user message, using a cheap model call that runs in the background and never blocks your turn.
- Non-blocking — titles are generated asynchronously while the agent responds.
- Fires once, early — only on the very first real user turn of a session.
- Smart guards — skips sessions that already have a name, forked/child sessions, and empty prompts.
- Model-flexible — use a configured cheap model, or fall back to the active session model automatically.
- Safe output — strips
<think>blocks, unwraps quotes, and truncates titles to 100 characters.
model_select
Adds /select-model, an interactive model picker with fuzzy search, optional favourites,
provider filtering, and inline or overlay layouts,
- quick access to listed favourite models
- filtering specified providers from model search
allow keybindings with pi-vim-keys with eventId of pi.vimKeys.event:pi-qol.model_select
custom_footer
Replaces pi's built-in interactive footer with the same three-line layout, but shows the current directory as an icon plus basename, supports hex color overrides, can hide token/cache clusters, and adds an OAuth subscription-usage progress bar for supported providers (Anthropic and OpenAI Codex).
- Directory line — directory icon + basename, with optional git branch and session name.
- Stats line — cumulative input/output tokens, cache read/write/hit cluster,
session cost (or
(sub)when on a subscription), context-window usage, and the right-aligned model name (with provider prefix when multiple providers are available). - Subscription usage — a colored progress bar plus percentage and reset time for the active OAuth provider. Usage is fetched lazily and cached, refreshing at most once every 60 seconds per provider; auth/network failures simply hide the segment.
Known difference from pi's built-in footer: the (auto) compaction suffix is
omitted because extensions do not expose reliable live state for it.
Configuration
pi-qol reads a JSON config file named config.json from two locations and merges
them (project overrides global):
| Scope | Path |
| ------- | ---------------------------------------------------------- |
| Global | <agent-dir>/extensions/pi-qol/config.json |
| Project | <cwd>/.pi/extensions/pi-qol/config.json (trusted projects only) |
Project config is only loaded when the project is trusted.
Example
{
"$schema": "https://raw.githubusercontent.com/0xKahi/pi-qol/main/assets/config.schema.json",
"auto_session_name": {
"enabled": true,
"model": {
"provider": "opencode",
"modelId": "gpt-5-nano",
"reasoning": "low"
}
},
"model_select": {
"enabled": true,
"layout": "overlay",
"provider_filter": ["anthropic", "openai"],
"favourite": [{ "provider": "anthropic", "modelId": "claude-sonnet-4-5" }]
},
"custom_footer": {
"enabled": true,
"colors": {
"directory": "#A78BFA",
"modelName": "#60A5FA"
},
"display": {
"tokens": true,
"cache": true
}
}
}Options
auto_session_name
| Key | Type | Default | Description |
| --------- | --------- | ------- | ------------------------------------------------------------------ |
| enabled | boolean | false | Turn the auto session naming feature on. |
| model | object | — | Optional model used to generate titles. Falls back to the session model if omitted. |
model
| Key | Type | Description |
| ----------- | -------- | --------------------------------------------------------------------- |
| provider | string | Model provider id (e.g. anthropic, openai). |
| modelId | string | Model identifier as registered in pi's model registry. |
| reasoning | enum | One of off, minimal, low, medium, high, xhigh. |
When model is set but cannot be found or authenticated, pi-qol automatically
falls back to the active session model and surfaces a warning notification.
model_select
| Key | Type | Default | Description |
| ----------------- | --------- | -------- | --------------------------------------------------------- |
| enabled | boolean | false | Turn the model picker on. |
| layout | enum | inline | Picker layout: inline or overlay. |
| provider_filter | string[]| [] | Restrict searchable models to these providers. |
| favourite | object[]| [] | Favourite models shown in a separate tab (provider, modelId). |
custom_footer
| Key | Type | Default | Description |
| --------------------------- | --------- | --------- | ------------------------------------------------ |
| enabled | boolean | false | Replace pi's built-in interactive footer. |
| display.tokens | boolean | true | Show cumulative input/output token counts. |
| display.cache | boolean | true | Show the custom cache read/write/hit cluster. |
| colors.directory | hex | — | Color the directory icon and basename. |
| colors.modelName | hex | — | Color the right-aligned model name. |
| colors.anthropicUsage | hex | #D97706 | Color the Claude subscription usage segment (bar + percentage). |
| colors.codexUsage | hex | #10B981 | Color the Codex subscription usage segment (bar + percentage). |
| icons.directory | string | nerd font | Glyph shown before the directory basename. |
| icons.cache | string | nerd font | Glyph for the cache cluster. |
| icons.cacheRead | string | nerd font | Glyph for cache-read tokens. |
| icons.cacheWrite | string | nerd font | Glyph for cache-write tokens. |
| icons.refresh | string | nerd font | Glyph shown before the subscription reset time. |
Project config shallow-merges each top-level section over global config. If project
config sets model_select.favourite, it replaces the global favourites array.
How it works
On before_agent_start, the auto_session_name extension checks a series of
guards before doing any work. It only proceeds when all of the following hold:
- The feature is enabled in config.
- The session does not already have a name.
- The session is not a fork/child session.
- It is the user's first turn.
- The user prompt is non-empty.
If those pass, it resolves a model, generates a title via a dedicated
title-generation prompt, cleans the result, and persists it with
pi.setSessionName(). The work runs in a cancellable background task that is
aborted on session shutdown.
Development
This project uses Bun and Biome.
bun install # install dependencies
bun run check # biome fix + type-check
bun test # run tests
bun run buildSchema # regenerate assets/config.schema.json from the zod schemasProject structure
src/
index.ts # extension entry — lifecycle wiring only
config-loader.ts # loads + merges global/project config
constants.ts # EXTENSION_ID
schemas/ # zod config schemas (full + partial)
utils/ # path + model-resolution helpers
extensions/
auto-session-name/ # the auto_session_name feature
model-select/ # the model_select feature
custom-footer/ # the custom_footer feature
scripts/ # JSON schema generation
assets/config.schema.json # generated config schemaLicense
See repository for license details.
