feat: add configurable pi statusbar extension
This commit is contained in:
106
modules/basic.ts
Normal file
106
modules/basic.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { homedir } from "node:os";
|
||||
import type { ModuleContext, RenderedModule } from "../types";
|
||||
|
||||
function formatTokens(count: number): string {
|
||||
if (count < 1000) return count.toString();
|
||||
if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
|
||||
if (count < 1000000) return `${Math.round(count / 1000)}k`;
|
||||
if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;
|
||||
return `${Math.round(count / 1000000)}M`;
|
||||
}
|
||||
|
||||
function sessionEntries(ctx: any): any[] {
|
||||
try {
|
||||
return ctx.sessionManager?.getEntries?.() ?? [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function totalCost(ctx: any): number {
|
||||
return sessionEntries(ctx).reduce((total, entry) => {
|
||||
const cost =
|
||||
entry?.type === "message" && entry.message?.role === "assistant"
|
||||
? entry.message.usage?.cost?.total
|
||||
: undefined;
|
||||
return (
|
||||
total + (typeof cost === "number" && Number.isFinite(cost) ? cost : 0)
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function isUsingSubscription(ctx: any): boolean {
|
||||
const provider = ctx.model?.provider;
|
||||
if (!provider) return false;
|
||||
try {
|
||||
return Boolean(ctx.modelRegistry?.isUsingOAuth?.(ctx.model));
|
||||
} catch {
|
||||
return provider === "anthropic" || provider === "openai-codex";
|
||||
}
|
||||
}
|
||||
|
||||
export function directoryModule(moduleCtx: ModuleContext): RenderedModule {
|
||||
const cwd = moduleCtx.ctx.sessionManager?.getCwd?.() ?? process.cwd();
|
||||
const home = homedir();
|
||||
let text = home && cwd.startsWith(home) ? `~${cwd.slice(home.length)}` : cwd;
|
||||
|
||||
// Git And Session Name
|
||||
const options = moduleCtx.config.modules.directory;
|
||||
if (options?.showGitBranch) {
|
||||
const branch = moduleCtx.footerData?.getGitBranch?.();
|
||||
if (branch) text = `${text} (${branch})`;
|
||||
}
|
||||
if (options?.showSessionName) {
|
||||
const sessionName = moduleCtx.ctx.sessionManager?.getSessionName?.();
|
||||
if (sessionName) text = `${text} • ${sessionName}`;
|
||||
}
|
||||
|
||||
return { text };
|
||||
}
|
||||
|
||||
export function contextModule(moduleCtx: ModuleContext): RenderedModule {
|
||||
const usage = moduleCtx.ctx.getContextUsage?.();
|
||||
const contextWindow =
|
||||
usage?.contextWindow ?? moduleCtx.ctx.model?.contextWindow ?? 0;
|
||||
const percent = usage?.percent;
|
||||
const showWindow = moduleCtx.config.modules.context?.showWindow ?? false;
|
||||
const value =
|
||||
percent === null || percent === undefined
|
||||
? "?"
|
||||
: `${Number(percent).toFixed(1)}%`;
|
||||
return {
|
||||
text: showWindow ? `${value} / ${formatTokens(contextWindow)}` : `${value}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function modelModule(moduleCtx: ModuleContext): RenderedModule {
|
||||
const model = moduleCtx.ctx.model;
|
||||
if (!model) return { text: "no-model" };
|
||||
|
||||
// Model Label
|
||||
const options = moduleCtx.config.modules.model;
|
||||
const provider = options?.showProvider ? `(${model.provider}) ` : "";
|
||||
let text = `${provider}${model.id}`;
|
||||
if (options?.showThinking && model.reasoning) {
|
||||
const thinking = moduleCtx.state.thinkingLevel ?? "off";
|
||||
text = thinking === "off" ? `${text} thinking off` : `${text} ${thinking}`;
|
||||
}
|
||||
return { text };
|
||||
}
|
||||
|
||||
export function thinkingModule(moduleCtx: ModuleContext): RenderedModule {
|
||||
if (!moduleCtx.ctx.model?.reasoning) return { text: "" };
|
||||
const level = moduleCtx.state.thinkingLevel ?? "off";
|
||||
if (level === "off" && moduleCtx.config.modules.thinking?.hideWhenOff)
|
||||
return { text: "" };
|
||||
return { text: `think ${level}` };
|
||||
}
|
||||
|
||||
export function costModule(moduleCtx: ModuleContext): RenderedModule {
|
||||
const cost = totalCost(moduleCtx.ctx);
|
||||
const subscription = isUsingSubscription(moduleCtx.ctx);
|
||||
if (!cost && !subscription) return { text: "" };
|
||||
if (subscription && moduleCtx.config.modules.cost?.showSubscription !== false)
|
||||
return { text: cost ? `$${cost.toFixed(3)} sub` : "sub" };
|
||||
return { text: `$${cost.toFixed(3)}` };
|
||||
}
|
||||
Reference in New Issue
Block a user