tokmon 0.17.0 → 0.18.0
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/{chunk-ZZ7DIK3O.js → chunk-STCMWCFW.js} +1 -4
- package/dist/{chunk-TLE24LIH.js → chunk-UAPL47GL.js} +56 -11
- package/dist/cli.js +4 -9
- package/dist/{server-UPX3ANBP.js → server-VMB5ZLZC.js} +2 -2
- package/dist/web/assets/index-BMHETe8W.js +113 -0
- package/dist/web/assets/{index-B-HEpWCR.css → index-D1GoBwrC.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/{web-23FJCFDS.js → web-DYAEMCAE.js} +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-aha2Tekh.js +0 -113
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
cacheDir,
|
|
6
6
|
detectProviders,
|
|
7
7
|
resolveTimezone
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UAPL47GL.js";
|
|
9
9
|
|
|
10
10
|
// src/web/server.ts
|
|
11
11
|
import { createServer } from "http";
|
|
@@ -52,9 +52,6 @@ async function resolveAccounts(config) {
|
|
|
52
52
|
const p = PROVIDERS[a.providerId];
|
|
53
53
|
return {
|
|
54
54
|
account: a,
|
|
55
|
-
// Web-only: a provider with a usage table (e.g. Cursor's local composer history)
|
|
56
|
-
// shows in the dashboard's leaderboard/calendar/explore even when its TUI flag is
|
|
57
|
-
// false. The TUI reads PROVIDERS[id].hasUsage directly, so it is unaffected.
|
|
58
55
|
hasUsage: p.hasUsage || !!p.fetchTable,
|
|
59
56
|
hasBilling: p.hasBilling,
|
|
60
57
|
color: colorHex(a.color, PROVIDERS[a.providerId].color)
|
|
@@ -1524,11 +1524,9 @@ async function cursorApiUsage(tz, homeDir) {
|
|
|
1524
1524
|
const endMs = Date.now();
|
|
1525
1525
|
const startMs = endMs - WINDOW_DAYS * 864e5;
|
|
1526
1526
|
const events = [];
|
|
1527
|
-
let
|
|
1528
|
-
for (let page = 1; page <= MAX_PAGES && events.length < total; page++) {
|
|
1527
|
+
for (let page = 1; page <= MAX_PAGES; page++) {
|
|
1529
1528
|
const resp = await fetchPage(token, startMs, endMs, page);
|
|
1530
1529
|
if (!resp) return page === 1 ? null : finalizeTable(events, tz);
|
|
1531
|
-
total = resp.totalUsageEventsCount ?? 0;
|
|
1532
1530
|
const batch = resp.usageEventsDisplay ?? [];
|
|
1533
1531
|
events.push(...batch);
|
|
1534
1532
|
if (batch.length < PAGE_SIZE) break;
|
|
@@ -1566,10 +1564,11 @@ function finalizeTable(events, tz) {
|
|
|
1566
1564
|
const ts = Number(e.timestamp);
|
|
1567
1565
|
if (!Number.isFinite(ts) || ts <= 0) continue;
|
|
1568
1566
|
const tu = e.tokenUsage ?? {};
|
|
1569
|
-
const input =
|
|
1570
|
-
const output =
|
|
1571
|
-
const cacheRead =
|
|
1572
|
-
const
|
|
1567
|
+
const input = safeNum(tu.inputTokens);
|
|
1568
|
+
const output = safeNum(tu.outputTokens);
|
|
1569
|
+
const cacheRead = safeNum(tu.cacheReadTokens);
|
|
1570
|
+
const cents = Number(e.chargedCents);
|
|
1571
|
+
const usd = Number.isFinite(cents) && cents > 0 ? cents / 100 : 0;
|
|
1573
1572
|
if (usd <= 0 && input + output + cacheRead === 0) continue;
|
|
1574
1573
|
const model = String(e.model ?? "unknown");
|
|
1575
1574
|
put(buckets.daily, dayKey(ts, tz), model, usd, input, output, cacheRead);
|
|
@@ -1587,16 +1586,62 @@ function finalizeTable(events, tz) {
|
|
|
1587
1586
|
|
|
1588
1587
|
// src/providers/cursor/index.ts
|
|
1589
1588
|
var EMPTY = { daily: [], weekly: [], monthly: [] };
|
|
1589
|
+
var overlayDaily = (lo, hi) => {
|
|
1590
|
+
const m = new Map(lo.map((r) => [r.label, r]));
|
|
1591
|
+
for (const r of hi) m.set(r.label, r);
|
|
1592
|
+
return [...m.values()].sort((a, b) => a.label.localeCompare(b.label));
|
|
1593
|
+
};
|
|
1594
|
+
function reBucket(daily, tz, keyOf) {
|
|
1595
|
+
const out = /* @__PURE__ */ new Map();
|
|
1596
|
+
for (const day of daily) {
|
|
1597
|
+
const [y, mo, d] = day.label.split("-").map(Number);
|
|
1598
|
+
const label = keyOf(Date.UTC(y, mo - 1, d, 12), tz);
|
|
1599
|
+
let row = out.get(label);
|
|
1600
|
+
if (!row) {
|
|
1601
|
+
row = { label, models: [], input: 0, output: 0, cacheCreate: 0, cacheRead: 0, cacheSavings: 0, total: 0, cost: 0, count: 0, breakdown: [] };
|
|
1602
|
+
out.set(label, row);
|
|
1603
|
+
}
|
|
1604
|
+
row.input += day.input;
|
|
1605
|
+
row.output += day.output;
|
|
1606
|
+
row.cacheCreate += day.cacheCreate;
|
|
1607
|
+
row.cacheRead += day.cacheRead;
|
|
1608
|
+
row.cacheSavings += day.cacheSavings;
|
|
1609
|
+
row.total += day.total;
|
|
1610
|
+
row.cost += day.cost;
|
|
1611
|
+
row.count += day.count;
|
|
1612
|
+
for (const b of day.breakdown) {
|
|
1613
|
+
let md = row.breakdown.find((x) => x.name === b.name);
|
|
1614
|
+
if (!md) {
|
|
1615
|
+
md = { name: b.name, input: 0, output: 0, cacheCreate: 0, cacheRead: 0, cacheSavings: 0, cost: 0, count: 0 };
|
|
1616
|
+
row.breakdown.push(md);
|
|
1617
|
+
}
|
|
1618
|
+
md.input += b.input;
|
|
1619
|
+
md.output += b.output;
|
|
1620
|
+
md.cacheCreate += b.cacheCreate;
|
|
1621
|
+
md.cacheRead += b.cacheRead;
|
|
1622
|
+
md.cacheSavings += b.cacheSavings;
|
|
1623
|
+
md.cost += b.cost;
|
|
1624
|
+
md.count += b.count;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
return [...out.values()].map((r) => {
|
|
1628
|
+
r.breakdown.sort((a, b) => b.cost - a.cost);
|
|
1629
|
+
r.models = r.breakdown.map((b) => b.name);
|
|
1630
|
+
return r;
|
|
1631
|
+
}).sort((a, b) => a.label.localeCompare(b.label));
|
|
1632
|
+
}
|
|
1590
1633
|
async function cursorTable(tz, homeDir) {
|
|
1591
|
-
|
|
1634
|
+
const [api, local] = await Promise.all([cursorApiUsage(tz, homeDir), cursorUsageTable(tz, homeDir)]);
|
|
1635
|
+
if (!api && !local) return EMPTY;
|
|
1636
|
+
const daily = overlayDaily(local?.daily ?? [], api?.daily ?? []);
|
|
1637
|
+
if (daily.length === 0) return EMPTY;
|
|
1638
|
+
return { daily, weekly: reBucket(daily, tz, weekKey), monthly: reBucket(daily, tz, monthKey) };
|
|
1592
1639
|
}
|
|
1593
1640
|
var cursorProvider = {
|
|
1594
1641
|
id: "cursor",
|
|
1595
1642
|
name: "Cursor",
|
|
1596
1643
|
color: "magenta",
|
|
1597
|
-
// hasUsage
|
|
1598
|
-
// The web surfaces the usage table via fetchTable (resolveAccounts promotes any
|
|
1599
|
-
// provider with a fetchTable to hasUsage for the dashboard only).
|
|
1644
|
+
// hasUsage: false — TUI keys its dedicated Cursor spend-table off this flag directly.
|
|
1600
1645
|
hasUsage: false,
|
|
1601
1646
|
hasBilling: true,
|
|
1602
1647
|
detect: (homeDir) => detectCursor(homeDir),
|
package/dist/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
systemTimezone,
|
|
24
24
|
time,
|
|
25
25
|
tokens
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-UAPL47GL.js";
|
|
27
27
|
|
|
28
28
|
// src/cli.tsx
|
|
29
29
|
import { EventEmitter } from "events";
|
|
@@ -1606,11 +1606,7 @@ function App({ interval: cliInterval, initialConfig }) {
|
|
|
1606
1606
|
const hasStrip = slots.length > 1;
|
|
1607
1607
|
const stripChipW = (s) => 2 + 2 + truncateName(s.name, 16).length + 2;
|
|
1608
1608
|
const stripChars = slots.reduce((sum, s) => sum + stripChipW(s), 0);
|
|
1609
|
-
const stripLines = hasStrip ? Math.max(1, Math.ceil(stripChars / Math.max(
|
|
1610
|
-
1,
|
|
1611
|
-
cols - 4 - 7
|
|
1612
|
-
/*"focus "*/
|
|
1613
|
-
))) : 0;
|
|
1609
|
+
const stripLines = hasStrip ? Math.max(1, Math.ceil(stripChars / Math.max(1, cols - 4 - 7))) : 0;
|
|
1614
1610
|
const headerRows = cols < 70 ? 2 : 1;
|
|
1615
1611
|
const CHROME = 2 + headerRows + 3 + (hasStrip ? 1 + stripLines : 0) + 2 + 2;
|
|
1616
1612
|
const gridBudget = Math.max(1, rows - CHROME);
|
|
@@ -1856,7 +1852,6 @@ function App({ interval: cliInterval, initialConfig }) {
|
|
|
1856
1852
|
function toggleProvider(pid) {
|
|
1857
1853
|
updateConfig((c) => ({
|
|
1858
1854
|
...c,
|
|
1859
|
-
// Toggling in settings is also an explicit decision → mark it known.
|
|
1860
1855
|
knownProviders: c.knownProviders.includes(pid) ? c.knownProviders : [...c.knownProviders, pid],
|
|
1861
1856
|
disabledProviders: c.disabledProviders.includes(pid) ? c.disabledProviders.filter((p) => p !== pid) : [...c.disabledProviders, pid]
|
|
1862
1857
|
}));
|
|
@@ -1996,7 +1991,7 @@ function App({ interval: cliInterval, initialConfig }) {
|
|
|
1996
1991
|
setWebStatus("off");
|
|
1997
1992
|
} else {
|
|
1998
1993
|
setWebStatus("starting");
|
|
1999
|
-
const { startWebServer } = await import("./server-
|
|
1994
|
+
const { startWebServer } = await import("./server-VMB5ZLZC.js");
|
|
2000
1995
|
const ctrl = await startWebServer({ config: cfg, log: false });
|
|
2001
1996
|
webRef.current = ctrl;
|
|
2002
1997
|
setWebUrl(ctrl.url);
|
|
@@ -2674,7 +2669,7 @@ process.emitWarning = ((warning, ...rest) => {
|
|
|
2674
2669
|
var args = process.argv.slice(2);
|
|
2675
2670
|
var subcommand = args[0]?.toLowerCase();
|
|
2676
2671
|
if (subcommand === "serve" || subcommand === "web") {
|
|
2677
|
-
const { startWeb } = await import("./web-
|
|
2672
|
+
const { startWeb } = await import("./web-DYAEMCAE.js");
|
|
2678
2673
|
await startWeb(args.slice(1));
|
|
2679
2674
|
process.exit(typeof process.exitCode === "number" ? process.exitCode : 0);
|
|
2680
2675
|
}
|