@vibe-cafe/vibe-usage 0.4.0 → 0.4.2
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/package.json +9 -1
- package/src/api.js +40 -0
- package/src/sync.js +14 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibe-cafe/vibe-usage",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Track your AI coding tool token usage and sync to vibecafe.ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,5 +25,13 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"ccusage": "18.0.5"
|
|
27
27
|
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/vibe-cafe/vibe-usage.git"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/vibe-cafe/vibe-usage#readme",
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/vibe-cafe/vibe-usage/issues"
|
|
35
|
+
},
|
|
28
36
|
"license": "MIT"
|
|
29
37
|
}
|
package/src/api.js
CHANGED
|
@@ -151,3 +151,43 @@ export function deleteAllData(apiUrl, apiKey, opts) {
|
|
|
151
151
|
req.end();
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* GET user settings from the vibecafe API.
|
|
157
|
+
* Returns null on any failure (network, auth, timeout) — caller should fail-safe.
|
|
158
|
+
* @param {string} apiUrl
|
|
159
|
+
* @param {string} apiKey
|
|
160
|
+
* @returns {Promise<{uploadProject: boolean} | null>}
|
|
161
|
+
*/
|
|
162
|
+
export function fetchSettings(apiUrl, apiKey) {
|
|
163
|
+
return new Promise((resolve) => {
|
|
164
|
+
const url = new URL('/api/usage/settings', apiUrl);
|
|
165
|
+
const mod = url.protocol === 'https:' ? https : http;
|
|
166
|
+
|
|
167
|
+
const req = mod.request(url, {
|
|
168
|
+
method: 'GET',
|
|
169
|
+
timeout: 10_000,
|
|
170
|
+
headers: {
|
|
171
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
172
|
+
},
|
|
173
|
+
}, (res) => {
|
|
174
|
+
let data = '';
|
|
175
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
176
|
+
res.on('end', () => {
|
|
177
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
178
|
+
resolve(null);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
resolve(JSON.parse(data));
|
|
183
|
+
} catch {
|
|
184
|
+
resolve(null);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
req.on('error', () => resolve(null));
|
|
190
|
+
req.on('timeout', () => { req.destroy(); resolve(null); });
|
|
191
|
+
req.end();
|
|
192
|
+
});
|
|
193
|
+
}
|
package/src/sync.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { hostname as osHostname } from 'node:os';
|
|
2
2
|
import { loadConfig, saveConfig } from './config.js';
|
|
3
|
-
import { ingest } from './api.js';
|
|
3
|
+
import { ingest, fetchSettings } from './api.js';
|
|
4
4
|
import { parsers, postSyncHooks } from './parsers/index.js';
|
|
5
5
|
|
|
6
6
|
const BATCH_SIZE = 100;
|
|
@@ -49,7 +49,20 @@ export async function runSync({ throws = false, quiet = false } = {}) {
|
|
|
49
49
|
b.hostname = host;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
// Privacy: check if user allows project name upload
|
|
52
53
|
const apiUrl = config.apiUrl || 'https://vibecafe.ai';
|
|
54
|
+
const settings = await fetchSettings(apiUrl, config.apiKey);
|
|
55
|
+
const uploadProject = settings?.uploadProject === true;
|
|
56
|
+
|
|
57
|
+
if (uploadProject) {
|
|
58
|
+
console.log('📂 项目名: 上传 (可在 vibecafe.ai/usage 设置中关闭)');
|
|
59
|
+
} else {
|
|
60
|
+
console.log('🔒 项目名: 已隐藏');
|
|
61
|
+
for (const b of allBuckets) {
|
|
62
|
+
b.project = 'unknown';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
53
66
|
let totalIngested = 0;
|
|
54
67
|
const totalBatches = Math.ceil(allBuckets.length / BATCH_SIZE);
|
|
55
68
|
|