@vibe-cafe/vibe-usage 0.7.8 → 0.7.9

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 (3) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/api.js +13 -6
package/README.md CHANGED
@@ -64,7 +64,7 @@ npx @vibe-cafe/vibe-usage status # Show config & detected tools
64
64
  - Parses local session logs from each AI coding tool
65
65
  - Aggregates token usage into 30-minute buckets
66
66
  - Extracts session metadata from all parsers: active time (AI generation time, excluding queue/TTFT wait), total duration, message counts
67
- - Uploads buckets + sessions to your vibecafe.ai dashboard
67
+ - Uploads buckets + sessions to your vibecafe.ai dashboard (gzip-compressed when ≥ 1 KB, ~94% smaller)
68
68
  - Stateless: computes full totals from local logs each sync (idempotent, no state files)
69
69
  - For continuous syncing, use `npx @vibe-cafe/vibe-usage daemon` or the [Vibe Usage Mac app](https://github.com/vibe-cafe/vibe-usage-app)
70
70
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-cafe/vibe-usage",
3
- "version": "0.7.8",
3
+ "version": "0.7.9",
4
4
  "description": "Track your AI coding tool token usage and sync to vibecafe.ai",
5
5
  "type": "module",
6
6
  "bin": {
package/src/api.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import https from 'node:https';
2
2
  import http from 'node:http';
3
3
  import { URL } from 'node:url';
4
+ import { gzipSync } from 'node:zlib';
4
5
 
5
6
  const MAX_RETRIES = 3;
6
7
  const INITIAL_DELAY = 1000;
8
+ const GZIP_MIN_BYTES = 1024;
7
9
 
8
10
  export async function ingest(apiUrl, apiKey, buckets, opts, sessions) {
9
11
  let lastError;
@@ -30,18 +32,23 @@ function _send(apiUrl, apiKey, buckets, onProgress, sessions) {
30
32
  const url = new URL('/api/usage/ingest', apiUrl);
31
33
  const payload = { buckets };
32
34
  if (sessions && sessions.length > 0) payload.sessions = sessions;
33
- const body = Buffer.from(JSON.stringify(payload));
35
+ const raw = Buffer.from(JSON.stringify(payload));
36
+ const useGzip = raw.length >= GZIP_MIN_BYTES;
37
+ const body = useGzip ? gzipSync(raw) : raw;
34
38
  const totalBytes = body.length;
35
39
  const mod = url.protocol === 'https:' ? https : http;
36
40
 
41
+ const headers = {
42
+ 'Content-Type': 'application/json',
43
+ 'Authorization': `Bearer ${apiKey}`,
44
+ 'Content-Length': totalBytes,
45
+ };
46
+ if (useGzip) headers['Content-Encoding'] = 'gzip';
47
+
37
48
  const req = mod.request(url, {
38
49
  method: 'POST',
39
50
  timeout: 60_000,
40
- headers: {
41
- 'Content-Type': 'application/json',
42
- 'Authorization': `Bearer ${apiKey}`,
43
- 'Content-Length': totalBytes,
44
- },
51
+ headers,
45
52
  }, (res) => {
46
53
  let data = '';
47
54
  res.on('data', (chunk) => { data += chunk; });