vibestats 1.0.4 → 1.0.6

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 +70 -0
  2. package/package.json +6 -7
package/dist/index.js CHANGED
@@ -1436,6 +1436,52 @@ function getModelAbbrevFromDisplayName(displayName) {
1436
1436
  };
1437
1437
  return map[displayName] || displayName.slice(0, 5).toLowerCase();
1438
1438
  }
1439
+ function encodeUsageToUrl(stats, baseUrl = "https://vibestats.wolfai.dev") {
1440
+ const params = new URLSearchParams();
1441
+ const aggMap = { daily: "d", monthly: "m", model: "mo", total: "t" };
1442
+ params.set("agg", aggMap[stats.aggregation] || "d");
1443
+ if (stats.source !== "claude") {
1444
+ params.set("src", stats.source);
1445
+ }
1446
+ const formatDateCompact = (d) => d.replace(/-/g, "");
1447
+ const limitedRows = stats.rows.slice(-31);
1448
+ const startDate = limitedRows[0]?.key || stats.dateRange.start;
1449
+ const endDate = limitedRows[limitedRows.length - 1]?.key || stats.dateRange.end;
1450
+ params.set("dr", `${formatDateCompact(startDate)}-${formatDateCompact(endDate)}`);
1451
+ const rows = limitedRows.map((row) => {
1452
+ let key = row.key;
1453
+ if (stats.aggregation === "daily" && row.key.length === 10) {
1454
+ key = row.key.slice(5).replace("-", "");
1455
+ }
1456
+ return [
1457
+ key,
1458
+ formatCompactNumber(row.inputTokens),
1459
+ formatCompactNumber(row.outputTokens),
1460
+ formatCompactNumber(row.cacheWriteTokens),
1461
+ formatCompactNumber(row.cacheReadTokens),
1462
+ formatCompactNumber(row.totalTokens),
1463
+ row.cost.toFixed(2)
1464
+ ].join(":");
1465
+ });
1466
+ params.set("rows", rows.join("|"));
1467
+ const t = stats.totals;
1468
+ params.set("tot", [
1469
+ formatCompactNumber(t.inputTokens),
1470
+ formatCompactNumber(t.outputTokens),
1471
+ formatCompactNumber(t.cacheWriteTokens),
1472
+ formatCompactNumber(t.cacheReadTokens),
1473
+ formatCompactNumber(t.totalTokens),
1474
+ t.cost.toFixed(2)
1475
+ ].join(":"));
1476
+ if (stats.modelBreakdown.length > 0) {
1477
+ const mb = stats.modelBreakdown.slice(0, 5).map((m) => {
1478
+ const abbr = getModelAbbrevFromDisplayName(m.model);
1479
+ return `${abbr}:${m.percentage}:${m.cost.toFixed(2)}`;
1480
+ });
1481
+ params.set("mb", mb.join(","));
1482
+ }
1483
+ return `${baseUrl}?${params.toString()}`;
1484
+ }
1439
1485
 
1440
1486
  // src/display.ts
1441
1487
  var colors2 = {
@@ -1704,6 +1750,13 @@ var main = defineCommand({
1704
1750
  description: "Use compact table format (hide cache columns)",
1705
1751
  default: false
1706
1752
  },
1753
+ // Share option for usage mode
1754
+ share: {
1755
+ type: "boolean",
1756
+ alias: "s",
1757
+ description: "Generate a shareable URL (usage mode)",
1758
+ default: false
1759
+ },
1707
1760
  // Wrapped-specific options
1708
1761
  url: {
1709
1762
  type: "string",
@@ -1769,6 +1822,19 @@ async function runUsage(args, config) {
1769
1822
  }
1770
1823
  process.exit(1);
1771
1824
  }
1825
+ const baseUrl = args.url || config.baseUrl || "https://vibestats.wolfai.dev";
1826
+ let shareUrl = null;
1827
+ if (args.share) {
1828
+ const fullUrl = encodeUsageToUrl(stats, baseUrl);
1829
+ if (!args["no-short"]) {
1830
+ shareUrl = await createShortlink(fullUrl, baseUrl);
1831
+ }
1832
+ shareUrl = shareUrl || fullUrl;
1833
+ }
1834
+ if (args.quiet && args.share && shareUrl) {
1835
+ console.log(shareUrl);
1836
+ return;
1837
+ }
1772
1838
  if (args.json) {
1773
1839
  console.log(JSON.stringify(stats, null, 2));
1774
1840
  } else if (args.quiet) {
@@ -1787,6 +1853,10 @@ async function runUsage(args, config) {
1787
1853
  showColors: config.theme?.enabled !== false
1788
1854
  });
1789
1855
  }
1856
+ if (args.share && shareUrl && !args.json) {
1857
+ console.log();
1858
+ console.log(`\u{1F517} ${shareUrl}`);
1859
+ }
1790
1860
  }
1791
1861
  async function runWrapped(args, config) {
1792
1862
  const options = resolveOptions(args, config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibestats",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
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",
@@ -18,11 +18,6 @@
18
18
  "files": [
19
19
  "dist"
20
20
  ],
21
- "scripts": {
22
- "dev": "tsx src/index.ts",
23
- "build": "tsup src/index.ts --format esm --dts --clean --shims",
24
- "prepublishOnly": "pnpm build"
25
- },
26
21
  "keywords": [
27
22
  "claude",
28
23
  "claude-code",
@@ -50,5 +45,9 @@
50
45
  },
51
46
  "engines": {
52
47
  "node": ">=18.0.0"
48
+ },
49
+ "scripts": {
50
+ "dev": "tsx src/index.ts",
51
+ "build": "tsup src/index.ts --format esm --dts --clean --shims"
53
52
  }
54
- }
53
+ }