@po.dev/pi-usage-dashboard 0.1.3 → 0.1.5

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.
Files changed (2) hide show
  1. package/index.ts +19 -20
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -755,7 +755,7 @@ class UsageComponent {
755
755
  return [truncateToWidth(summary, width), truncateToWidth(stats, width), ""];
756
756
  }
757
757
 
758
- private buildDailyProviderModel(): { days: { label: string; total: number; providers: Map<string, number> }[]; providers: { name: string; total: number; models: { name: string; cost: number; tokens: number; value: number }[] }[]; max: number; total: number } {
758
+ private buildDailyProviderModel(): { days: { label: string; total: number; providers: Map<string, number> }[]; providers: { name: string; total: number; tokens: number; models: { name: string; cost: number; tokens: number; value: number }[] }[]; max: number; total: number } {
759
759
  const now = this.data.bounds.nowMs;
760
760
  const start = this.activeTab === "today" ? this.data.bounds.todayMs : this.activeTab === "thisWeek" ? this.data.bounds.weekStartMs : this.activeTab === "lastWeek" ? this.data.bounds.lastWeekStartMs : this.activeTab === "last30Days" ? this.data.bounds.last30DaysStartMs : Math.min(...this.data.hourly.keys(), this.data.bounds.todayMs);
761
761
  const end = this.activeTab === "lastWeek" ? this.data.bounds.weekStartMs : now;
@@ -792,11 +792,10 @@ class UsageComponent {
792
792
  byModel.set(model, modelTotal);
793
793
  }
794
794
  }
795
- const providers = [...providerTotals.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([name, total]) => ({
796
- name,
797
- total,
798
- models: [...(modelTotals.get(name) ?? new Map()).entries()].sort((a, b) => b[1].value - a[1].value).map(([modelName, stats]) => ({ name: modelName, ...stats })),
799
- }));
795
+ const providers = [...providerTotals.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([name, total]) => {
796
+ const models = [...(modelTotals.get(name) ?? new Map()).entries()].sort((a, b) => b[1].value - a[1].value).map(([modelName, stats]) => ({ name: modelName, ...stats }));
797
+ return { name, total, tokens: models.reduce((sum, model) => sum + model.tokens, 0), models };
798
+ });
800
799
  return { days, providers, max: Math.max(0, ...days.map((d) => d.total)), total: days.reduce((sum, d) => sum + d.total, 0) };
801
800
  }
802
801
 
@@ -833,23 +832,23 @@ class UsageComponent {
833
832
  lines.push(th.fg("dim", " ".repeat(labelW) + " └" + Array.from({ length: axisW }, (_, i) => i % slotW === 0 ? "┬" : "─").join("")));
834
833
  lines.push(th.fg("dim", " ".repeat(labelW + 2) + days.map((day) => day.label.padEnd(slotW)).join("").trimEnd()));
835
834
  lines.push("");
835
+ const detail = model.providers.find((p) => p.name === this.graphDetailProvider);
836
+ const rows = detail?.models.slice(0, 8) ?? [];
837
+ const providerWidth = Math.max(24, ...model.providers.map((p) => visibleWidth(p.name)), ...rows.map((m) => visibleWidth(m.name)));
838
+ const costWidth = Math.max(visibleWidth("Cost ($)"), ...model.providers.map((p) => visibleWidth(formatValue(p.total))), ...rows.map((m) => visibleWidth(formatAxisCost(m.cost))));
839
+ const tokenWidth = Math.max(visibleWidth("Token usage"), ...model.providers.map((p) => visibleWidth(formatTokens(p.tokens))), ...rows.map((m) => visibleWidth(formatTokens(m.tokens))));
840
+ const treeIndent = " ";
841
+ lines.push(th.fg("muted", `${treeIndent} ${padRight("Model", providerWidth)} ${padLeft("Cost ($)", costWidth)} ${padLeft("Token usage", tokenWidth)}`));
836
842
  for (let i = 0; i < model.providers.length; i++) {
837
843
  const p = model.providers[i]!;
838
844
  const cursor = i === this.graphLegendIndex ? th.fg("accent", "▸ ") : " ";
839
- const marker = this.graphHidden.has(p.name) ? th.fg("dim", "·") : seriesColor(i) + "" + COLOR_RESET;
840
- lines.push(`${cursor}${marker} ${padRight(this.graphHidden.has(p.name) ? th.fg("dim", p.name) : p.name, 24)} ${padLeft(formatValue(p.total), 8)}`);
841
- }
842
- const detail = model.providers.find((p) => p.name === this.graphDetailProvider);
843
- if (detail) {
844
- const rows = detail.models.slice(0, 8);
845
- const prefix = " · ";
846
- const costWidth = Math.max(visibleWidth("Cost ($)"), ...rows.map((m) => visibleWidth(formatAxisCost(m.cost))));
847
- const tokenWidth = Math.max(visibleWidth("Token usage"), ...rows.map((m) => visibleWidth(formatTokens(m.tokens))));
848
- const modelWidth = Math.max(visibleWidth("Model"), Math.min(Math.max(...rows.map((m) => visibleWidth(m.name))), width - visibleWidth(prefix) - costWidth - tokenWidth - 3));
849
- lines.push("", th.fg("accent", `${detail.name} by model`));
850
- lines.push(this.theme.fg("muted", `${prefix}${padRight("Model", modelWidth)} ${padLeft("Cost ($)", costWidth)} ${padLeft("Token usage", tokenWidth)}`));
851
- for (const m of rows) {
852
- lines.push(`${prefix}${padRight(truncateToWidth(m.name, modelWidth), modelWidth)} ${padLeft(formatAxisCost(m.cost), costWidth)} ${padLeft(formatTokens(m.tokens), tokenWidth)}`);
845
+ const name = this.graphHidden.has(p.name) ? th.fg("dim", p.name) : i === this.graphLegendIndex ? th.fg("accent", p.name) : p.name;
846
+ lines.push(`${treeIndent}${cursor}${padRight(name, providerWidth + 2)} ${padLeft(formatValue(p.total), costWidth)} ${padLeft(formatTokens(p.tokens), tokenWidth)}`);
847
+ if (p !== detail) continue;
848
+ for (let j = 0; j < rows.length; j++) {
849
+ const m = rows[j]!;
850
+ const branch = j === rows.length - 1 ? "└" : "├";
851
+ lines.push(`${treeIndent} ${branch} ${padRight(truncateToWidth(m.name, providerWidth), providerWidth)} ${padLeft(formatAxisCost(m.cost), costWidth)} ${padLeft(formatTokens(m.tokens), tokenWidth)}`);
853
852
  }
854
853
  }
855
854
  lines.push("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@po.dev/pi-usage-dashboard",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Local token and cost dashboard for pi sessions",
5
5
  "keywords": [
6
6
  "pi-package",