tokmon 0.12.1 → 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.
- package/dist/cli.js +222 -242
- 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
|
-
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
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
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
setError(
|
|
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
|
-
}
|
|
661
|
-
|
|
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,
|
|
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 }) {
|
|
@@ -1525,70 +1577,46 @@ function ColorField({ value, focused }) {
|
|
|
1525
1577
|
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: " shows on dashboard, account strip, borders" }) })
|
|
1526
1578
|
] });
|
|
1527
1579
|
}
|
|
1528
|
-
function DashboardView({ slots, stats, compact }) {
|
|
1529
|
-
const slotKey = (
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
const slot = slots[0];
|
|
1535
|
-
const s = stats.get(slotKey(slot));
|
|
1536
|
-
if (!s?.dashboard) {
|
|
1537
|
-
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1538
|
-
/* @__PURE__ */ jsxs(Text, { color: slot.color, bold: true, children: [
|
|
1539
|
-
"\u25CF ",
|
|
1540
|
-
slot.name,
|
|
1541
|
-
" "
|
|
1542
|
-
] }),
|
|
1543
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "loading..." })
|
|
1544
|
-
] });
|
|
1545
|
-
}
|
|
1546
|
-
return /* @__PURE__ */ jsx(SoloAccountCard, { slot, dashboard: s.dashboard, billing: s.billing });
|
|
1547
|
-
}
|
|
1548
|
-
function bar(value, max, width) {
|
|
1549
|
-
if (max <= 0) return { filled: 0, empty: width };
|
|
1550
|
-
const filled = Math.max(0, Math.min(width, Math.round(value / max * width)));
|
|
1551
|
-
return { filled, empty: width - filled };
|
|
1552
|
-
}
|
|
1553
|
-
function SoloAccountCard({ slot, dashboard, billing }) {
|
|
1554
|
-
const maxCost = Math.max(dashboard.today.cost, dashboard.week.cost, dashboard.month.cost, 0.01);
|
|
1555
|
-
const maxTokens = Math.max(dashboard.today.tokens, dashboard.week.tokens, dashboard.month.tokens, 1);
|
|
1556
|
-
const rows = [
|
|
1557
|
-
{ label: "Today", s: dashboard.today },
|
|
1558
|
-
{ label: "This Week", s: dashboard.week },
|
|
1559
|
-
{ label: "This Month", s: dashboard.month }
|
|
1560
|
-
];
|
|
1580
|
+
function DashboardView({ slots, stats, compact: _compact }) {
|
|
1581
|
+
const slotKey = (s) => s.id ?? "__default__";
|
|
1582
|
+
const items = slots.map((slot) => ({ slot, s: stats.get(slotKey(slot)) })).filter((x) => !!x.s?.dashboard);
|
|
1583
|
+
if (items.length === 0) return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Loading..." });
|
|
1584
|
+
const agg = aggregateUsage(items.map((i) => i.s.dashboard));
|
|
1585
|
+
const isMulti = items.length > 1;
|
|
1561
1586
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1562
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1563
|
-
/* @__PURE__ */ jsxs(Text, { color: slot.color, bold: true, children: [
|
|
1564
|
-
"\u25CF ",
|
|
1565
|
-
slot.name
|
|
1566
|
-
] }),
|
|
1567
|
-
slot.id && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1568
|
-
" ",
|
|
1569
|
-
slot.id
|
|
1570
|
-
] })
|
|
1571
|
-
] }),
|
|
1572
1587
|
/* @__PURE__ */ jsxs(
|
|
1573
1588
|
Box,
|
|
1574
1589
|
{
|
|
1575
1590
|
flexDirection: "column",
|
|
1576
|
-
marginTop: 1,
|
|
1577
1591
|
paddingLeft: 1,
|
|
1578
1592
|
borderStyle: "bold",
|
|
1579
|
-
borderColor: slot.color,
|
|
1593
|
+
borderColor: isMulti ? "green" : items[0].slot.color,
|
|
1580
1594
|
borderRight: false,
|
|
1581
1595
|
borderTop: false,
|
|
1582
1596
|
borderBottom: false,
|
|
1583
1597
|
children: [
|
|
1584
|
-
/* @__PURE__ */
|
|
1598
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1599
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Claude" }),
|
|
1600
|
+
isMulti && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1601
|
+
" all accounts (",
|
|
1602
|
+
items.length,
|
|
1603
|
+
")"
|
|
1604
|
+
] }),
|
|
1605
|
+
!isMulti && items[0].slot.id && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1606
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
1607
|
+
/* @__PURE__ */ jsx(Text, { color: items[0].slot.color, children: "\u25CF " }),
|
|
1608
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: items[0].slot.name })
|
|
1609
|
+
] })
|
|
1610
|
+
] }),
|
|
1585
1611
|
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
1586
|
-
|
|
1587
|
-
|
|
1612
|
+
/* @__PURE__ */ jsx(SummaryRow, { label: "Today", summary: agg.today }),
|
|
1613
|
+
/* @__PURE__ */ jsx(SummaryRow, { label: "This Week", summary: agg.week }),
|
|
1614
|
+
/* @__PURE__ */ jsx(SummaryRow, { label: "This Month", summary: agg.month }),
|
|
1615
|
+
agg.burnRate > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1588
1616
|
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
1589
1617
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1590
1618
|
/* @__PURE__ */ jsx(Box, { width: 14, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Burn rate" }) }),
|
|
1591
|
-
/* @__PURE__ */ jsx(Box, { width: 12, justifyContent: "flex-end", children: /* @__PURE__ */ jsx(Text, { color: "red", children: currency(
|
|
1619
|
+
/* @__PURE__ */ jsx(Box, { width: 12, justifyContent: "flex-end", children: /* @__PURE__ */ jsx(Text, { color: "red", children: currency(agg.burnRate) }) }),
|
|
1592
1620
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "/hr" })
|
|
1593
1621
|
] })
|
|
1594
1622
|
] })
|
|
@@ -1596,166 +1624,137 @@ function SoloAccountCard({ slot, dashboard, billing }) {
|
|
|
1596
1624
|
}
|
|
1597
1625
|
),
|
|
1598
1626
|
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
1599
|
-
/* @__PURE__ */
|
|
1600
|
-
Box,
|
|
1601
|
-
{
|
|
1602
|
-
flexDirection: "column",
|
|
1603
|
-
paddingLeft: 1,
|
|
1604
|
-
borderStyle: "bold",
|
|
1605
|
-
borderColor: billing?.error ? "red" : "yellow",
|
|
1606
|
-
borderRight: false,
|
|
1607
|
-
borderTop: false,
|
|
1608
|
-
borderBottom: false,
|
|
1609
|
-
children: [
|
|
1610
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "Rate Limits" }),
|
|
1611
|
-
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
1612
|
-
billing?.error ? /* @__PURE__ */ jsx(Text, { color: "red", children: billing.error }) : billing?.session || billing?.weekly ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1613
|
-
billing.session && /* @__PURE__ */ jsx(LimitBar, { label: "Session", pct: billing.session.utilization, resets: billing.session.resetsAt }),
|
|
1614
|
-
billing.weekly && /* @__PURE__ */ jsx(LimitBar, { label: "Weekly", pct: billing.weekly.utilization, resets: billing.weekly.resetsAt }),
|
|
1615
|
-
billing.sonnet && /* @__PURE__ */ jsx(LimitBar, { label: "Sonnet", pct: billing.sonnet.utilization, resets: billing.sonnet.resetsAt }),
|
|
1616
|
-
billing.extraUsage && /* @__PURE__ */ jsxs(Box, { children: [
|
|
1617
|
-
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Extra" }) }),
|
|
1618
|
-
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
1619
|
-
"$",
|
|
1620
|
-
billing.extraUsage.used.toFixed(2)
|
|
1621
|
-
] }),
|
|
1622
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1623
|
-
" / $",
|
|
1624
|
-
billing.extraUsage.limit.toFixed(2),
|
|
1625
|
-
" limit"
|
|
1626
|
-
] })
|
|
1627
|
-
] })
|
|
1628
|
-
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Fetching..." })
|
|
1629
|
-
]
|
|
1630
|
-
}
|
|
1631
|
-
)
|
|
1627
|
+
/* @__PURE__ */ jsx(RateLimitsCard, { items })
|
|
1632
1628
|
] });
|
|
1633
1629
|
}
|
|
1634
|
-
function
|
|
1630
|
+
function aggregateUsage(list) {
|
|
1631
|
+
const z = {
|
|
1632
|
+
today: { cost: 0, tokens: 0 },
|
|
1633
|
+
week: { cost: 0, tokens: 0 },
|
|
1634
|
+
month: { cost: 0, tokens: 0 },
|
|
1635
|
+
burnRate: 0
|
|
1636
|
+
};
|
|
1637
|
+
for (const d of list) {
|
|
1638
|
+
z.today.cost += d.today.cost;
|
|
1639
|
+
z.today.tokens += d.today.tokens;
|
|
1640
|
+
z.week.cost += d.week.cost;
|
|
1641
|
+
z.week.tokens += d.week.tokens;
|
|
1642
|
+
z.month.cost += d.month.cost;
|
|
1643
|
+
z.month.tokens += d.month.tokens;
|
|
1644
|
+
z.burnRate += d.burnRate;
|
|
1645
|
+
}
|
|
1646
|
+
return z;
|
|
1647
|
+
}
|
|
1648
|
+
function SummaryRow({ label, summary }) {
|
|
1649
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1650
|
+
/* @__PURE__ */ jsx(Box, { width: 14, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: label }) }),
|
|
1651
|
+
/* @__PURE__ */ jsx(Box, { width: 12, justifyContent: "flex-end", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: currency(summary.cost) }) }),
|
|
1652
|
+
/* @__PURE__ */ jsx(Box, { width: 18, justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1653
|
+
tokens(summary.tokens),
|
|
1654
|
+
" tokens"
|
|
1655
|
+
] }) })
|
|
1656
|
+
] });
|
|
1657
|
+
}
|
|
1658
|
+
function RateLimitsCard({ items }) {
|
|
1659
|
+
const anyData = items.some((i) => i.s.billing?.session || i.s.billing?.weekly || i.s.billing?.sonnet);
|
|
1660
|
+
const anyError = items.some((i) => i.s.billing?.error);
|
|
1661
|
+
const borderColor = !anyData && anyError ? "red" : "yellow";
|
|
1662
|
+
return /* @__PURE__ */ jsxs(
|
|
1663
|
+
Box,
|
|
1664
|
+
{
|
|
1665
|
+
flexDirection: "column",
|
|
1666
|
+
paddingLeft: 1,
|
|
1667
|
+
borderStyle: "bold",
|
|
1668
|
+
borderColor,
|
|
1669
|
+
borderRight: false,
|
|
1670
|
+
borderTop: false,
|
|
1671
|
+
borderBottom: false,
|
|
1672
|
+
children: [
|
|
1673
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Rate Limits" }),
|
|
1674
|
+
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
1675
|
+
!anyData ? anyError ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: items.map(({ slot, s }) => s.billing?.error && /* @__PURE__ */ jsxs(Box, { children: [
|
|
1676
|
+
/* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
|
|
1677
|
+
/* @__PURE__ */ jsx(Box, { width: 22, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateName(slot.name, 20) }) }),
|
|
1678
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: s.billing.error })
|
|
1679
|
+
] }, slot.id ?? "__default__")) }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Fetching..." }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1680
|
+
/* @__PURE__ */ jsx(MetricBlock, { label: "Total Usage", sublabel: "5h session", pick: (b) => b?.session, items, showResets: true }),
|
|
1681
|
+
/* @__PURE__ */ jsx(MetricBlock, { label: "This Week", sublabel: "7-day", pick: (b) => b?.weekly, items, showResets: true }),
|
|
1682
|
+
/* @__PURE__ */ jsx(MetricBlock, { label: "Sonnet", sublabel: "7-day sonnet", pick: (b) => b?.sonnet, items }),
|
|
1683
|
+
items.some((i) => i.s.billing?.extraUsage) && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1684
|
+
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "Extra Usage" }),
|
|
1685
|
+
items.map(({ slot, s }) => {
|
|
1686
|
+
const e = s.billing?.extraUsage;
|
|
1687
|
+
if (!e) return null;
|
|
1688
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1689
|
+
/* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
|
|
1690
|
+
/* @__PURE__ */ jsx(Box, { width: 22, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateName(slot.name, 20) }) }),
|
|
1691
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
1692
|
+
"$",
|
|
1693
|
+
e.used.toFixed(2)
|
|
1694
|
+
] }),
|
|
1695
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1696
|
+
" / $",
|
|
1697
|
+
e.limit.toFixed(2)
|
|
1698
|
+
] })
|
|
1699
|
+
] }, slot.id ?? "__default__");
|
|
1700
|
+
})
|
|
1701
|
+
] })
|
|
1702
|
+
] })
|
|
1703
|
+
]
|
|
1704
|
+
}
|
|
1705
|
+
);
|
|
1706
|
+
}
|
|
1707
|
+
function MetricBlock({
|
|
1635
1708
|
label,
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
color
|
|
1709
|
+
sublabel,
|
|
1710
|
+
pick,
|
|
1711
|
+
items,
|
|
1712
|
+
showResets
|
|
1641
1713
|
}) {
|
|
1642
|
-
const
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 0, children: [
|
|
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;
|
|
1716
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1646
1717
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1647
|
-
/* @__PURE__ */ jsx(
|
|
1648
|
-
/* @__PURE__ */
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1718
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: label }),
|
|
1719
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1720
|
+
" ",
|
|
1721
|
+
sublabel
|
|
1722
|
+
] })
|
|
1652
1723
|
] }),
|
|
1653
|
-
/* @__PURE__ */
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2591".repeat(t.empty) }),
|
|
1657
|
-
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1658
|
-
/* @__PURE__ */ jsx(Box, { width: 11, justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1659
|
-
tokens(tokens2),
|
|
1660
|
-
" tk"
|
|
1661
|
-
] }) })
|
|
1662
|
-
] })
|
|
1663
|
-
] });
|
|
1664
|
-
}
|
|
1665
|
-
function ComparisonView({ accountStats }) {
|
|
1666
|
-
if (accountStats.length === 0) {
|
|
1667
|
-
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No accounts loaded yet..." });
|
|
1668
|
-
}
|
|
1669
|
-
const periods = [
|
|
1670
|
-
{ key: "Today", pick: (d) => d.today },
|
|
1671
|
-
{ key: "This Week", pick: (d) => d.week },
|
|
1672
|
-
{ key: "This Month", pick: (d) => d.month }
|
|
1673
|
-
];
|
|
1674
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1675
|
-
periods.map((p, i) => {
|
|
1676
|
-
const rows = accountStats.map(({ slot, s }) => ({
|
|
1724
|
+
rows.map(({ slot, lim }) => /* @__PURE__ */ jsx(
|
|
1725
|
+
AccountLimitBar,
|
|
1726
|
+
{
|
|
1677
1727
|
slot,
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
rows.map(({ slot, summary }) => /* @__PURE__ */ jsx(
|
|
1685
|
-
ComparisonRow,
|
|
1686
|
-
{
|
|
1687
|
-
slot,
|
|
1688
|
-
cost: summary.cost,
|
|
1689
|
-
tokens: summary.tokens,
|
|
1690
|
-
maxCost,
|
|
1691
|
-
maxTokens
|
|
1692
|
-
},
|
|
1693
|
-
slot.id ?? "__default__"
|
|
1694
|
-
))
|
|
1695
|
-
] }, p.key);
|
|
1696
|
-
}),
|
|
1697
|
-
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
1698
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1699
|
-
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "RATE LIMITS" }),
|
|
1700
|
-
accountStats.map(({ slot, s }) => /* @__PURE__ */ jsx(CompactLimitsRow, { slot, billing: s.billing }, slot.id ?? "__default__"))
|
|
1701
|
-
] })
|
|
1728
|
+
pct: lim.utilization,
|
|
1729
|
+
resets: showResets ? lim.resetsAt : null,
|
|
1730
|
+
showName: items.length > 1
|
|
1731
|
+
},
|
|
1732
|
+
slot.id ?? "__default__"
|
|
1733
|
+
))
|
|
1702
1734
|
] });
|
|
1703
1735
|
}
|
|
1704
|
-
function
|
|
1736
|
+
function AccountLimitBar({
|
|
1705
1737
|
slot,
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
maxTokens
|
|
1738
|
+
pct,
|
|
1739
|
+
resets,
|
|
1740
|
+
showName
|
|
1710
1741
|
}) {
|
|
1711
|
-
const
|
|
1712
|
-
const
|
|
1713
|
-
const t = bar(tokens2, maxTokens, W);
|
|
1742
|
+
const width = 28;
|
|
1743
|
+
const filled = Math.max(0, Math.min(width, Math.round(pct / 100 * width)));
|
|
1714
1744
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1715
|
-
/* @__PURE__ */
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
/* @__PURE__ */ jsx(Text, {
|
|
1720
|
-
/* @__PURE__ */ jsx(
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
/* @__PURE__ */
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
tokens(tokens2),
|
|
1729
|
-
" tk"
|
|
1730
|
-
] }) })
|
|
1731
|
-
] });
|
|
1732
|
-
}
|
|
1733
|
-
function CompactLimitsRow({ slot, billing }) {
|
|
1734
|
-
if (billing?.error) {
|
|
1735
|
-
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1736
|
-
/* @__PURE__ */ jsxs(Box, { width: 14, children: [
|
|
1737
|
-
/* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
|
|
1738
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: slot.name })
|
|
1739
|
-
] }),
|
|
1740
|
-
/* @__PURE__ */ jsx(Text, { color: "red", children: billing.error })
|
|
1741
|
-
] });
|
|
1742
|
-
}
|
|
1743
|
-
const fmtPct = (p) => p ? `${Math.round(p.utilization)}%` : "\u2014";
|
|
1744
|
-
const colorFor = (p) => {
|
|
1745
|
-
if (!p) return void 0;
|
|
1746
|
-
return p.utilization >= 80 ? "red" : p.utilization >= 50 ? "yellow" : "green";
|
|
1747
|
-
};
|
|
1748
|
-
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1749
|
-
/* @__PURE__ */ jsxs(Box, { width: 14, children: [
|
|
1750
|
-
/* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
|
|
1751
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: slot.name })
|
|
1752
|
-
] }),
|
|
1753
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "S " }),
|
|
1754
|
-
/* @__PURE__ */ jsx(Box, { width: 6, children: /* @__PURE__ */ jsx(Text, { bold: true, color: colorFor(billing?.session), children: fmtPct(billing?.session) }) }),
|
|
1755
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "W " }),
|
|
1756
|
-
/* @__PURE__ */ jsx(Box, { width: 6, children: /* @__PURE__ */ jsx(Text, { bold: true, color: colorFor(billing?.weekly), children: fmtPct(billing?.weekly) }) }),
|
|
1757
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Sonnet " }),
|
|
1758
|
-
/* @__PURE__ */ jsx(Box, { width: 6, children: /* @__PURE__ */ jsx(Text, { bold: true, color: colorFor(billing?.sonnet), children: fmtPct(billing?.sonnet) }) })
|
|
1745
|
+
/* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u25CF " }),
|
|
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: " " }) }),
|
|
1747
|
+
/* @__PURE__ */ jsx(Text, { color: slot.color, children: "\u2501".repeat(filled) }),
|
|
1748
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(width - filled) }),
|
|
1749
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1750
|
+
/* @__PURE__ */ jsx(Box, { width: 5, justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
1751
|
+
Math.round(pct),
|
|
1752
|
+
"%"
|
|
1753
|
+
] }) }),
|
|
1754
|
+
resets && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1755
|
+
" resets ",
|
|
1756
|
+
resets
|
|
1757
|
+
] })
|
|
1759
1758
|
] });
|
|
1760
1759
|
}
|
|
1761
1760
|
function PeakBadge({ peak }) {
|
|
@@ -1776,25 +1775,6 @@ function fmtMinutes(mins) {
|
|
|
1776
1775
|
const m = mins % 60;
|
|
1777
1776
|
return m === 0 ? `${h}h` : `${h}h ${m}m`;
|
|
1778
1777
|
}
|
|
1779
|
-
function LimitBar({ label, pct, resets }) {
|
|
1780
|
-
const width = 30;
|
|
1781
|
-
const filled = Math.round(pct / 100 * width);
|
|
1782
|
-
const color = pct >= 80 ? "red" : pct >= 50 ? "yellow" : "green";
|
|
1783
|
-
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1784
|
-
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: label }) }),
|
|
1785
|
-
/* @__PURE__ */ jsx(Text, { color, children: "\u2501".repeat(filled) }),
|
|
1786
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(width - filled) }),
|
|
1787
|
-
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1788
|
-
/* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
1789
|
-
Math.round(pct),
|
|
1790
|
-
"%"
|
|
1791
|
-
] }),
|
|
1792
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1793
|
-
" resets ",
|
|
1794
|
-
resets
|
|
1795
|
-
] })
|
|
1796
|
-
] });
|
|
1797
|
-
}
|
|
1798
1778
|
function TableView({ rows: allRows, cursor, expanded, maxRows, cols, onRowClick }) {
|
|
1799
1779
|
const wide = cols > 90;
|
|
1800
1780
|
const base = wide ? { label: 12, input: 10, output: 10, cc: 14, cr: 12, total: 11, cost: 13 } : { label: 8, input: 7, output: 7, cc: 7, cr: 8, total: 0, cost: 11 };
|