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.
- package/README.md +2 -1
- package/dist/cli.js +33 -9
- 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** —
|
|
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
|
|
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,
|
|
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(
|
|
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
|
|
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: "
|
|
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 }),
|