pi-footer-manager
v1.1.0
Published
One footer, many extensions: build flexible Pi footers from reusable fragments with configurable layout and built-in fragments instead of competing `setFooter()` calls. `pi-footer-manager` lets one extension own footer rendering while built-in and custom
Maintainers
Readme
pi-footer-manager
One footer, many extensions: build flexible Pi footers from reusable fragments with configurable layout and built-in fragments instead of competing setFooter() calls.
pi-footer-manager lets one extension own ctx.ui.setFooter(...) while built-in and custom fragments are arranged through a shared API, with flexible rows, regions, widths, alignment, and redraw/invalidation flow.
Install or test
Install permanently:
pi install npm:pi-footer-managerTest without installing permanently:
pi --no-extensions -e npm:pi-footer-managerTo load it alongside your normal setup:
pi -e npm:pi-footer-manager
Included extensions
footer-manager/index.ts— cooperative footer ownerfragments/footer-timer-fragment.ts— example fragment showing elapsed work timefragments/quota-footer-fragment.ts— richer quota usage display for supported providersfragments/quota-footer-fragment-text.ts— text-focused quota usage displayfragments/context-gauge-text-fragment.ts— text version of context usage
Public API for custom fragment extensions
External extensions can integrate with the footer manager through:
import {
FOOTER_MANAGER_REGISTER_FRAGMENT,
FOOTER_MANAGER_UNREGISTER_FRAGMENT,
type FooterFragmentRegistration,
} from "pi-footer-manager/api";This is the supported public integration surface for custom fragment extensions. It avoids fragile cross-extension relative imports and lets third-party fragment extensions live in their own repos or packages.
How configuration works
Layout is configured under footerManager.layout in Pi settings.
separatorcontrols how fragments are joined inside a regionrowsis an array of footer rows- each row has
regions - each region can set:
width: fraction like0.35or"auto"align:"left","center", or"right"fragments: fragment ids to render in that region
Project settings override global settings.
Example: simple two-region footer
{
"footerManager": {
"layout": {
"separator": " > ",
"rows": [
{
"regions": [
{ "width": 0.65, "align": "left", "fragments": ["cwd.full", "git.branch", "context.gauge"] },
{ "width": 0.35, "align": "right", "fragments": ["model.name", "thinking.level", "statuses"] }
]
}
]
}
}
}Example: mostly automatic sizing
{
"footerManager": {
"layout": {
"rows": [
{
"regions": [
{ "align": "left", "fragments": ["cwd.full", "git.branch"] },
{ "width": 0.35, "align": "right", "fragments": ["model.name", "statuses"] }
]
}
]
}
}
}In mixed layouts, fixed fractional regions are allocated first and the remaining width goes to "auto" regions.
Example: multi-row footer
{
"footerManager": {
"layout": {
"rows": [
{
"regions": [
{ "align": "left", "fragments": ["cwd.full", "git.branch"] },
{ "align": "right", "fragments": ["model.name", "thinking.level"] }
]
},
{
"regions": [
{ "align": "left", "fragments": ["context.gauge.text", "quota.current.text", "timer.work"] }
]
}
]
}
}
}Widths and overflow
Think of each row as a fixed-width bar split into regions:
[ left region ][ right region ]For this layout:
{
"regions": [
{ "align": "left", "fragments": ["cwd.full", "git.branch"] },
{ "width": 0.35, "align": "right", "fragments": ["model.name", "statuses"] }
]
}The row behaves roughly like this:
[ cwd.full > git.branch ][ model.name > statuses ]Rules of thumb:
- fixed fractional regions get their width first
"auto"regions get the remaining space- if content does not fit, fragments are dropped before the final visible fragment is truncated
- left- and center-aligned regions drop fragments from the right
- right-aligned regions drop fragments from the left
Multi-row layouts behave like stacked bars:
row 1: [ cwd.full > git.branch ][ model.name > statuses ]
row 2: [ context.gauge.text > timer.work ]Built-in fragments
Main built-ins provided by footer-manager include:
cwd.full— full path of the current working directorycwd.shortened— current working directory, shortened from left to right when it exceeds half of the footer widthcwd.last— last directory of the current working directorygit.branch— current Git branch for the active working treegit.branch.shortened— shortened Git branch, hidden when it matches the last directory namemodel.name— active model namemodel.cost— input/output token pricing for the active modelmodel.cacheCost— cached token read/write pricing for the active modelcache.hit— cache hit rate summarycache.hit_counts— cache hit rate with read/write token countsthinking.level— current reasoning/thinking levelcontext.gauge— graphical context usage indicatorcost.total— total accumulated session coststatuses— status items contributed through Pi status APIs
The included fragment extensions add examples like:
timer.work— elapsed time for the current agent runcontext.gauge.text— text version of context usagequota.current— quota usage summary for supported providersquota.current.text— text-focused quota usage summary
Custom fragments
Other extensions should register fragments instead of calling ctx.ui.setFooter(...) directly.
See detailed fragment API docs and examples in:
The public integration module for external fragment extensions is pi-footer-manager/api.
Check
npm run checkPublish dry run
npm run release:check