tokmon 0.12.3 → 0.12.4

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/dist/cli.js +66 -46
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -484,8 +484,9 @@ async function fetchUsage(token) {
484
484
  resetsAt: formatReset(data.seven_day_sonnet.resets_at)
485
485
  } : null,
486
486
  extraUsage: data.extra_usage?.is_enabled ? {
487
- limit: data.extra_usage.monthly_limit / 100,
488
- used: data.extra_usage.used_credits / 100
487
+ limit: data.extra_usage.monthly_limit != null ? data.extra_usage.monthly_limit / 100 : null,
488
+ used: (data.extra_usage.used_credits ?? 0) / 100,
489
+ currency: data.extra_usage.currency ?? "USD"
489
490
  } : null
490
491
  }
491
492
  };
@@ -641,13 +642,13 @@ function App({ interval: cliInterval }) {
641
642
  });
642
643
  }, []);
643
644
  const billingMs = cfg.billingInterval * 6e4;
644
- const slotIdsKey = (activeSlot.id === null && cfg.accounts.length > 0 ? slots.slice(1) : [activeSlot]).map((s) => s.id ?? "__default__").join(",");
645
+ const dataSlots = cfg.accounts.length > 0 ? slots.slice(1) : slots;
646
+ const dataSlotsKey = dataSlots.map((s) => s.id ?? "__default__").join(",");
645
647
  useEffect(() => {
646
648
  if (!config2) return;
647
649
  let active = true;
648
- const slotsToLoad = activeSlot.id === null && cfg.accounts.length > 0 ? slots.slice(1) : [activeSlot];
649
650
  const load = async () => {
650
- await Promise.all(slotsToLoad.map(async (slot) => {
651
+ await Promise.all(dataSlots.map(async (slot) => {
651
652
  try {
652
653
  const dashboard = await fetchDashboard(tz, slot.homeDir);
653
654
  if (!active) return;
@@ -672,13 +673,12 @@ function App({ interval: cliInterval }) {
672
673
  active = false;
673
674
  clearInterval(id);
674
675
  };
675
- }, [interval2, tz, config2, slotIdsKey]);
676
+ }, [interval2, tz, config2, dataSlotsKey]);
676
677
  useEffect(() => {
677
678
  if (!config2) return;
678
679
  let active = true;
679
- const slotsToLoad = activeSlot.id === null && cfg.accounts.length > 0 ? slots.slice(1) : [activeSlot];
680
680
  const load = async () => {
681
- await Promise.all(slotsToLoad.map(async (slot) => {
681
+ await Promise.all(dataSlots.map(async (slot) => {
682
682
  try {
683
683
  const billing = await fetchBilling(slot.homeDir);
684
684
  if (!active) return;
@@ -698,7 +698,7 @@ function App({ interval: cliInterval }) {
698
698
  active = false;
699
699
  clearInterval(id);
700
700
  };
701
- }, [billingMs, config2, slotIdsKey]);
701
+ }, [billingMs, config2, dataSlotsKey]);
702
702
  useEffect(() => {
703
703
  tableLoadedOnce.current = false;
704
704
  setTable(null);
@@ -1155,19 +1155,7 @@ function App({ interval: cliInterval }) {
1155
1155
  activeAccountId: cfg.activeAccountId
1156
1156
  }
1157
1157
  ) : /* @__PURE__ */ jsxs(Fragment, { children: [
1158
- slots.length > 1 && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
1159
- AccountStrip,
1160
- {
1161
- slots,
1162
- activeIdx: activeSlotIdx,
1163
- onSelect: (i) => {
1164
- const id = slots[i].id;
1165
- updateConfig((c) => ({ ...c, activeAccountId: id }));
1166
- resetView();
1167
- }
1168
- }
1169
- ) }),
1170
- /* @__PURE__ */ jsxs(Box, { marginTop: slots.length > 1 ? 0 : 1, children: [
1158
+ /* @__PURE__ */ jsxs(Box, { marginTop: 1, children: [
1171
1159
  /* @__PURE__ */ jsx(TabBar, { tabs: TABS, active: tab, onSelect: (i) => {
1172
1160
  setTab(i);
1173
1161
  resetView();
@@ -1175,14 +1163,31 @@ function App({ interval: cliInterval }) {
1175
1163
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: " Tab/\u2190\u2192" })
1176
1164
  ] }),
1177
1165
  /* @__PURE__ */ jsx(Box, { height: 1 }),
1178
- tab === 0 && /* @__PURE__ */ jsx(
1179
- DashboardView,
1180
- {
1181
- slots: visibleSlots,
1182
- stats,
1183
- compact: visibleSlots.length > 1
1184
- }
1185
- ),
1166
+ tab === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1167
+ /* @__PURE__ */ jsx(
1168
+ DashboardView,
1169
+ {
1170
+ slots: visibleSlots,
1171
+ stats,
1172
+ compact: visibleSlots.length > 1
1173
+ }
1174
+ ),
1175
+ slots.length > 1 && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
1176
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Accounts" }),
1177
+ /* @__PURE__ */ jsx(Box, { marginTop: 0, children: /* @__PURE__ */ jsx(
1178
+ AccountStrip,
1179
+ {
1180
+ slots,
1181
+ activeIdx: activeSlotIdx,
1182
+ onSelect: (i) => {
1183
+ const id = slots[i].id;
1184
+ updateConfig((c) => ({ ...c, activeAccountId: id }));
1185
+ resetView();
1186
+ }
1187
+ }
1188
+ ) })
1189
+ ] })
1190
+ ] }),
1186
1191
  tab === 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
1187
1192
  /* @__PURE__ */ jsx(ViewBar, { views: VIEWS, active: view, sort: SORTS[sort], onSelect: (i) => {
1188
1193
  setView(i);
@@ -1685,17 +1690,19 @@ function RateLimitsCard({ items }) {
1685
1690
  items.map(({ slot, s }) => {
1686
1691
  const e = s.billing?.extraUsage;
1687
1692
  if (!e) return null;
1693
+ const sym = e.currency === "EUR" ? "\u20AC" : "$";
1688
1694
  return /* @__PURE__ */ jsxs(Box, { children: [
1689
1695
  /* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
1690
1696
  /* @__PURE__ */ jsx(Box, { width: 22, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateName(slot.name, 20) }) }),
1691
1697
  /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
1692
- "$",
1698
+ sym,
1693
1699
  e.used.toFixed(2)
1694
1700
  ] }),
1695
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
1696
- " / $",
1701
+ e.limit != null ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
1702
+ " / ",
1703
+ sym,
1697
1704
  e.limit.toFixed(2)
1698
- ] })
1705
+ ] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: " used" })
1699
1706
  ] }, slot.id ?? "__default__");
1700
1707
  })
1701
1708
  ] })
@@ -1711,8 +1718,12 @@ function MetricBlock({
1711
1718
  items,
1712
1719
  showResets
1713
1720
  }) {
1714
- const rows = items.map((i) => ({ slot: i.slot, lim: pick(i.s.billing) ?? null })).filter((r) => r.lim !== null);
1715
- if (rows.length === 0) return null;
1721
+ const rows = items.map((i) => ({
1722
+ slot: i.slot,
1723
+ lim: pick(i.s.billing) ?? null,
1724
+ error: i.s.billing?.error ?? null
1725
+ }));
1726
+ if (rows.every((r) => r.lim === null && !r.error)) return null;
1716
1727
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
1717
1728
  /* @__PURE__ */ jsxs(Box, { children: [
1718
1729
  /* @__PURE__ */ jsx(Text, { bold: true, children: label }),
@@ -1721,16 +1732,25 @@ function MetricBlock({
1721
1732
  sublabel
1722
1733
  ] })
1723
1734
  ] }),
1724
- rows.map(({ slot, lim }) => /* @__PURE__ */ jsx(
1725
- AccountLimitBar,
1726
- {
1727
- slot,
1728
- pct: lim.utilization,
1729
- resets: showResets ? lim.resetsAt : null,
1730
- showName: items.length > 1
1731
- },
1732
- slot.id ?? "__default__"
1733
- ))
1735
+ rows.map(({ slot, lim, error }) => {
1736
+ if (lim) {
1737
+ return /* @__PURE__ */ jsx(
1738
+ AccountLimitBar,
1739
+ {
1740
+ slot,
1741
+ pct: lim.utilization,
1742
+ resets: showResets ? lim.resetsAt : null,
1743
+ showName: items.length > 1
1744
+ },
1745
+ slot.id ?? "__default__"
1746
+ );
1747
+ }
1748
+ return /* @__PURE__ */ jsxs(Box, { children: [
1749
+ /* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
1750
+ /* @__PURE__ */ jsx(Box, { width: 22, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateName(slot.name, 20) }) }),
1751
+ /* @__PURE__ */ jsx(Text, { color: error ? "red" : void 0, dimColor: !error, children: error ?? "no data" })
1752
+ ] }, slot.id ?? "__default__");
1753
+ })
1734
1754
  ] });
1735
1755
  }
1736
1756
  function AccountLimitBar({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokmon",
3
- "version": "0.12.3",
3
+ "version": "0.12.4",
4
4
  "description": "Terminal dashboard for Claude Code usage and costs",
5
5
  "type": "module",
6
6
  "bin": {