@vibe-cafe/vibe-usage 0.10.5 → 0.10.8

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/src/sync.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  } from './state.js';
7
7
  import { ingest, fetchSettings } from './api.js';
8
8
  import { createSyncClient, forBatch } from './client-meta.js';
9
- import { parsers } from './parsers/index.js';
9
+ import { aggregateToBuckets, parsers } from './parsers/index.js';
10
10
  import { success, failure, arrow, link, dim } from './output.js';
11
11
 
12
12
  const BATCH_SIZE = 100;
@@ -31,6 +31,16 @@ export function resolveCodexExtraHome(configured, temporary) {
31
31
  return temporary ?? configured;
32
32
  }
33
33
 
34
+ // Hiding project names can collapse multiple parser buckets onto one server
35
+ // identity. Merge those buckets before hashing/uploading so no project's usage
36
+ // wins by iteration order.
37
+ export function reaggregateHiddenProjectBuckets(buckets) {
38
+ return aggregateToBuckets(buckets.map(bucket => ({
39
+ ...bucket,
40
+ timestamp: new Date(bucket.bucketStart),
41
+ })));
42
+ }
43
+
34
44
  export async function runSync({
35
45
  throws = false,
36
46
  quiet = false,
@@ -70,7 +80,7 @@ export async function runSync({
70
80
  process.exit(1);
71
81
  }
72
82
 
73
- const allBuckets = [];
83
+ let allBuckets = [];
74
84
  const allSessions = [];
75
85
  const parserResults = [];
76
86
  const parserProgress = [];
@@ -166,6 +176,7 @@ export async function runSync({
166
176
  if (!uploadProject) {
167
177
  for (const b of allBuckets) b.project = 'unknown';
168
178
  for (const s of allSessions) s.project = 'unknown';
179
+ allBuckets = reaggregateHiddenProjectBuckets(allBuckets);
169
180
  }
170
181
 
171
182
  // Incremental upload diff: parsers above emit a complete view of live local
package/src/tools.js CHANGED
@@ -1,8 +1,29 @@
1
1
  import { existsSync, readdirSync, statSync } from 'node:fs';
2
- import { isAbsolute, join, resolve } from 'node:path';
2
+ import { isAbsolute, join, posix, resolve, win32 } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
4
  import { findClaudeCodeDataDirs } from './claude-roots.js';
5
5
  import { codexSessionDirs, resolveCodexHomes } from './codex-roots.js';
6
+ import { findClineDataDirs } from './cline-roots.js';
7
+ import { findCraftDataDirs } from './craft-roots.js';
8
+ import { findOmpDataDirs, findPiDataDirs } from './pi-roots.js';
9
+ import { findWorkbuddyDataDirs } from './workbuddy-roots.js';
10
+
11
+ export function getAlmaDbPath(env = process.env, platform = process.platform, home = homedir()) {
12
+ const pathImpl = platform === 'win32' ? win32 : posix;
13
+ const override = env.VIBE_USAGE_ALMA_DB?.trim();
14
+ if (override) {
15
+ return platform === process.platform ? resolve(override) : pathImpl.resolve(override);
16
+ }
17
+ if (platform === 'darwin') {
18
+ return pathImpl.join(home, 'Library', 'Application Support', 'alma', 'chat_threads.db');
19
+ }
20
+ if (platform === 'win32') {
21
+ const appData = env.APPDATA?.trim() || pathImpl.join(home, 'AppData', 'Roaming');
22
+ return pathImpl.join(appData, 'alma', 'chat_threads.db');
23
+ }
24
+ const configHome = env.XDG_CONFIG_HOME?.trim() || pathImpl.join(home, '.config');
25
+ return pathImpl.join(configHome, 'alma', 'chat_threads.db');
26
+ }
6
27
 
7
28
  function getCursorStateDbPath() {
8
29
  const rel = join('User', 'globalStorage', 'state.vscdb');
@@ -61,7 +82,6 @@ function findExtensionDirs(extensionId) {
61
82
  return dirs;
62
83
  }
63
84
 
64
- const findClineDataDirs = () => findExtensionDirs('saoudrizwan.claude-dev');
65
85
  const findRooCodeDataDirs = () => findExtensionDirs('rooveterinaryinc.roo-cline');
66
86
 
67
87
  /** Find all OpenClaw data roots: ~/.openclaw and ~/.openclaw-<profile> */
@@ -175,6 +195,12 @@ export function findDimAgentDataDirs() {
175
195
  }
176
196
 
177
197
  export const TOOLS = [
198
+ {
199
+ name: 'Alma',
200
+ id: 'alma',
201
+ dataDir: getAlmaDbPath(),
202
+ detectDataDirs: () => [getAlmaDbPath()].filter(existsSync),
203
+ },
178
204
  {
179
205
  name: 'Claude Code',
180
206
  id: 'claude-code',
@@ -198,6 +224,12 @@ export const TOOLS = [
198
224
  id: 'copilot-cli',
199
225
  dataDir: join(homedir(), '.copilot', 'session-state'),
200
226
  },
227
+ {
228
+ name: 'CraftAgent',
229
+ id: 'craft-agent',
230
+ dataDir: join(homedir(), '.craft-agent', 'workspaces'),
231
+ detectDataDirs: findCraftDataDirs,
232
+ },
201
233
  {
202
234
  name: 'Cursor',
203
235
  id: 'cursor',
@@ -225,10 +257,17 @@ export const TOOLS = [
225
257
  dataDir: join(homedir(), '.openclaw', 'agents'),
226
258
  detectDataDirs: findOpenclawDataDirs,
227
259
  },
260
+ {
261
+ name: 'Oh My Pi',
262
+ id: 'omp',
263
+ dataDir: join(homedir(), '.omp', 'agent', 'sessions'),
264
+ detectDataDirs: findOmpDataDirs,
265
+ },
228
266
  {
229
267
  name: 'pi',
230
268
  id: 'pi-coding-agent',
231
269
  dataDir: join(homedir(), '.pi', 'agent', 'sessions'),
270
+ detectDataDirs: findPiDataDirs,
232
271
  },
233
272
  {
234
273
  name: 'Qwen Code',
@@ -284,7 +323,7 @@ export const TOOLS = [
284
323
  {
285
324
  name: 'Cline',
286
325
  id: 'cline',
287
- dataDir: join(homedir(), 'Library', 'Application Support', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev'),
326
+ dataDir: join(homedir(), '.cline'),
288
327
  detectDataDirs: findClineDataDirs,
289
328
  },
290
329
  {
@@ -293,6 +332,12 @@ export const TOOLS = [
293
332
  dataDir: join(homedir(), 'Library', 'Application Support', 'Code', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline'),
294
333
  detectDataDirs: findRooCodeDataDirs,
295
334
  },
335
+ {
336
+ name: 'WorkBuddy',
337
+ id: 'workbuddy',
338
+ dataDir: join(homedir(), '.workbuddy', 'projects'),
339
+ detectDataDirs: () => findWorkbuddyDataDirs().filter(existsSync),
340
+ },
296
341
  {
297
342
  name: 'ZCode',
298
343
  id: 'zcode',
@@ -0,0 +1,19 @@
1
+ import { delimiter, join } from 'node:path';
2
+ import { homedir } from 'node:os';
3
+
4
+ export function getDefaultWorkbuddyProjectsDir() {
5
+ return join(homedir(), '.workbuddy', 'projects');
6
+ }
7
+
8
+ // Fixture/relocation hook. Entries may name either the WorkBuddy home or its
9
+ // projects/ directory; the parser normalizes both forms.
10
+ export function findWorkbuddyDataDirs() {
11
+ const override = process.env.VIBE_USAGE_WORKBUDDY_DIRS?.trim();
12
+ if (!override) return [getDefaultWorkbuddyProjectsDir()];
13
+ return [...new Set(
14
+ override
15
+ .split(delimiter)
16
+ .map(entry => entry.trim())
17
+ .filter(Boolean)
18
+ )];
19
+ }