vibestats 1.0.7 → 1.0.8

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 (2) hide show
  1. package/dist/index.js +35 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1447,21 +1447,49 @@ function getModelAbbrevFromDisplayName(displayName) {
1447
1447
  };
1448
1448
  return map[displayName] || displayName.slice(0, 5).toLowerCase();
1449
1449
  }
1450
+ function aggregateRowsToMonthly(rows) {
1451
+ const monthMap = /* @__PURE__ */ new Map();
1452
+ for (const row of rows) {
1453
+ const month = row.key.slice(0, 7);
1454
+ const existing = monthMap.get(month);
1455
+ if (existing) {
1456
+ existing.inputTokens += row.inputTokens;
1457
+ existing.outputTokens += row.outputTokens;
1458
+ existing.cacheWriteTokens += row.cacheWriteTokens;
1459
+ existing.cacheReadTokens += row.cacheReadTokens;
1460
+ existing.totalTokens += row.totalTokens;
1461
+ existing.cost += row.cost;
1462
+ } else {
1463
+ monthMap.set(month, { ...row, key: month });
1464
+ }
1465
+ }
1466
+ return Array.from(monthMap.values()).sort((a, b) => a.key.localeCompare(b.key));
1467
+ }
1450
1468
  function encodeUsageToUrl(stats, baseUrl = "https://vibestats.wolfai.dev") {
1451
1469
  const params = new URLSearchParams();
1452
- const aggMap = { daily: "d", monthly: "m", model: "mo", total: "t" };
1453
- params.set("agg", aggMap[stats.aggregation] || "d");
1454
1470
  if (stats.source !== "claude") {
1455
1471
  params.set("src", stats.source);
1456
1472
  }
1457
1473
  const formatDateCompact = (d) => d.replace(/-/g, "");
1458
- const limitedRows = stats.rows.slice(-31);
1459
- const startDate = limitedRows[0]?.key || stats.dateRange.start;
1460
- const endDate = limitedRows[limitedRows.length - 1]?.key || stats.dateRange.end;
1474
+ const startMs = new Date(stats.dateRange.start).getTime();
1475
+ const endMs = new Date(stats.dateRange.end).getTime();
1476
+ const daySpan = Math.ceil((endMs - startMs) / (1e3 * 60 * 60 * 24));
1477
+ const useMonthly = stats.aggregation === "daily" && daySpan > 31;
1478
+ const aggMap = { daily: "d", monthly: "m", model: "mo", total: "t" };
1479
+ const effectiveAgg = useMonthly ? "monthly" : stats.aggregation;
1480
+ params.set("agg", aggMap[effectiveAgg] || "d");
1481
+ let rowsToEncode;
1482
+ if (useMonthly) {
1483
+ rowsToEncode = aggregateRowsToMonthly(stats.rows);
1484
+ } else {
1485
+ rowsToEncode = stats.rows.slice(-31);
1486
+ }
1487
+ const startDate = useMonthly ? stats.dateRange.start : rowsToEncode[0]?.key || stats.dateRange.start;
1488
+ const endDate = useMonthly ? stats.dateRange.end : rowsToEncode[rowsToEncode.length - 1]?.key || stats.dateRange.end;
1461
1489
  params.set("dr", `${formatDateCompact(startDate)}-${formatDateCompact(endDate)}`);
1462
- const rows = limitedRows.map((row) => {
1490
+ const rows = rowsToEncode.map((row) => {
1463
1491
  let key = row.key;
1464
- if (stats.aggregation === "daily" && row.key.length === 10) {
1492
+ if (effectiveAgg === "daily" && row.key.length === 10) {
1465
1493
  key = row.key.slice(5).replace("-", "");
1466
1494
  }
1467
1495
  return [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibestats",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "AI coding stats - usage tracking and annual wrapped for Claude Code & Codex",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",