tokmon 0.22.6 → 0.22.7
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 +4 -5
- package/dist/{bootstrap-ink-CHJWH5XC.js → bootstrap-ink-OHPQZKGB.js} +54 -170
- package/dist/{chunk-FO7IUYCM.js → chunk-EMQL5P5J.js} +2 -2
- package/dist/{chunk-AQNFQRWV.js → chunk-I4USANOF.js} +1527 -1143
- package/dist/{chunk-QTHCHB7S.js → chunk-TNIADJ3W.js} +3 -2
- package/dist/cli.js +5 -5
- package/dist/{config-64N7KBZ7.js → config-WLRQHLVJ.js} +1 -1
- package/dist/{daemon-ATXHNYTK.js → daemon-IP3UCTPB.js} +3 -3
- package/dist/server-GA2FKYDQ.js +9 -0
- package/dist/web/assets/{breakdown-Bj0BAVYf.js → breakdown-DU2j1sQ8.js} +1 -1
- package/dist/web/assets/{index-Dziiggw_.js → index-ygZyXDLT.js} +20 -20
- package/dist/web/assets/{timeline-BQpqTU-a.js → timeline-CO2B2c-0.js} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +2 -2
- package/dist/server-56C7MMEZ.js +0 -9
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# tokmon
|
|
2
2
|
|
|
3
|
-
Terminal dashboard for **Claude Code**, **Codex**, **Cursor**, **Copilot**, **opencode**, **pi**, **Antigravity**, and **
|
|
3
|
+
Terminal dashboard for **Claude Code**, **Codex**, **Cursor**, **Copilot**, **opencode**, **pi**, **Antigravity**, **Gemini**, and **Grok** — usage, costs, and rate limits, all in one place.
|
|
4
4
|
|
|
5
5
|
Built with [Ink](https://github.com/vadimdemedes/ink) and TypeScript.
|
|
6
6
|
|
|
@@ -34,14 +34,15 @@ Then run `tokmon`. On first launch you'll pick which providers to track; press `
|
|
|
34
34
|
|----------|---------------|--------------|
|
|
35
35
|
| **Claude** | `~/.claude/projects/**/*.jsonl` | Cost & token history, plan (e.g. Max 20x), live 5h / weekly / Sonnet limits |
|
|
36
36
|
| **Codex** | `~/.codex/sessions/**/rollout-*.jsonl` | Cost & token history, plan, live 5h / weekly limits, credit balance |
|
|
37
|
+
| **Cursor** | Cursor API usage events + local `composerData` | Cost & token history (Today / Week / Month), plan, period spend, on-demand caps |
|
|
37
38
|
| **opencode** | `~/.local/share/opencode/opencode.db` | Cost & token history across whatever providers opencode routes to (uses its own recorded cost) |
|
|
38
39
|
| **pi** | `~/.pi/agent/sessions/**/*.jsonl` | Cost & token history (uses pi's own recorded cost) |
|
|
40
|
+
| **Grok** | `~/.grok/logs/unified.jsonl` (+ session model join) | Cost & token history from Grok CLI turns, SuperGrok / credits billing when signed in |
|
|
39
41
|
|
|
40
42
|
**Billing / quota providers** — plan + live quota or spend (no local token history):
|
|
41
43
|
|
|
42
44
|
| Provider | What it reads | What you get |
|
|
43
45
|
|----------|---------------|--------------|
|
|
44
|
-
| **Cursor** | `state.vscdb` + local tracking DBs | Plan, current-period spend, on-demand caps, per-model spend, AI-code activity |
|
|
45
46
|
| **Copilot** | GitHub token (gh / VS Code) | Plan + premium-request & chat quota |
|
|
46
47
|
| **Antigravity** | its `state.vscdb` OAuth → Google Cloud Code | Plan + per-pool (Gemini Pro/Flash/Claude) quota |
|
|
47
48
|
| **Gemini** | `~/.gemini/oauth_creds.json` → Google Cloud Code | Plan + quota (re-run `gemini` to refresh an expired token) |
|
|
@@ -70,7 +71,7 @@ A **Peak / Off-Peak** badge appears in the header (Claude only), fetched from [p
|
|
|
70
71
|
|
|
71
72
|
Per-provider history with a provider selector (`p` / `P`), search (`/`), and sorting (`o`).
|
|
72
73
|
|
|
73
|
-
For **Claude / Codex** — Daily, Weekly, and Monthly breakdowns (6 months of history). Each row shows models used, input/output/cache tokens, and cost. Press `Enter` to expand a per-model breakdown:
|
|
74
|
+
For **Claude / Codex / Cursor / Grok** — Daily, Weekly, and Monthly breakdowns (6 months of history). Each row shows models used, input/output/cache tokens, and cost. Press `Enter` to expand a per-model breakdown:
|
|
74
75
|
|
|
75
76
|
```
|
|
76
77
|
▸ Apr 7 haiku-4-5, op~ 7.6K 487.0K 10.1M 1.1B $603.89
|
|
@@ -78,8 +79,6 @@ For **Claude / Codex** — Daily, Weekly, and Monthly breakdowns (6 months of hi
|
|
|
78
79
|
└─ haiku-4-5 100 2.0K 100K 5.0M $2.39
|
|
79
80
|
```
|
|
80
81
|
|
|
81
|
-
For **Cursor** — a per-model spend table (cost, request count, share of total, all-time), sourced from Cursor's local conversation data.
|
|
82
|
-
|
|
83
82
|
## Web Dashboard
|
|
84
83
|
|
|
85
84
|
Prefer a browser? `tokmon serve` starts a local web dashboard with the same data as the TUI — charts, global filtering, and shareable images — in a terminal-styled UI. Press `w` (or `W`) inside the TUI to toggle it without leaving the terminal; the header shows `● web :4317` while it's running.
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
coalesceTables,
|
|
11
11
|
col,
|
|
12
12
|
currency,
|
|
13
|
-
cursorModelSpend,
|
|
14
13
|
detectProviders,
|
|
15
14
|
fetchPeak,
|
|
16
15
|
modelColor,
|
|
@@ -20,7 +19,7 @@ import {
|
|
|
20
19
|
time,
|
|
21
20
|
tokens,
|
|
22
21
|
withTimeout
|
|
23
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-I4USANOF.js";
|
|
24
23
|
import {
|
|
25
24
|
COLOR_PALETTE,
|
|
26
25
|
DEFAULTS,
|
|
@@ -35,7 +34,7 @@ import {
|
|
|
35
34
|
sanitizeTyped,
|
|
36
35
|
saveConfigSync,
|
|
37
36
|
snapshotCacheFile
|
|
38
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-TNIADJ3W.js";
|
|
39
38
|
import {
|
|
40
39
|
glyphs
|
|
41
40
|
} from "./chunk-RF4GGQGM.js";
|
|
@@ -1246,62 +1245,6 @@ function RowDetail({ row, indent }) {
|
|
|
1246
1245
|
/* @__PURE__ */ jsx4(Text4, { bold: true, color: "yellow", children: currency(m.cost) })
|
|
1247
1246
|
] }, m.name)) });
|
|
1248
1247
|
}
|
|
1249
|
-
var CursorSpendTable = memo4(function CursorSpendTable2({ rows, cursor, maxRows, onRowClick }) {
|
|
1250
|
-
if (rows.length === 0) return /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "No Cursor spend recorded locally." });
|
|
1251
|
-
const total = rows.reduce((a, r) => a + r.usd, 0);
|
|
1252
|
-
const totalAmt = rows.reduce((a, r) => a + r.requests, 0);
|
|
1253
|
-
const clamped = Math.min(cursor, rows.length - 1);
|
|
1254
|
-
const scrollStart = Math.max(0, Math.min(clamped - Math.floor(maxRows / 2), rows.length - maxRows));
|
|
1255
|
-
const visible = rows.slice(scrollStart, scrollStart + maxRows);
|
|
1256
|
-
const W = { model: 34, cost: 12, amount: 12, share: 8 };
|
|
1257
|
-
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
1258
|
-
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1259
|
-
/* @__PURE__ */ jsxs4(Text4, { bold: true, children: [
|
|
1260
|
-
" ",
|
|
1261
|
-
col("Model", W.model, "left")
|
|
1262
|
-
] }),
|
|
1263
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, children: col("Cost", W.cost) }),
|
|
1264
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, children: col("Amount", W.amount) }),
|
|
1265
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, children: col("Share", W.share) })
|
|
1266
|
-
] }),
|
|
1267
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: glyphs().rule.repeat(W.model + W.cost + W.amount + W.share + 2) }),
|
|
1268
|
-
visible.map((r, vi) => {
|
|
1269
|
-
const idx = scrollStart + vi;
|
|
1270
|
-
const selected = idx === clamped;
|
|
1271
|
-
const share = total > 0 ? r.usd / total * 100 : 0;
|
|
1272
|
-
return /* @__PURE__ */ jsx4(ClickableBox, { onClick: () => onRowClick(idx), children: /* @__PURE__ */ jsxs4(Text4, { inverse: selected, children: [
|
|
1273
|
-
/* @__PURE__ */ jsxs4(Text4, { color: selected ? void 0 : "magenta", children: [
|
|
1274
|
-
selected ? `${glyphs().caretR} ` : " ",
|
|
1275
|
-
col(r.name, W.model, "left")
|
|
1276
|
-
] }),
|
|
1277
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, color: selected ? void 0 : "yellow", children: col(currency(r.usd), W.cost) }),
|
|
1278
|
-
/* @__PURE__ */ jsx4(Text4, { children: col(tokens(r.requests), W.amount) }),
|
|
1279
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: col(share.toFixed(1) + "%", W.share) })
|
|
1280
|
-
] }) }, r.name);
|
|
1281
|
-
}),
|
|
1282
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: glyphs().rule.repeat(W.model + W.cost + W.amount + W.share + 2) }),
|
|
1283
|
-
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1284
|
-
/* @__PURE__ */ jsxs4(Text4, { bold: true, color: "greenBright", children: [
|
|
1285
|
-
" ",
|
|
1286
|
-
col("Total", W.model, "left")
|
|
1287
|
-
] }),
|
|
1288
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, color: "yellowBright", children: col(currency(total), W.cost) }),
|
|
1289
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, color: "yellow", children: col(tokens(totalAmt), W.amount) }),
|
|
1290
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: col("100%", W.share) })
|
|
1291
|
-
] }),
|
|
1292
|
-
/* @__PURE__ */ jsx4(Box4, { height: 1 }),
|
|
1293
|
-
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
1294
|
-
"local spend by model (composerData) ",
|
|
1295
|
-
glyphs().middot,
|
|
1296
|
-
" est. API-equivalent ",
|
|
1297
|
-
glyphs().middot,
|
|
1298
|
-
" ",
|
|
1299
|
-
clamped + 1,
|
|
1300
|
-
"/",
|
|
1301
|
-
rows.length
|
|
1302
|
-
] })
|
|
1303
|
-
] });
|
|
1304
|
-
});
|
|
1305
1248
|
function fmtLabel(label) {
|
|
1306
1249
|
if (label.length === 7 && label[4] === "-") {
|
|
1307
1250
|
return `${MONTHS[Number(label.slice(5, 7))]} '${label.slice(2, 4)}`;
|
|
@@ -1965,15 +1908,6 @@ function toStatsMap(snapshot, accounts) {
|
|
|
1965
1908
|
}
|
|
1966
1909
|
return out;
|
|
1967
1910
|
}
|
|
1968
|
-
function toCursorRows(snapshot, accountId) {
|
|
1969
|
-
if (!snapshot || !accountId) return null;
|
|
1970
|
-
const wa = snapshot.accounts.find((a) => a.id === accountId);
|
|
1971
|
-
if (!wa) return null;
|
|
1972
|
-
if (wa.billingState === "pending") return null;
|
|
1973
|
-
const spend = wa.billing?.modelSpend;
|
|
1974
|
-
if (!spend) return [];
|
|
1975
|
-
return spend.map((m) => ({ name: m.name, usd: m.usd, requests: m.requests }));
|
|
1976
|
-
}
|
|
1977
1911
|
function pickTable(snapshot, accountIds) {
|
|
1978
1912
|
if (!snapshot) return null;
|
|
1979
1913
|
const byId = indexById(snapshot);
|
|
@@ -1994,11 +1928,6 @@ var SORTS = [
|
|
|
1994
1928
|
{ label: "cost", dir: "up" },
|
|
1995
1929
|
{ label: "cost", dir: "down" }
|
|
1996
1930
|
];
|
|
1997
|
-
var CURSOR_SORTS = [
|
|
1998
|
-
{ label: "cost", dir: "down" },
|
|
1999
|
-
{ label: "amount", dir: "down" },
|
|
2000
|
-
{ label: "model", dir: null }
|
|
2001
|
-
];
|
|
2002
1931
|
var acctKey = (a) => `${a.id}:${a.homeDir ?? ""}`;
|
|
2003
1932
|
var clampCaret = (caret, len) => Math.max(0, Math.min(caret, len));
|
|
2004
1933
|
function spliceInsert(value, caret, text) {
|
|
@@ -2098,22 +2027,6 @@ function filterTokenRows(rows, q) {
|
|
|
2098
2027
|
const s = q.toLowerCase();
|
|
2099
2028
|
return rows.filter((r) => r.label.toLowerCase().includes(s) || r.models.some((m) => m.toLowerCase().includes(s)));
|
|
2100
2029
|
}
|
|
2101
|
-
function filterCursorRows(rows, q) {
|
|
2102
|
-
if (!q) return rows;
|
|
2103
|
-
const s = q.toLowerCase();
|
|
2104
|
-
return rows.filter((r) => r.name.toLowerCase().includes(s));
|
|
2105
|
-
}
|
|
2106
|
-
function sortCursorRows(rows, sortIdx) {
|
|
2107
|
-
const out = [...rows];
|
|
2108
|
-
switch (sortIdx % CURSOR_SORTS.length) {
|
|
2109
|
-
case 1:
|
|
2110
|
-
return out.sort((a, b) => b.requests - a.requests);
|
|
2111
|
-
case 2:
|
|
2112
|
-
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
2113
|
-
default:
|
|
2114
|
-
return out.sort((a, b) => b.usd - a.usd);
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
2030
|
|
|
2118
2031
|
// src/ui/keybindings.ts
|
|
2119
2032
|
function handleKey(input, key, ctx) {
|
|
@@ -2176,7 +2089,6 @@ function handleKey(input, key, ctx) {
|
|
|
2176
2089
|
setExpanded,
|
|
2177
2090
|
setSort,
|
|
2178
2091
|
SORTS_FOR,
|
|
2179
|
-
tableIsCursor,
|
|
2180
2092
|
cycleTableModel: cycleTableModel2,
|
|
2181
2093
|
setView,
|
|
2182
2094
|
cursor,
|
|
@@ -2610,48 +2522,38 @@ function handleKey(input, key, ctx) {
|
|
|
2610
2522
|
resetView();
|
|
2611
2523
|
return;
|
|
2612
2524
|
}
|
|
2613
|
-
if (
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
return;
|
|
2618
|
-
}
|
|
2619
|
-
if (input === "w") {
|
|
2620
|
-
setView(1);
|
|
2621
|
-
resetView();
|
|
2622
|
-
return;
|
|
2623
|
-
}
|
|
2624
|
-
if (input === "m") {
|
|
2625
|
-
cycleTableModel2(1);
|
|
2626
|
-
return;
|
|
2627
|
-
}
|
|
2628
|
-
if (input === "M") {
|
|
2629
|
-
cycleTableModel2(-1);
|
|
2630
|
-
return;
|
|
2631
|
-
}
|
|
2632
|
-
if (key.leftArrow) {
|
|
2633
|
-
setView((v) => (v - 1 + VIEWS.length) % VIEWS.length);
|
|
2634
|
-
resetView();
|
|
2635
|
-
return;
|
|
2636
|
-
}
|
|
2637
|
-
if (key.rightArrow) {
|
|
2638
|
-
setView((v) => (v + 1) % VIEWS.length);
|
|
2639
|
-
resetView();
|
|
2640
|
-
return;
|
|
2641
|
-
}
|
|
2642
|
-
if (key.return) {
|
|
2643
|
-
setExpanded((e) => e === cursor ? -1 : cursor);
|
|
2644
|
-
return;
|
|
2645
|
-
}
|
|
2525
|
+
if (input === "d") {
|
|
2526
|
+
setView(0);
|
|
2527
|
+
resetView();
|
|
2528
|
+
return;
|
|
2646
2529
|
}
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
setTab((t) => (t + 1) % TABS.length);
|
|
2530
|
+
if (input === "w") {
|
|
2531
|
+
setView(1);
|
|
2650
2532
|
resetView();
|
|
2651
2533
|
return;
|
|
2652
2534
|
}
|
|
2653
|
-
|
|
2654
|
-
|
|
2535
|
+
if (input === "m") {
|
|
2536
|
+
cycleTableModel2(1);
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
if (input === "M") {
|
|
2540
|
+
cycleTableModel2(-1);
|
|
2541
|
+
return;
|
|
2542
|
+
}
|
|
2543
|
+
if (key.leftArrow) {
|
|
2544
|
+
setView((v) => (v - 1 + VIEWS.length) % VIEWS.length);
|
|
2545
|
+
resetView();
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
if (key.rightArrow) {
|
|
2549
|
+
setView((v) => (v + 1) % VIEWS.length);
|
|
2550
|
+
resetView();
|
|
2551
|
+
return;
|
|
2552
|
+
}
|
|
2553
|
+
if (key.return) {
|
|
2554
|
+
setExpanded((e) => e === cursor ? -1 : cursor);
|
|
2555
|
+
return;
|
|
2556
|
+
}
|
|
2655
2557
|
if (key.upArrow) {
|
|
2656
2558
|
setCursor((c) => Math.max(0, c - 1));
|
|
2657
2559
|
return;
|
|
@@ -2668,6 +2570,12 @@ function handleKey(input, key, ctx) {
|
|
|
2668
2570
|
setCursor((c) => input === "g" ? 0 : Math.max(0, c - Math.max(1, rows - 12)));
|
|
2669
2571
|
return;
|
|
2670
2572
|
}
|
|
2573
|
+
} else {
|
|
2574
|
+
if (key.leftArrow || key.rightArrow) {
|
|
2575
|
+
setTab((t) => (t + 1) % TABS.length);
|
|
2576
|
+
resetView();
|
|
2577
|
+
return;
|
|
2578
|
+
}
|
|
2671
2579
|
}
|
|
2672
2580
|
}
|
|
2673
2581
|
|
|
@@ -3055,7 +2963,6 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3055
2963
|
const [tableModel, setTableModel] = useState8(null);
|
|
3056
2964
|
const [search, setSearch] = useState8("");
|
|
3057
2965
|
const [searchMode, setSearchMode] = useState8(false);
|
|
3058
|
-
const [cursorRowsLocal, setCursorRows] = useState8(null);
|
|
3059
2966
|
const [showSettings, setShowSettings] = useState8(false);
|
|
3060
2967
|
const [settingsTab, setSettingsTab] = useState8("general");
|
|
3061
2968
|
const [settingsCursor, setSettingsCursor] = useState8(0);
|
|
@@ -3153,7 +3060,10 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3153
3060
|
() => focusId === null ? allGroups : accountsByProvider(visibleAccounts),
|
|
3154
3061
|
[allGroups, visibleAccounts, focusId]
|
|
3155
3062
|
);
|
|
3156
|
-
const tableProvs = useMemo2(
|
|
3063
|
+
const tableProvs = useMemo2(
|
|
3064
|
+
() => allGroups.map((g) => g.provider).filter((pid) => PROVIDERS[pid].hasUsage),
|
|
3065
|
+
[allGroups]
|
|
3066
|
+
);
|
|
3157
3067
|
const TOO_SMALL = cols < 40 || rows < 12;
|
|
3158
3068
|
const allReady = accounts.length > 0 && accounts.every((a) => accountReady(readyInputFor(a.id), a.providerId));
|
|
3159
3069
|
const { gridBudget } = useMemo2(() => computeChrome(slots, cols, rows), [slots, cols, rows]);
|
|
@@ -3193,21 +3103,16 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3193
3103
|
};
|
|
3194
3104
|
const { handlePasteData, isPasteInput } = usePaste(insertText);
|
|
3195
3105
|
const effTableProvider = tableProvider && tableProvs.includes(tableProvider) ? tableProvider : tableProvs[0] ?? null;
|
|
3196
|
-
const tableIsCursor = !!effTableProvider && !PROVIDERS[effTableProvider].hasUsage;
|
|
3197
3106
|
const tableAccounts = useMemo2(
|
|
3198
3107
|
() => effTableProvider ? accounts.filter((a) => a.providerId === effTableProvider) : [],
|
|
3199
3108
|
[accounts, effTableProvider]
|
|
3200
3109
|
);
|
|
3201
|
-
const SORTS_FOR =
|
|
3110
|
+
const SORTS_FOR = SORTS;
|
|
3202
3111
|
const tableAccountIds = useMemo2(() => tableAccounts.map((a) => a.id), [tableAccounts]);
|
|
3203
3112
|
const table = useMemo2(
|
|
3204
3113
|
() => connected ? pickTable(snapshot, tableAccountIds) : tableLocal,
|
|
3205
3114
|
[connected, snapshot, tableAccountIds, tableLocal]
|
|
3206
3115
|
);
|
|
3207
|
-
const cursorRows = useMemo2(
|
|
3208
|
-
() => connected ? toCursorRows(snapshot, tableAccounts[0]?.id) : cursorRowsLocal,
|
|
3209
|
-
[connected, snapshot, tableAccounts, cursorRowsLocal]
|
|
3210
|
-
);
|
|
3211
3116
|
const { showLoader } = useLoader({
|
|
3212
3117
|
configReady,
|
|
3213
3118
|
showPicker,
|
|
@@ -3236,11 +3141,10 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3236
3141
|
);
|
|
3237
3142
|
useEffect7(() => {
|
|
3238
3143
|
setTable(null);
|
|
3239
|
-
setCursorRows(null);
|
|
3240
3144
|
setCursor(0);
|
|
3241
3145
|
setExpanded(-1);
|
|
3242
3146
|
setTableModel(null);
|
|
3243
|
-
setSort(
|
|
3147
|
+
setSort(1);
|
|
3244
3148
|
setTableLoading(false);
|
|
3245
3149
|
}, [tableKey]);
|
|
3246
3150
|
useEffect7(() => {
|
|
@@ -3249,13 +3153,8 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3249
3153
|
let timer;
|
|
3250
3154
|
const fetchOnce = async () => {
|
|
3251
3155
|
try {
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
if (active) setCursorRows(s?.models ?? []);
|
|
3255
|
-
} else {
|
|
3256
|
-
const r = await withTimeout(fetchScopeTable(tableAccounts, tz));
|
|
3257
|
-
if (active) setTable(r);
|
|
3258
|
-
}
|
|
3156
|
+
const r = await withTimeout(fetchScopeTable(tableAccounts, tz));
|
|
3157
|
+
if (active) setTable(r);
|
|
3259
3158
|
} catch {
|
|
3260
3159
|
}
|
|
3261
3160
|
};
|
|
@@ -3392,8 +3291,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3392
3291
|
const cur = effTableProvider ? tableProvs.indexOf(effTableProvider) : 0;
|
|
3393
3292
|
const nextProv = tableProvs[(cur + dir + tableProvs.length) % tableProvs.length];
|
|
3394
3293
|
setTableProvider(nextProv);
|
|
3395
|
-
|
|
3396
|
-
setSort(nextIsCursor ? 0 : 1);
|
|
3294
|
+
setSort(1);
|
|
3397
3295
|
setCursor(0);
|
|
3398
3296
|
setExpanded(-1);
|
|
3399
3297
|
setTableModel(null);
|
|
@@ -3426,7 +3324,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3426
3324
|
if (webStartingRef.current) return;
|
|
3427
3325
|
webStartingRef.current = true;
|
|
3428
3326
|
try {
|
|
3429
|
-
const { startWebServer } = await import("./server-
|
|
3327
|
+
const { startWebServer } = await import("./server-GA2FKYDQ.js");
|
|
3430
3328
|
const ctrl = await startWebServer({ config: cfg, log: false });
|
|
3431
3329
|
webRef.current = ctrl;
|
|
3432
3330
|
openUrl(ctrl.url);
|
|
@@ -3456,10 +3354,9 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3456
3354
|
if (idx === cursor) setExpanded((e) => e === idx ? -1 : idx);
|
|
3457
3355
|
else setCursor(idx);
|
|
3458
3356
|
}, [cursor]);
|
|
3459
|
-
const onRowClickCursor = useCallback4((idx) => setCursor(idx), []);
|
|
3460
3357
|
const rawTokenRows = useMemo2(
|
|
3461
|
-
() => tab === 1
|
|
3462
|
-
[tab,
|
|
3358
|
+
() => tab === 1 ? table ? [table.daily, table.weekly, table.monthly][view] : [] : [],
|
|
3359
|
+
[tab, table, view]
|
|
3463
3360
|
);
|
|
3464
3361
|
const tokenModelOptions = useMemo2(() => tableModelOptions(rawTokenRows), [rawTokenRows]);
|
|
3465
3362
|
useEffect7(() => {
|
|
@@ -3471,12 +3368,8 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3471
3368
|
}, [tokenModelOptions, resetView]);
|
|
3472
3369
|
const activeTableModel = tableModel && tokenModelOptions.includes(tableModel) ? tableModel : null;
|
|
3473
3370
|
const tokenRows = useMemo2(
|
|
3474
|
-
() => tab === 1
|
|
3475
|
-
[tab,
|
|
3476
|
-
);
|
|
3477
|
-
const cursorTableRows = useMemo2(
|
|
3478
|
-
() => tab === 1 && tableIsCursor ? sortCursorRows(filterCursorRows(cursorRows ?? [], search), sort) : [],
|
|
3479
|
-
[tab, tableIsCursor, cursorRows, search, sort]
|
|
3371
|
+
() => tab === 1 ? sortRows(filterTokenRows(filterRowsByModel(rawTokenRows, activeTableModel), search), sort) : [],
|
|
3372
|
+
[tab, rawTokenRows, activeTableModel, search, sort]
|
|
3480
3373
|
);
|
|
3481
3374
|
useInput((input, key) => handleKey(input, key, {
|
|
3482
3375
|
showPicker,
|
|
@@ -3537,7 +3430,6 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3537
3430
|
setExpanded,
|
|
3538
3431
|
setSort,
|
|
3539
3432
|
SORTS_FOR,
|
|
3540
|
-
tableIsCursor,
|
|
3541
3433
|
cycleTableModel: cycleTableModelFilter,
|
|
3542
3434
|
setView,
|
|
3543
3435
|
cursor,
|
|
@@ -3568,7 +3460,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3568
3460
|
if (TOO_SMALL && !showSettings) {
|
|
3569
3461
|
return /* @__PURE__ */ jsx11(TinyFallback, { groups, stats, rows, cols });
|
|
3570
3462
|
}
|
|
3571
|
-
rowCountRef.current =
|
|
3463
|
+
rowCountRef.current = tokenRows.length;
|
|
3572
3464
|
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 2, paddingY: 1, height: rows, overflow: "hidden", children: [
|
|
3573
3465
|
/* @__PURE__ */ jsxs11(Box11, { justifyContent: "space-between", children: [
|
|
3574
3466
|
/* @__PURE__ */ jsxs11(Box11, { children: [
|
|
@@ -3660,8 +3552,8 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3660
3552
|
search,
|
|
3661
3553
|
searchCaret,
|
|
3662
3554
|
searching: searchMode,
|
|
3663
|
-
showPeriod:
|
|
3664
|
-
showModel:
|
|
3555
|
+
showPeriod: true,
|
|
3556
|
+
showModel: true
|
|
3665
3557
|
}
|
|
3666
3558
|
),
|
|
3667
3559
|
/* @__PURE__ */ jsx11(Box11, { height: 1 }),
|
|
@@ -3669,15 +3561,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3669
3561
|
"No providers enabled ",
|
|
3670
3562
|
glyphs().emDash,
|
|
3671
3563
|
" press s to pick providers."
|
|
3672
|
-
] }) : tableLoading && !table
|
|
3673
|
-
CursorSpendTable,
|
|
3674
|
-
{
|
|
3675
|
-
rows: cursorTableRows,
|
|
3676
|
-
cursor,
|
|
3677
|
-
maxRows: Math.max(1, rows - 16),
|
|
3678
|
-
onRowClick: onRowClickCursor
|
|
3679
|
-
}
|
|
3680
|
-
) : /* @__PURE__ */ jsx11(
|
|
3564
|
+
] }) : tableLoading && !table ? /* @__PURE__ */ jsx11(Spinner, { label: "Loading history" }) : /* @__PURE__ */ jsx11(
|
|
3681
3565
|
TokenTable,
|
|
3682
3566
|
{
|
|
3683
3567
|
rows: tokenRows,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
namedHex,
|
|
12
12
|
resolveTimezone,
|
|
13
13
|
withTimeout
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-I4USANOF.js";
|
|
15
15
|
import {
|
|
16
16
|
cacheDir,
|
|
17
17
|
expandHome,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
normalizeConfig,
|
|
20
20
|
saveConfig,
|
|
21
21
|
snapshotCacheFile
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-TNIADJ3W.js";
|
|
23
23
|
|
|
24
24
|
// src/web/server.ts
|
|
25
25
|
import { createServer } from "http";
|