tokmon 0.9.1 → 0.9.2

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 (3) hide show
  1. package/README.md +2 -1
  2. package/dist/cli.js +33 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -96,7 +96,8 @@ Sort by date or cost with `o`.
96
96
 
97
97
  Press `s` to open. Persisted to `~/.config/tokmon/config.json` (macOS/Linux) or `%APPDATA%\tokmon\config.json` (Windows).
98
98
 
99
- - **Refresh interval** — adjust with `←` `→`
99
+ - **Refresh interval** — dashboard poll rate (default: 2s)
100
+ - **Billing poll** — rate limits API poll rate (default: 5m, min 1m to avoid 429s)
100
101
  - **Clear screen** — clears terminal on launch (like `watch`)
101
102
 
102
103
  ## How It Works
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import { MouseProvider } from "@zenobius/ink-mouse";
8
8
  import { readFile, writeFile, mkdir } from "fs/promises";
9
9
  import { join } from "path";
10
10
  import { homedir } from "os";
11
- var DEFAULTS = { interval: 2, clearScreen: true };
11
+ var DEFAULTS = { interval: 2, billingInterval: 5, clearScreen: true };
12
12
  function configDir() {
13
13
  if (process.platform === "win32") {
14
14
  return join(process.env.APPDATA ?? join(homedir(), "AppData", "Roaming"), "tokmon");
@@ -310,7 +310,7 @@ async function fetchBilling() {
310
310
  },
311
311
  signal: AbortSignal.timeout(1e4)
312
312
  });
313
- if (res.status === 429) return { ...EMPTY, error: "Rate limited \u2014 retrying in 2m" };
313
+ if (res.status === 429) return { ...EMPTY, error: "Rate limited \u2014 retrying next poll" };
314
314
  if (res.status === 401) return { ...EMPTY, error: "Token expired \u2014 restart Claude Code" };
315
315
  if (!res.ok) return { ...EMPTY, error: `API ${res.status}` };
316
316
  const data = await res.json();
@@ -387,7 +387,7 @@ var VIEWS = ["Daily", "Weekly", "Monthly"];
387
387
  var SORTS = ["date \u2191", "date \u2193", "cost \u2191", "cost \u2193"];
388
388
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
389
389
  var MONTHS = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
390
- var DEFAULT_CONFIG = { interval: 2, clearScreen: true };
390
+ var DEFAULT_CONFIG = { interval: 2, billingInterval: 5, clearScreen: true };
391
391
  var IS_TTY = process.stdin.isTTY === true;
392
392
  function App({ interval: cliInterval }) {
393
393
  const [dashboard, setDashboard] = useState(null);
@@ -438,6 +438,7 @@ function App({ interval: cliInterval }) {
438
438
  clearInterval(id);
439
439
  };
440
440
  }, [interval2]);
441
+ const billingMs = cfg.billingInterval * 6e4;
441
442
  useEffect(() => {
442
443
  let active = true;
443
444
  const load = () => fetchBilling().then((b) => {
@@ -445,12 +446,12 @@ function App({ interval: cliInterval }) {
445
446
  }).catch(() => {
446
447
  });
447
448
  load();
448
- const id = setInterval(load, 12e4);
449
+ const id = setInterval(load, billingMs);
449
450
  return () => {
450
451
  active = false;
451
452
  clearInterval(id);
452
453
  };
453
- }, []);
454
+ }, [billingMs]);
454
455
  useEffect(() => {
455
456
  if (tab !== 1) return;
456
457
  if (tableLoadedOnce.current && table) return;
@@ -506,12 +507,16 @@ function App({ interval: cliInterval }) {
506
507
  if (showSettings) {
507
508
  if (key.escape || input === "s") setShowSettings(false);
508
509
  if (key.upArrow) setSettingsCursor((c) => Math.max(0, c - 1));
509
- if (key.downArrow) setSettingsCursor((c) => Math.min(1, c + 1));
510
+ if (key.downArrow) setSettingsCursor((c) => Math.min(2, c + 1));
510
511
  if (settingsCursor === 0) {
511
512
  if (key.leftArrow) updateConfig((c) => ({ ...c, interval: Math.max(1, c.interval - 1) }));
512
513
  if (key.rightArrow) updateConfig((c) => ({ ...c, interval: c.interval + 1 }));
513
514
  }
514
- if (settingsCursor === 1 && (key.leftArrow || key.rightArrow || key.return)) {
515
+ if (settingsCursor === 1) {
516
+ if (key.leftArrow) updateConfig((c) => ({ ...c, billingInterval: Math.max(1, c.billingInterval - 1) }));
517
+ if (key.rightArrow) updateConfig((c) => ({ ...c, billingInterval: c.billingInterval + 1 }));
518
+ }
519
+ if (settingsCursor === 2 && (key.leftArrow || key.rightArrow || key.return)) {
515
520
  updateConfig((c) => ({ ...c, clearScreen: !c.clearScreen }));
516
521
  }
517
522
  return;
@@ -721,7 +726,7 @@ function SettingsView({ config: config2, cursor }) {
721
726
  cursor === 0 ? "\u25B8" : " ",
722
727
  " "
723
728
  ] }),
724
- /* @__PURE__ */ jsx(Text, { children: "Refresh interval " }),
729
+ /* @__PURE__ */ jsx(Text, { children: "Refresh interval " }),
725
730
  /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
726
731
  "\u25C2",
727
732
  " "
@@ -740,7 +745,26 @@ function SettingsView({ config: config2, cursor }) {
740
745
  cursor === 1 ? "\u25B8" : " ",
741
746
  " "
742
747
  ] }),
743
- /* @__PURE__ */ jsx(Text, { children: "Clear screen " }),
748
+ /* @__PURE__ */ jsx(Text, { children: "Billing poll " }),
749
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
750
+ "\u25C2",
751
+ " "
752
+ ] }),
753
+ /* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", children: [
754
+ config2.billingInterval,
755
+ "m"
756
+ ] }),
757
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
758
+ " ",
759
+ "\u25B8"
760
+ ] })
761
+ ] }),
762
+ /* @__PURE__ */ jsxs(Box, { children: [
763
+ /* @__PURE__ */ jsxs(Text, { color: cursor === 2 ? "green" : void 0, children: [
764
+ cursor === 2 ? "\u25B8" : " ",
765
+ " "
766
+ ] }),
767
+ /* @__PURE__ */ jsx(Text, { children: "Clear screen " }),
744
768
  /* @__PURE__ */ jsx(Text, { bold: true, color: config2.clearScreen ? "green" : "red", children: config2.clearScreen ? "on" : "off" })
745
769
  ] }),
746
770
  /* @__PURE__ */ jsx(Box, { height: 1 }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokmon",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "Terminal dashboard for Claude Code usage and costs",
5
5
  "type": "module",
6
6
  "bin": {