@vibe-cafe/vibe-usage 0.1.12 → 0.2.1
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 +1 -1
- package/src/config.js +2 -1
- package/src/hooks.js +5 -3
- package/src/index.js +68 -7
- package/src/sync.js +21 -0
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -3,7 +3,8 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
|
|
5
5
|
const CONFIG_DIR = join(homedir(), '.vibe-usage');
|
|
6
|
-
const
|
|
6
|
+
const isDev = process.env.VIBE_USAGE_DEV === '1';
|
|
7
|
+
const CONFIG_FILE = join(CONFIG_DIR, isDev ? 'config.dev.json' : 'config.json');
|
|
7
8
|
|
|
8
9
|
export function getConfigPath() {
|
|
9
10
|
return CONFIG_FILE;
|
package/src/hooks.js
CHANGED
|
@@ -86,6 +86,8 @@ export function injectCodex() {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
if (content.includes('vibe-usage')) {
|
|
89
|
+
// Fix broken [notify] → [[notify]] from previous versions
|
|
90
|
+
content = content.replace(/^\[notify\]$/gm, '[[notify]]');
|
|
89
91
|
// Update existing command to use latest
|
|
90
92
|
content = content.replace(
|
|
91
93
|
/npx @vibe-cafe\/vibe-usage(?:@[\d.]+)? sync[^"']*/g,
|
|
@@ -95,12 +97,12 @@ export function injectCodex() {
|
|
|
95
97
|
return { injected: false, reason: 'already installed (updated)' };
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
const notifySection = `\n[notify]\ncommand = "${SYNC_CMD}"\n`;
|
|
99
|
-
const notifyIdx = content.indexOf('[notify]');
|
|
100
|
+
const notifySection = `\n[[notify]]\ncommand = "${SYNC_CMD}"\n`;
|
|
101
|
+
const notifyIdx = content.indexOf('[[notify]]');
|
|
100
102
|
if (notifyIdx !== -1) {
|
|
101
103
|
const nextSection = content.indexOf('\n[', notifyIdx + 1);
|
|
102
104
|
const sectionEnd = nextSection === -1 ? content.length : nextSection;
|
|
103
|
-
content = content.slice(0, notifyIdx) + `[notify]\ncommand = "${SYNC_CMD}"` + content.slice(sectionEnd);
|
|
105
|
+
content = content.slice(0, notifyIdx) + `[[notify]]\ncommand = "${SYNC_CMD}"` + content.slice(sectionEnd);
|
|
104
106
|
} else {
|
|
105
107
|
content += notifySection;
|
|
106
108
|
}
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadConfig, getConfigPath } from './config.js';
|
|
1
|
+
import { loadConfig, saveConfig, getConfigPath } from './config.js';
|
|
2
2
|
import { detectInstalledTools, TOOLS } from './hooks.js';
|
|
3
3
|
import { existsSync } from 'node:fs';
|
|
4
4
|
|
|
@@ -36,6 +36,60 @@ async function showStatus() {
|
|
|
36
36
|
console.log();
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const VALID_CONFIG_KEYS = ['apiKey', 'apiUrl', 'lastSync'];
|
|
40
|
+
|
|
41
|
+
function handleConfig(args) {
|
|
42
|
+
const sub = args[0];
|
|
43
|
+
|
|
44
|
+
switch (sub) {
|
|
45
|
+
case 'get': {
|
|
46
|
+
const key = args[1];
|
|
47
|
+
if (!key) {
|
|
48
|
+
console.error('Usage: vibe-usage config get <key>');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const config = loadConfig();
|
|
52
|
+
if (!config || !(key in config)) {
|
|
53
|
+
// Output nothing — caller checks exit code or empty output
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
// Output raw value (no formatting) for machine parsing
|
|
57
|
+
console.log(config[key] ?? '');
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case 'set': {
|
|
61
|
+
const key = args[1];
|
|
62
|
+
const value = args[2];
|
|
63
|
+
if (!key || value === undefined) {
|
|
64
|
+
console.error('Usage: vibe-usage config set <key> <value>');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
if (!VALID_CONFIG_KEYS.includes(key)) {
|
|
68
|
+
console.error(`Unknown config key: ${key}`);
|
|
69
|
+
console.error(`Valid keys: ${VALID_CONFIG_KEYS.join(', ')}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const config = loadConfig() || {};
|
|
73
|
+
config[key] = value;
|
|
74
|
+
saveConfig(config);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case 'show': {
|
|
78
|
+
const config = loadConfig();
|
|
79
|
+
if (!config) {
|
|
80
|
+
console.log('{}');
|
|
81
|
+
} else {
|
|
82
|
+
console.log(JSON.stringify(config, null, 2));
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
default:
|
|
87
|
+
console.error(`Unknown config subcommand: ${sub || '(none)'}`);
|
|
88
|
+
console.error('Usage: vibe-usage config <get|set|show>');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
39
93
|
export async function run(args) {
|
|
40
94
|
const command = args[0];
|
|
41
95
|
|
|
@@ -50,6 +104,10 @@ export async function run(args) {
|
|
|
50
104
|
await runSync();
|
|
51
105
|
break;
|
|
52
106
|
}
|
|
107
|
+
case 'config': {
|
|
108
|
+
handleConfig(args.slice(1));
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
53
111
|
case 'status': {
|
|
54
112
|
await showStatus();
|
|
55
113
|
break;
|
|
@@ -58,14 +116,17 @@ export async function run(args) {
|
|
|
58
116
|
case '--help':
|
|
59
117
|
case '-h': {
|
|
60
118
|
console.log(`
|
|
61
|
-
vibe-usage - Vibe Usage Tracker by
|
|
119
|
+
vibe-usage - Vibe Usage Tracker by VibeCafé
|
|
62
120
|
|
|
63
121
|
Usage:
|
|
64
|
-
npx vibe-usage
|
|
65
|
-
npx vibe-usage init
|
|
66
|
-
npx vibe-usage sync
|
|
67
|
-
npx vibe-usage status
|
|
68
|
-
npx vibe-usage
|
|
122
|
+
npx vibe-usage Init (first run) or sync
|
|
123
|
+
npx vibe-usage init Set up API key and hooks
|
|
124
|
+
npx vibe-usage sync Manually sync usage data
|
|
125
|
+
npx vibe-usage status Show config and detected tools
|
|
126
|
+
npx vibe-usage config show Show full config as JSON
|
|
127
|
+
npx vibe-usage config get <key> Get a config value
|
|
128
|
+
npx vibe-usage config set <key> <value> Set a config value
|
|
129
|
+
npx vibe-usage help Show this help
|
|
69
130
|
`);
|
|
70
131
|
break;
|
|
71
132
|
}
|
package/src/sync.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { hostname as osHostname } from 'node:os';
|
|
2
|
+
import { existsSync, readFileSync, unlinkSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
2
5
|
import { loadConfig, saveConfig } from './config.js';
|
|
3
6
|
import { ingest } from './api.js';
|
|
4
7
|
import { parsers } from './parsers/index.js';
|
|
@@ -90,6 +93,24 @@ export async function runSync() {
|
|
|
90
93
|
* Runs silently — meant as a self-healing side effect of sync.
|
|
91
94
|
*/
|
|
92
95
|
function ensureHooks() {
|
|
96
|
+
// Skip hook injection if Vibe Usage Mac app is running
|
|
97
|
+
const markerPath = join(homedir(), '.vibe-usage', 'mac-app-active');
|
|
98
|
+
if (existsSync(markerPath)) {
|
|
99
|
+
try {
|
|
100
|
+
const marker = JSON.parse(readFileSync(markerPath, 'utf-8'));
|
|
101
|
+
if (marker.pid) {
|
|
102
|
+
try {
|
|
103
|
+
process.kill(marker.pid, 0);
|
|
104
|
+
return;
|
|
105
|
+
} catch {
|
|
106
|
+
try { unlinkSync(markerPath); } catch { /* ignore */ }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} catch {
|
|
110
|
+
// Malformed marker file — ignore
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
93
114
|
for (const tool of TOOLS) {
|
|
94
115
|
if (!tool.inject) continue;
|
|
95
116
|
try {
|