@po.dev/pi-usage-dashboard 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +27 -5
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -1192,7 +1192,7 @@ function footerModelLabel(ctx: Pick<ExtensionCommandContext, "model" | "thinking
|
|
|
1192
1192
|
return model.reasoning && ctx.thinkingLevel ? `${label} • ${ctx.thinkingLevel}` : label;
|
|
1193
1193
|
}
|
|
1194
1194
|
|
|
1195
|
-
function setUsageFooter(ctx: Pick<ExtensionCommandContext, "ui" | "model" | "thinkingLevel" | "getContextUsage">, totals: TotalStats): void {
|
|
1195
|
+
function setUsageFooter(ctx: Pick<ExtensionCommandContext, "ui" | "model" | "thinkingLevel" | "getContextUsage">, totals: TotalStats, sessionTotals: TotalStats | null): void {
|
|
1196
1196
|
ctx.ui.setFooter((_tui, theme) => ({
|
|
1197
1197
|
invalidate() {},
|
|
1198
1198
|
render(width: number): string[] {
|
|
@@ -1202,7 +1202,10 @@ function setUsageFooter(ctx: Pick<ExtensionCommandContext, "ui" | "model" | "thi
|
|
|
1202
1202
|
const contextStatus = context
|
|
1203
1203
|
? " · " + theme.fg("warning", `${context.percent?.toFixed(1) ?? "?"}%`) + theme.fg("dim", "/") + theme.fg("success", `${left} left`) + " " + theme.fg("accent", "(auto)")
|
|
1204
1204
|
: "";
|
|
1205
|
-
const
|
|
1205
|
+
const sessionPart = sessionTotals
|
|
1206
|
+
? theme.fg("success", "(Session)") + " · " + theme.fg("accent", formatCost(sessionTotals.cost)) + " · " + theme.fg("text", `${formatTokens(sessionTotals.tokens.total)} tokens`) + " · " + theme.fg("success", `↑${formatTokens(sessionTotals.tokens.input + sessionTotals.tokens.cacheWrite)}`) + " · " + theme.fg("warning", `↓${formatTokens(sessionTotals.tokens.output)}`) + " "
|
|
1207
|
+
: "";
|
|
1208
|
+
const usage = theme.fg("thinkingHigh", "Usage:") + " " + sessionPart + theme.fg("accent", "(Today)") + " · " + theme.fg("accent", formatCost(totals.cost)) + " · " + theme.fg("text", `${formatTokens(totals.tokens.total)} tokens`) + " · " + theme.fg("success", `↑${formatTokens(totals.tokens.input + totals.tokens.cacheWrite)}`) + " · " + theme.fg("warning", `↓${formatTokens(totals.tokens.output)}`) + " · " + theme.fg("thinkingHigh", `${formatTokens(totals.tokens.cacheRead + totals.tokens.cacheWrite)} cache`) + contextStatus;
|
|
1206
1209
|
const model = theme.fg("accent", footerModelLabel(ctx));
|
|
1207
1210
|
const gap = width - visibleWidth(usage) - visibleWidth(model);
|
|
1208
1211
|
return [gap >= 2 ? usage + " ".repeat(gap) + model : truncateToWidth(usage, width)];
|
|
@@ -1211,6 +1214,8 @@ function setUsageFooter(ctx: Pick<ExtensionCommandContext, "ui" | "model" | "thi
|
|
|
1211
1214
|
}
|
|
1212
1215
|
|
|
1213
1216
|
export default function (pi: ExtensionAPI) {
|
|
1217
|
+
let sessionTotals: TotalStats = { sessions: 0, messages: 0, cost: 0, tokens: { total: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } };
|
|
1218
|
+
|
|
1214
1219
|
const refreshFooter = (ctx: Pick<ExtensionCommandContext, "hasUI" | "ui" | "model" | "thinkingLevel" | "getContextUsage">) => {
|
|
1215
1220
|
if (!ctx.hasUI) return;
|
|
1216
1221
|
void collectUsageData().then((data) => {
|
|
@@ -1221,14 +1226,31 @@ export default function (pi: ExtensionAPI) {
|
|
|
1221
1226
|
totals.messages += stats.messages; totals.cost += stats.cost;
|
|
1222
1227
|
totals.tokens.total += stats.tokens.total; totals.tokens.input += stats.tokens.input; totals.tokens.output += stats.tokens.output; totals.tokens.cacheRead += stats.tokens.cacheRead; totals.tokens.cacheWrite += stats.tokens.cacheWrite;
|
|
1223
1228
|
}
|
|
1224
|
-
setUsageFooter(ctx, totals);
|
|
1229
|
+
setUsageFooter(ctx, totals, sessionTotals);
|
|
1225
1230
|
});
|
|
1226
1231
|
};
|
|
1227
1232
|
const snapshotPrompt = (ctx: { sessionManager: { getSessionId(): string }; getSystemPrompt(): string }) => {
|
|
1228
1233
|
try { savePromptSnapshot(ctx.sessionManager.getSessionId(), ctx.getSystemPrompt()); } catch { /* usage must never block Pi */ }
|
|
1229
1234
|
};
|
|
1230
|
-
pi.on("session_start", (_event, ctx) => {
|
|
1231
|
-
|
|
1235
|
+
pi.on("session_start", (_event, ctx) => {
|
|
1236
|
+
sessionTotals = { sessions: 0, messages: 0, cost: 0, tokens: { total: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } };
|
|
1237
|
+
snapshotPrompt(ctx);
|
|
1238
|
+
refreshFooter(ctx);
|
|
1239
|
+
});
|
|
1240
|
+
pi.on("message_end", (event, ctx) => {
|
|
1241
|
+
if (event.message.role === "assistant") {
|
|
1242
|
+
const u = event.message.usage;
|
|
1243
|
+
sessionTotals.messages++;
|
|
1244
|
+
sessionTotals.cost += u.cost.total;
|
|
1245
|
+
sessionTotals.tokens.total += u.totalTokens;
|
|
1246
|
+
sessionTotals.tokens.input += u.input;
|
|
1247
|
+
sessionTotals.tokens.output += u.output;
|
|
1248
|
+
sessionTotals.tokens.cacheRead += u.cacheRead;
|
|
1249
|
+
sessionTotals.tokens.cacheWrite += u.cacheWrite;
|
|
1250
|
+
}
|
|
1251
|
+
snapshotPrompt(ctx);
|
|
1252
|
+
refreshFooter(ctx);
|
|
1253
|
+
});
|
|
1232
1254
|
pi.on("model_select", (_event, ctx) => { refreshFooter(ctx); });
|
|
1233
1255
|
pi.registerCommand("usage", {
|
|
1234
1256
|
description: "Show usage statistics dashboard",
|