tokmon 0.26.0 → 0.27.0

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.
@@ -217,6 +217,25 @@ function metricValueText(m) {
217
217
  // src/ui/dashboard.tsx
218
218
  import { memo as memo2 } from "react";
219
219
  import { Box as Box2, Text as Text2 } from "ink";
220
+
221
+ // src/ui/provider-card.logic.ts
222
+ function normalizePlan(plan) {
223
+ if (plan == null) return null;
224
+ const t = plan.trim();
225
+ return t === "" ? null : t;
226
+ }
227
+ function planDisplay(rawPlans) {
228
+ const plans = rawPlans.map(normalizePlan);
229
+ const named = plans.filter((p) => p != null);
230
+ if (named.length === 0) return { mode: "none" };
231
+ if (plans.length === 1) return { mode: "header", plan: named[0] };
232
+ const allNamed = named.length === plans.length;
233
+ const allEqual = named.every((p) => p === named[0]);
234
+ if (allNamed && allEqual) return { mode: "header", plan: named[0] };
235
+ return { mode: "perRow", count: plans.length };
236
+ }
237
+
238
+ // src/ui/dashboard.tsx
220
239
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
221
240
  var GAP = 2;
222
241
  var MIN_CARD = 56;
@@ -325,7 +344,7 @@ function ProviderCard({ provider, accounts, stats, width, variant, privacyMode =
325
344
  const items = accounts.map((a) => ({ account: a, s: stats.get(a.id) }));
326
345
  const dashboards = items.map((i) => i.s?.dashboard).filter((d) => !!d);
327
346
  const agg = meta.hasUsage && dashboards.length > 0 ? aggregate(dashboards) : null;
328
- const plan = items.map((i) => i.s?.billing?.plan).find(Boolean) ?? null;
347
+ const planView = planDisplay(items.map((i) => i.s?.billing?.plan));
329
348
  const activity = items.map((i) => i.s?.billing?.activity).find(Boolean) ?? null;
330
349
  const inner = width - 4;
331
350
  const hasSpark = !!agg && agg.series.some((v) => v > 0);
@@ -339,7 +358,11 @@ function ProviderCard({ provider, accounts, stats, width, variant, privacyMode =
339
358
  ] }),
340
359
  /* @__PURE__ */ jsx2(Text2, { bold: true, color: meta.color, children: meta.name }),
341
360
  /* @__PURE__ */ jsx2(Box2, { flexGrow: 1 }),
342
- plan && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: plan })
361
+ planView.mode === "header" && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: planView.plan }),
362
+ planView.mode === "perRow" && /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
363
+ planView.count,
364
+ " accounts"
365
+ ] })
343
366
  ] }),
344
367
  meta.hasUsage && (agg ? /* @__PURE__ */ jsxs2(Fragment, { children: [
345
368
  /* @__PURE__ */ jsx2(Box2, { height: 1 }),
@@ -356,7 +379,7 @@ function ProviderCard({ provider, accounts, stats, width, variant, privacyMode =
356
379
  ] })),
357
380
  meta.hasBilling && showBars && /* @__PURE__ */ jsxs2(Fragment, { children: [
358
381
  meta.hasUsage && /* @__PURE__ */ jsx2(Rule, { inner }),
359
- /* @__PURE__ */ jsx2(LimitsBlock, { items, inner, privacyMode, resetDisplay, tz })
382
+ /* @__PURE__ */ jsx2(LimitsBlock, { items, inner, showRowPlans: planView.mode === "perRow", privacyMode, resetDisplay, tz })
360
383
  ] }),
361
384
  meta.hasBilling && !showBars && !meta.hasUsage && /* @__PURE__ */ jsx2(CompactBilling, { items, privacyMode }),
362
385
  hasSpark && showSpark && /* @__PURE__ */ jsxs2(Fragment, { children: [
@@ -429,7 +452,7 @@ function accountTitle(account, billing, privacyMode = false) {
429
452
  const title = email && !account.name.includes("@") ? `${account.name} ${email}` : account.name;
430
453
  return privacyMode ? redactEmail(title) : title;
431
454
  }
432
- function LimitsBlock({ items, inner, privacyMode, resetDisplay, tz }) {
455
+ function LimitsBlock({ items, inner, showRowPlans, privacyMode, resetDisplay, tz }) {
433
456
  const showName = items.length > 1;
434
457
  const labels = items.flatMap((i) => i.s?.billing?.metrics ?? []).map((m) => m.label.length);
435
458
  const labelW = Math.min(Math.max(7, ...labels) + 1, 14);
@@ -438,13 +461,24 @@ function LimitsBlock({ items, inner, privacyMode, resetDisplay, tz }) {
438
461
  return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: items.map(({ account, s }, idx) => {
439
462
  const billing = s?.billing;
440
463
  return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: showName && idx > 0 ? 1 : 0, children: [
441
- showName && /* @__PURE__ */ jsxs2(Box2, { children: [
442
- /* @__PURE__ */ jsxs2(Text2, { color: account.color, children: [
443
- glyphs().dot,
444
- " "
445
- ] }),
446
- /* @__PURE__ */ jsx2(Text2, { bold: true, children: truncateName(accountTitle(account, billing, privacyMode), Math.max(22, inner - 2)) })
447
- ] }),
464
+ showName && (() => {
465
+ const rowPlan = showRowPlans ? normalizePlan(billing?.plan) : null;
466
+ const planCap = Math.max(0, inner - 25);
467
+ const shownPlan = rowPlan && planCap >= 4 ? truncateName(rowPlan, planCap) : "";
468
+ const planReserve = shownPlan ? shownPlan.length + 1 : 0;
469
+ const nameBudget = Math.max(22, inner - 2 - planReserve);
470
+ return /* @__PURE__ */ jsxs2(Box2, { children: [
471
+ /* @__PURE__ */ jsxs2(Text2, { color: account.color, children: [
472
+ glyphs().dot,
473
+ " "
474
+ ] }),
475
+ /* @__PURE__ */ jsx2(Text2, { bold: true, children: truncateName(accountTitle(account, billing, privacyMode), nameBudget) }),
476
+ shownPlan && /* @__PURE__ */ jsxs2(Fragment, { children: [
477
+ /* @__PURE__ */ jsx2(Box2, { flexGrow: 1 }),
478
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: shownPlan })
479
+ ] })
480
+ ] });
481
+ })(),
448
482
  !billing ? /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
449
483
  "Fetching",
450
484
  glyphs().ellipsis
package/dist/cli.js CHANGED
@@ -128,7 +128,7 @@ Run tokmon ${subcommand} --help for usage.
128
128
  }));
129
129
  const daemon = await attachOrSpawn();
130
130
  const mode = daemon.kind === "spawned" ? "connected" : "degraded";
131
- const { bootstrapInk } = await import("./bootstrap-ink-5UFPNDV4.js");
131
+ const { bootstrapInk } = await import("./bootstrap-ink-3YNJFKCW.js");
132
132
  await bootstrapInk({ interval, config, daemon, mode });
133
133
  }
134
134
  void main().catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokmon",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Terminal + web dashboard for Claude Code, Codex, Cursor, Grok, opencode, pi, Copilot, Gemini & more — usage, limits, and costs",
5
5
  "type": "module",
6
6
  "bin": {