tokmon 0.12.2 → 0.12.3

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 +81 -29
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -434,16 +434,15 @@ async function readMacKeychain() {
434
434
  }
435
435
  }
436
436
  async function getAccessToken(homeDir) {
437
- if (homeDir) {
438
- const fromFile = await readCredentialsFile(homeDir);
439
- if (fromFile) return fromFile;
440
- return null;
441
- }
442
- if (process.platform === "darwin") {
443
- const token = await readMacKeychain();
444
- if (token) return token;
437
+ const isDefault = !homeDir || homeDir === homedir3();
438
+ if (isDefault) {
439
+ if (process.platform === "darwin") {
440
+ const token = await readMacKeychain();
441
+ if (token) return token;
442
+ }
443
+ return readCredentialsFile(homeDir);
445
444
  }
446
- return readCredentialsFile();
445
+ return readCredentialsFile(homeDir);
447
446
  }
448
447
  var EMPTY = { session: null, weekly: null, sonnet: null, extraUsage: null, peak: null, error: null };
449
448
  async function fetchBilling(homeDir) {
@@ -580,6 +579,9 @@ var DEFAULT_CONFIG = {
580
579
  };
581
580
  var GENERAL_ROWS = 4;
582
581
  var IS_TTY = process.stdin.isTTY === true;
582
+ function truncateName(s, n) {
583
+ return s.length > n ? s.slice(0, n - 1) + "\u2026" : s;
584
+ }
583
585
  function buildSlots(config2) {
584
586
  const slots = [];
585
587
  if (config2.accounts.length === 0) {
@@ -638,27 +640,30 @@ function App({ interval: cliInterval }) {
638
640
  setConfig(c);
639
641
  });
640
642
  }, []);
643
+ 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(",");
641
645
  useEffect(() => {
642
646
  if (!config2) return;
643
647
  let active = true;
644
648
  const slotsToLoad = activeSlot.id === null && cfg.accounts.length > 0 ? slots.slice(1) : [activeSlot];
645
649
  const load = async () => {
646
- try {
647
- const next = /* @__PURE__ */ new Map();
648
- await Promise.all(slotsToLoad.map(async (slot) => {
649
- const [dashboard, billing] = await Promise.all([
650
- fetchDashboard(tz, slot.homeDir),
651
- fetchBilling(slot.homeDir)
652
- ]);
653
- next.set(slotKey(slot), { slot, dashboard, billing });
654
- }));
655
- if (active) {
656
- setStats(next);
657
- setError(null);
658
- setUpdated(/* @__PURE__ */ new Date());
650
+ await Promise.all(slotsToLoad.map(async (slot) => {
651
+ try {
652
+ const dashboard = await fetchDashboard(tz, slot.homeDir);
653
+ if (!active) return;
654
+ setStats((prev) => {
655
+ const next = new Map(prev);
656
+ const cur = next.get(slotKey(slot)) ?? { slot, dashboard: null, billing: null };
657
+ next.set(slotKey(slot), { ...cur, slot, dashboard });
658
+ return next;
659
+ });
660
+ } catch (e) {
661
+ if (active) setError(e instanceof Error ? e.message : String(e));
659
662
  }
660
- } catch (e) {
661
- if (active) setError(e instanceof Error ? e.message : String(e));
663
+ }));
664
+ if (active) {
665
+ setError(null);
666
+ setUpdated(/* @__PURE__ */ new Date());
662
667
  }
663
668
  };
664
669
  load();
@@ -667,7 +672,33 @@ function App({ interval: cliInterval }) {
667
672
  active = false;
668
673
  clearInterval(id);
669
674
  };
670
- }, [interval2, tz, config2, activeSlot.id]);
675
+ }, [interval2, tz, config2, slotIdsKey]);
676
+ useEffect(() => {
677
+ if (!config2) return;
678
+ let active = true;
679
+ const slotsToLoad = activeSlot.id === null && cfg.accounts.length > 0 ? slots.slice(1) : [activeSlot];
680
+ const load = async () => {
681
+ await Promise.all(slotsToLoad.map(async (slot) => {
682
+ try {
683
+ const billing = await fetchBilling(slot.homeDir);
684
+ if (!active) return;
685
+ setStats((prev) => {
686
+ const next = new Map(prev);
687
+ const cur = next.get(slotKey(slot)) ?? { slot, dashboard: null, billing: null };
688
+ next.set(slotKey(slot), { ...cur, slot, billing });
689
+ return next;
690
+ });
691
+ } catch {
692
+ }
693
+ }));
694
+ };
695
+ load();
696
+ const id = setInterval(load, billingMs);
697
+ return () => {
698
+ active = false;
699
+ clearInterval(id);
700
+ };
701
+ }, [billingMs, config2, slotIdsKey]);
671
702
  useEffect(() => {
672
703
  tableLoadedOnce.current = false;
673
704
  setTable(null);
@@ -813,6 +844,21 @@ function App({ interval: cliInterval }) {
813
844
  activeAccountId: c.activeAccountId === id ? null : c.activeAccountId
814
845
  }));
815
846
  }
847
+ function moveAccount(idx, dir) {
848
+ updateConfig((c) => {
849
+ const next = [...c.accounts];
850
+ const target = idx + dir;
851
+ if (target < 0 || target >= next.length) return c;
852
+ [next[idx], next[target]] = [next[target], next[idx]];
853
+ return { ...c, accounts: next };
854
+ });
855
+ setSettingsCursor((c) => {
856
+ const target = c + dir;
857
+ const min = accountRowsStart;
858
+ const max = accountRowsStart + cfg.accounts.length - 1;
859
+ return Math.max(min, Math.min(max, target));
860
+ });
861
+ }
816
862
  const accountRowsStart = GENERAL_ROWS;
817
863
  const totalSettingsRows = GENERAL_ROWS + cfg.accounts.length + 1;
818
864
  useInput((input, key) => {
@@ -915,6 +961,12 @@ function App({ interval: cliInterval }) {
915
961
  setShowSettings(false);
916
962
  return;
917
963
  }
964
+ const accIdxNav = settingsCursor - accountRowsStart;
965
+ const onAccountRow = accIdxNav >= 0 && accIdxNav < cfg.accounts.length;
966
+ if (onAccountRow && key.shift && (key.upArrow || key.downArrow)) {
967
+ moveAccount(accIdxNav, key.upArrow ? -1 : 1);
968
+ return;
969
+ }
918
970
  if (key.upArrow) {
919
971
  setSettingsCursor((c) => Math.max(0, c - 1));
920
972
  return;
@@ -1346,7 +1398,7 @@ function SettingsView({
1346
1398
  /* @__PURE__ */ jsx(Text, { children: "Add account" })
1347
1399
  ] }),
1348
1400
  /* @__PURE__ */ jsx(Box, { height: 1 }),
1349
- editingTz ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "type IANA name (e.g. Europe/London) \xB7 empty = System \xB7 Enter save \xB7 Esc cancel" }) : cursor >= accountRowsStart && cursor < accountRowsStart + config2.accounts.length ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 select \xB7 Enter edit \xB7 space activate \xB7 d delete \xB7 s/Esc close" }) : cursor === accountRowsStart + config2.accounts.length ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 select \xB7 Enter add account \xB7 s/Esc close" }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 select \u2190\u2192 adjust Enter edit s/Esc close" })
1401
+ editingTz ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "type IANA name (e.g. Europe/London) \xB7 empty = System \xB7 Enter save \xB7 Esc cancel" }) : cursor >= accountRowsStart && cursor < accountRowsStart + config2.accounts.length ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 select \xB7 \u21E7\u2191\u2193 reorder \xB7 Enter edit \xB7 space activate \xB7 d delete \xB7 s/Esc close" }) : cursor === accountRowsStart + config2.accounts.length ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 select \xB7 Enter add account \xB7 s/Esc close" }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 select \u2190\u2192 adjust Enter edit s/Esc close" })
1350
1402
  ] });
1351
1403
  }
1352
1404
  function AccountFormView({ form, accounts }) {
@@ -1622,7 +1674,7 @@ function RateLimitsCard({ items }) {
1622
1674
  /* @__PURE__ */ jsx(Box, { height: 1 }),
1623
1675
  !anyData ? anyError ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: items.map(({ slot, s }) => s.billing?.error && /* @__PURE__ */ jsxs(Box, { children: [
1624
1676
  /* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
1625
- /* @__PURE__ */ jsx(Box, { width: 12, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: slot.name }) }),
1677
+ /* @__PURE__ */ jsx(Box, { width: 22, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateName(slot.name, 20) }) }),
1626
1678
  /* @__PURE__ */ jsx(Text, { color: "red", children: s.billing.error })
1627
1679
  ] }, slot.id ?? "__default__")) }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Fetching..." }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
1628
1680
  /* @__PURE__ */ jsx(MetricBlock, { label: "Total Usage", sublabel: "5h session", pick: (b) => b?.session, items, showResets: true }),
@@ -1635,7 +1687,7 @@ function RateLimitsCard({ items }) {
1635
1687
  if (!e) return null;
1636
1688
  return /* @__PURE__ */ jsxs(Box, { children: [
1637
1689
  /* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
1638
- /* @__PURE__ */ jsx(Box, { width: 12, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: slot.name }) }),
1690
+ /* @__PURE__ */ jsx(Box, { width: 22, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateName(slot.name, 20) }) }),
1639
1691
  /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
1640
1692
  "$",
1641
1693
  e.used.toFixed(2)
@@ -1691,7 +1743,7 @@ function AccountLimitBar({
1691
1743
  const filled = Math.max(0, Math.min(width, Math.round(pct / 100 * width)));
1692
1744
  return /* @__PURE__ */ jsxs(Box, { children: [
1693
1745
  /* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
1694
- showName ? /* @__PURE__ */ jsx(Box, { width: 12, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: slot.name }) }) : /* @__PURE__ */ jsx(Box, { width: 2, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
1746
+ showName ? /* @__PURE__ */ jsx(Box, { width: 22, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateName(slot.name, 20) }) }) : /* @__PURE__ */ jsx(Box, { width: 2, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
1695
1747
  /* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u2501".repeat(filled) }),
1696
1748
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(width - filled) }),
1697
1749
  /* @__PURE__ */ jsx(Text, { children: " " }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokmon",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "description": "Terminal dashboard for Claude Code usage and costs",
5
5
  "type": "module",
6
6
  "bin": {