@vibe-cafe/vibe-usage 0.7.5 → 0.7.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.
- package/README.md +12 -2
- package/package.json +1 -1
- package/src/index.js +21 -5
- package/src/init.js +43 -9
package/README.md
CHANGED
|
@@ -4,19 +4,29 @@ Track your AI coding tool token usage and sync to [vibecafe.ai](https://vibecafe
|
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
7
|
+
Get your API key at [vibecafe.ai/usage](https://vibecafe.ai/usage), then copy the one-liner shown there:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @vibe-cafe/vibe-usage --key vbu_xxxxxxxxxxxx
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or run without a key and paste it interactively:
|
|
14
|
+
|
|
7
15
|
```bash
|
|
8
16
|
npx @vibe-cafe/vibe-usage
|
|
9
17
|
```
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
1.
|
|
19
|
+
Either path will:
|
|
20
|
+
1. Save your API key to `~/.vibe-usage/config.json`
|
|
13
21
|
2. Detect installed AI coding tools
|
|
14
22
|
3. Run an initial sync of your usage data
|
|
23
|
+
4. Prompt you to enable the background daemon for continuous syncing (recommended)
|
|
15
24
|
|
|
16
25
|
## Commands
|
|
17
26
|
|
|
18
27
|
```bash
|
|
19
28
|
npx @vibe-cafe/vibe-usage # Init (first run) or sync (subsequent runs)
|
|
29
|
+
npx @vibe-cafe/vibe-usage --key <vbu_...> # One-shot init with a pre-copied key
|
|
20
30
|
npx @vibe-cafe/vibe-usage init # Re-run setup
|
|
21
31
|
npx @vibe-cafe/vibe-usage sync # Manual sync
|
|
22
32
|
npx @vibe-cafe/vibe-usage daemon # Continuous sync (every 30m, foreground)
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -88,13 +88,26 @@ function handleConfig(args) {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
function extractOption(args, name) {
|
|
92
|
+
const flag = `--${name}`;
|
|
93
|
+
const idx = args.findIndex(a => a === flag);
|
|
94
|
+
if (idx === -1) return { args, value: undefined };
|
|
95
|
+
const value = args[idx + 1];
|
|
96
|
+
if (value === undefined || value.startsWith('--')) {
|
|
97
|
+
console.error(`Option ${flag} requires a value.`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
return { args: [...args.slice(0, idx), ...args.slice(idx + 2)], value };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function run(rawArgs) {
|
|
104
|
+
const { args, value: apiKey } = extractOption(rawArgs, 'key');
|
|
92
105
|
const command = args[0];
|
|
93
106
|
|
|
94
107
|
switch (command) {
|
|
95
108
|
case 'init': {
|
|
96
109
|
const { runInit } = await import('./init.js');
|
|
97
|
-
await runInit();
|
|
110
|
+
await runInit({ apiKey });
|
|
98
111
|
break;
|
|
99
112
|
}
|
|
100
113
|
case 'sync': {
|
|
@@ -140,7 +153,9 @@ export async function run(args) {
|
|
|
140
153
|
|
|
141
154
|
Usage:
|
|
142
155
|
npx @vibe-cafe/vibe-usage Init (first run) or sync
|
|
143
|
-
npx @vibe-cafe/vibe-usage init
|
|
156
|
+
npx @vibe-cafe/vibe-usage --key <vbu_...> One-shot init with a pre-copied key
|
|
157
|
+
npx @vibe-cafe/vibe-usage init Set up API key (interactive)
|
|
158
|
+
npx @vibe-cafe/vibe-usage init --key <vbu_...> Init with key, skip paste prompt
|
|
144
159
|
npx @vibe-cafe/vibe-usage sync Manually sync usage data
|
|
145
160
|
npx @vibe-cafe/vibe-usage daemon Continuous sync (every 30m, foreground)
|
|
146
161
|
npx @vibe-cafe/vibe-usage daemon install Install background service (systemd/launchd)
|
|
@@ -162,9 +177,10 @@ export async function run(args) {
|
|
|
162
177
|
}
|
|
163
178
|
default: {
|
|
164
179
|
const config = loadConfig();
|
|
165
|
-
if (!config?.apiKey) {
|
|
180
|
+
if (!config?.apiKey || apiKey) {
|
|
181
|
+
// First run OR user passed --key for a one-shot setup
|
|
166
182
|
const { runInit } = await import('./init.js');
|
|
167
|
-
await runInit();
|
|
183
|
+
await runInit({ apiKey });
|
|
168
184
|
} else {
|
|
169
185
|
const { runSync } = await import('./sync.js');
|
|
170
186
|
await runSync();
|
package/src/init.js
CHANGED
|
@@ -23,11 +23,22 @@ function openBrowser(url) {
|
|
|
23
23
|
execFile(cmd, [url], () => {});
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
function isDaemonPlatform() {
|
|
27
|
+
return process.platform === 'linux' || process.platform === 'darwin';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function runInit(options = {}) {
|
|
31
|
+
const { apiKey: providedKey } = options;
|
|
32
|
+
|
|
27
33
|
console.log('\n vibe-usage - Vibe Usage Tracker by VibeCaf\u00e9\n');
|
|
28
34
|
|
|
29
35
|
const existing = loadConfig();
|
|
30
36
|
if (existing?.apiKey) {
|
|
37
|
+
if (providedKey && existing.apiKey === providedKey) {
|
|
38
|
+
console.log('Already configured with this key. Running sync...\n');
|
|
39
|
+
await runSync();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
31
42
|
const answer = await prompt('Config already exists. Overwrite? (y/N) ');
|
|
32
43
|
if (answer.toLowerCase() !== 'y') {
|
|
33
44
|
console.log('Cancelled.');
|
|
@@ -36,14 +47,24 @@ export async function runInit() {
|
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
const apiUrl = process.env.VIBE_USAGE_API_URL || 'https://vibecafe.ai';
|
|
39
|
-
console.log(`Get your API key at: ${apiUrl}/usage/setup\n`);
|
|
40
|
-
openBrowser(`${apiUrl}/usage/setup`);
|
|
41
50
|
|
|
42
51
|
let apiKey;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
if (providedKey) {
|
|
53
|
+
if (!providedKey.startsWith('vbu_')) {
|
|
54
|
+
console.error('Invalid API key — must start with "vbu_".');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
apiKey = providedKey;
|
|
58
|
+
console.log(`Using API key ${apiKey.slice(0, 8)}...`);
|
|
59
|
+
} else {
|
|
60
|
+
console.log(`Get your API key at: ${apiUrl}/usage\n`);
|
|
61
|
+
openBrowser(`${apiUrl}/usage`);
|
|
62
|
+
|
|
63
|
+
while (true) {
|
|
64
|
+
apiKey = await prompt('Paste your API key: ');
|
|
65
|
+
if (apiKey.startsWith('vbu_')) break;
|
|
66
|
+
console.log('Invalid key — must start with "vbu_". Try again.');
|
|
67
|
+
}
|
|
47
68
|
}
|
|
48
69
|
|
|
49
70
|
console.log(`\nVerifying key ${apiKey.slice(0, 8)}...`);
|
|
@@ -77,7 +98,20 @@ export async function runInit() {
|
|
|
77
98
|
|
|
78
99
|
console.log(`\nSetup complete! View your dashboard at: ${apiUrl}/usage`);
|
|
79
100
|
|
|
80
|
-
if (
|
|
81
|
-
|
|
101
|
+
if (isDaemonPlatform()) {
|
|
102
|
+
if (process.stdin.isTTY) {
|
|
103
|
+
console.log('');
|
|
104
|
+
const answer = await prompt('开启后台自动同步?(持续上报用量数据,推荐) [Y/n] ');
|
|
105
|
+
const normalized = answer.toLowerCase();
|
|
106
|
+
if (normalized === '' || normalized === 'y' || normalized === 'yes') {
|
|
107
|
+
const { manageDaemon } = await import('./daemon-service.js');
|
|
108
|
+
await manageDaemon('install');
|
|
109
|
+
} else {
|
|
110
|
+
console.log('\n可随时运行 `npx @vibe-cafe/vibe-usage daemon install` 开启后台同步。');
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
// Non-interactive shell (CI, pipe) — don't block on prompt
|
|
114
|
+
console.log('\nTip: Run `npx @vibe-cafe/vibe-usage daemon install` to sync automatically in the background.');
|
|
115
|
+
}
|
|
82
116
|
}
|
|
83
117
|
}
|