@tzlzl/pi-footer0.1.0
Official two-row Pi footer replacement with truthful lifecycle, context, session totals, extension statuses, and pi-usage quota bridge.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
@tzlzl/pi-footer
An independent two-row footer replacement for Pi 0.99.2+, implemented through Pi's official ctx.ui.setFooter() API. It does not patch Pi core or editor files.
The fixed layout is:
project branch | activity model THINK (5h 72% · wk 84%)
ctx ▰▰▰▱▱ 56% ↓18k ↑3.4k $0.08 other-extension status
The visual | separates working-directory identity from lifecycle activity. The model/quota and extension-status columns are aligned by available width; there is no third row. Narrow terminals progressively drop session cost/token details, the context bar, branch/project identity, and then shorten activity/model/quota strings. ANSI-aware truncation keeps both rows within the terminal width, including very narrow widths.
Data sources and privacy
- Working directory and branch are read from the current Pi context and official footer data provider.
- Activity is based on Pi lifecycle events only. Bash command text and other arbitrary tool arguments are never displayed. File targets are reduced to sanitized path components.
- Context comes from
ctx.getContextUsage(). Unknown context is rendered asctx ?, never as zero. - Session totals follow Pi's native footer accounting across persisted usage, assistant, tool-result, compaction, and branch-summary entries. Cost is omitted unless a finite recorded cost exists.
- Other extensions'
ctx.ui.setStatus()values are shown on row two. Provider usage is shown beside the model on row one, preferably from a current matching pi-usage snapshot. Legacy native usage strings are labeledusage, not guessed to be remaining percentages. - The footer never queries providers. No credentials, account labels, or authentication fingerprints are exchanged.
External text is stripped of terminal control sequences and control characters before rendering. Theme colors are applied at render time, so theme changes do not leave cached ANSI colors behind.
pi-usage bridge
The footer emits pi-usage:footer-request with { sessionId } after session start, model changes, and active branch changes. pi-usage may answer on pi-usage:footer with the following contract (as implemented by its src/footer-bridge.ts):
{
version: 1,
sessionId: "active-session-id",
providerId: "provider-id",
modelId: "model-id",
status: "ready", // auth-unavailable | query-failed | selection-required | unsupported | cleared
semantics: "remaining", // usage | unavailable
text: "Codex 5h 72% · week 84%", // formatted windows; no reset countdown
remainingPercent: 72, // optional finite number in [0, 100]
capturedAt: Date.now(), // optional finite number
}
Payloads are validated at runtime and accepted only for the active session and exact current provider/model. On session shutdown and /footer off, the event subscription is removed; enabling again requests a fresh snapshot. A stale/missing snapshot renders ? when no native usage status is available. A native usage status, if present, is preserved beside the model with an explicit usage or status label; it is never treated as a reliable declaration of remaining percentages.
Ready remaining snapshots render the emitted value directly, such as 32% or ¥20, without a rest prefix. A percent is remaining quota and a currency amount is remaining balance. Each window's existing percentage is preserved without appending a duplicate. remainingPercent only chooses its semantic tone: green at >=40%, yellow above 15%, red at <=15%. If no denominator/percentage is known, no percentage or status color is inferred. semantics: "usage" remains explicitly labeled usage (including Fireworks spend); semantics: "unavailable" retains its reported unavailable state with a status label, never remaining quota. Non-ready status values produce a warning status, not a zero balance.
Activity and lifecycle
Waiting-for-model, thinking/responding, tool execution, user-input prompts, completion, abort, and errors are mapped from Pi's public events. Concurrent tools are tracked by call ID. A running or later action replaces an earlier error; the error stays only when it is the current settled result, until the next action. Generic permission-needed state is not fabricated because Pi exposes no authoritative lifecycle event for it.
The spinner refreshes at most every 100ms and only while a model/tool operation is active. Its interval and the footer's git listener are disposed with the footer component. Completion timers are canceled on a new run, session transition, disable, or shutdown. Pi's native working indicator is hidden while this footer is enabled, because the activity column already shows the running state. /footer off restores the default indicator.
Controls
/footer offdisables this component and restores Pi's built-in footer./footer onenables it and requests a current quota snapshot.- Commands are TUI-only; other modes receive a warning and do not change footer state.
/footer off restores the built-in footer, not an unknown custom footer installed by another extension. Use this extension only if it is acceptable for it to own Pi's footer while enabled.
Install with pi install npm:@tzlzl/pi-footer@0.1.0. Do not also leave a copy in ~/.pi/agent/extensions/.
Development
npm install --ignore-scripts
npm run check