@yhong91/vibetime 0.1.66 → 0.1.67
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/bin/vibetime.mjs +109 -12
- package/package.json +1 -1
package/bin/vibetime.mjs
CHANGED
|
@@ -2047,7 +2047,7 @@ function claudeStyleFileMetrics(tool, input) {
|
|
|
2047
2047
|
}
|
|
2048
2048
|
|
|
2049
2049
|
// src/lib/constants.ts
|
|
2050
|
-
var PACKAGE_VERSION = true ? "0.1.
|
|
2050
|
+
var PACKAGE_VERSION = true ? "0.1.67" : "0.1.1";
|
|
2051
2051
|
var GENERATED_MARKER = "Generated by vibetime.";
|
|
2052
2052
|
var DEFAULT_API_URL = "http://121.196.224.82:3001";
|
|
2053
2053
|
var DEFAULT_BACKFILL_BATCH_SIZE = 50;
|
|
@@ -6291,6 +6291,7 @@ function createCopilotAdapter() {
|
|
|
6291
6291
|
}
|
|
6292
6292
|
|
|
6293
6293
|
// src/adapters/cursor.ts
|
|
6294
|
+
import { readFileSync } from "node:fs";
|
|
6294
6295
|
import { copyFile, mkdir as mkdir4, readdir as readdir6, readFile as readFile8, stat as stat8, writeFile as writeFile4 } from "node:fs/promises";
|
|
6295
6296
|
import os6 from "node:os";
|
|
6296
6297
|
import path13 from "node:path";
|
|
@@ -6873,9 +6874,18 @@ function cloudUsageToPersisted(row, index = 0) {
|
|
|
6873
6874
|
tokensCacheCreationInput: row.tokensCacheCreationInput || void 0
|
|
6874
6875
|
};
|
|
6875
6876
|
}
|
|
6876
|
-
async function resolveCursorSessionUsage(options, sessionId) {
|
|
6877
|
+
async function resolveCursorSessionUsage(options, sessionId, filePath) {
|
|
6877
6878
|
const persisted = await readPersistedSessionContextFromOptions(options, sessionId);
|
|
6878
|
-
|
|
6879
|
+
const hookUsage = persisted?.usage ?? [];
|
|
6880
|
+
if (hookUsage.length > 0) {
|
|
6881
|
+
return hookUsage;
|
|
6882
|
+
}
|
|
6883
|
+
const cloudMap = await loadCursorCloudUsageMap(options, filePath);
|
|
6884
|
+
const cloudEvents = cloudMap.get(sessionId);
|
|
6885
|
+
if (!cloudEvents?.length) {
|
|
6886
|
+
return [];
|
|
6887
|
+
}
|
|
6888
|
+
return cloudEvents.map((event, index) => cloudUsageToPersisted(event, index));
|
|
6879
6889
|
}
|
|
6880
6890
|
function cursorCloudUsageCachePath(home) {
|
|
6881
6891
|
return path13.join(home, ".vibetime", CURSOR_CLOUD_USAGE_FILENAME);
|
|
@@ -7146,13 +7156,99 @@ function loadBubbles(db, composerId) {
|
|
|
7146
7156
|
});
|
|
7147
7157
|
return bubbles;
|
|
7148
7158
|
}
|
|
7159
|
+
function pathFromCursorResource(value) {
|
|
7160
|
+
const trimmed = value.trim();
|
|
7161
|
+
if (!trimmed) {
|
|
7162
|
+
return void 0;
|
|
7163
|
+
}
|
|
7164
|
+
const remote = trimmed.match(/^vscode-remote:\/\/[^/]+(\/.*)$/i);
|
|
7165
|
+
if (remote?.[1]) {
|
|
7166
|
+
try {
|
|
7167
|
+
return decodeURIComponent(remote[1]);
|
|
7168
|
+
} catch {
|
|
7169
|
+
return remote[1];
|
|
7170
|
+
}
|
|
7171
|
+
}
|
|
7172
|
+
if (trimmed.startsWith("file:")) {
|
|
7173
|
+
const rest = trimmed.slice("file://".length);
|
|
7174
|
+
try {
|
|
7175
|
+
return decodeURIComponent(rest);
|
|
7176
|
+
} catch {
|
|
7177
|
+
return rest;
|
|
7178
|
+
}
|
|
7179
|
+
}
|
|
7180
|
+
if (path13.isAbsolute(trimmed) || trimmed.startsWith("/")) {
|
|
7181
|
+
return trimmed;
|
|
7182
|
+
}
|
|
7183
|
+
return void 0;
|
|
7184
|
+
}
|
|
7185
|
+
function projectFromFolderPaths(folders, fallback) {
|
|
7186
|
+
const names = [...new Set(
|
|
7187
|
+
folders.map((folder) => path13.basename(folder.replace(/[\\/]+$/, ""))).filter(Boolean)
|
|
7188
|
+
)];
|
|
7189
|
+
if (names.length === 1) {
|
|
7190
|
+
return names[0];
|
|
7191
|
+
}
|
|
7192
|
+
if (names.length > 1) {
|
|
7193
|
+
return names.join("+");
|
|
7194
|
+
}
|
|
7195
|
+
return fallback;
|
|
7196
|
+
}
|
|
7197
|
+
function projectFallbackFromWorkspaceFile(filePath) {
|
|
7198
|
+
const base = path13.basename(filePath, ".code-workspace");
|
|
7199
|
+
const stripped = base.replace(/-workspace$/i, "").trim();
|
|
7200
|
+
return stripped || void 0;
|
|
7201
|
+
}
|
|
7202
|
+
function folderPathsFromCodeWorkspace(workspacePath) {
|
|
7203
|
+
let parsed;
|
|
7204
|
+
try {
|
|
7205
|
+
parsed = JSON.parse(readFileSync(workspacePath, "utf8"));
|
|
7206
|
+
} catch {
|
|
7207
|
+
return [];
|
|
7208
|
+
}
|
|
7209
|
+
if (!isPlainObject(parsed) || !Array.isArray(parsed.folders)) {
|
|
7210
|
+
return [];
|
|
7211
|
+
}
|
|
7212
|
+
const root = path13.dirname(workspacePath);
|
|
7213
|
+
const folders = [];
|
|
7214
|
+
for (const folder of parsed.folders) {
|
|
7215
|
+
if (!isPlainObject(folder)) {
|
|
7216
|
+
continue;
|
|
7217
|
+
}
|
|
7218
|
+
const uri = stringField(folder, "uri");
|
|
7219
|
+
if (uri) {
|
|
7220
|
+
const resolved = pathFromCursorResource(uri);
|
|
7221
|
+
if (resolved) {
|
|
7222
|
+
folders.push(resolved);
|
|
7223
|
+
}
|
|
7224
|
+
continue;
|
|
7225
|
+
}
|
|
7226
|
+
const relative = stringField(folder, "path");
|
|
7227
|
+
if (relative) {
|
|
7228
|
+
folders.push(path13.resolve(root, relative));
|
|
7229
|
+
}
|
|
7230
|
+
}
|
|
7231
|
+
return folders;
|
|
7232
|
+
}
|
|
7149
7233
|
function workspaceFromComposer(data) {
|
|
7150
7234
|
const ident = objectField(data, "workspaceIdentifier");
|
|
7151
7235
|
const uri = objectField(ident, "uri");
|
|
7152
|
-
const
|
|
7236
|
+
const fromUri = stringField(uri, "fsPath") || stringField(uri, "path") || (stringField(uri, "external") ? pathFromCursorResource(stringField(uri, "external")) : void 0);
|
|
7237
|
+
if (fromUri) {
|
|
7238
|
+
return {
|
|
7239
|
+
cwd: fromUri,
|
|
7240
|
+
project: path13.basename(fromUri.replace(/[\\/]+$/, "")) || void 0
|
|
7241
|
+
};
|
|
7242
|
+
}
|
|
7243
|
+
const configPath2 = objectField(ident, "configPath");
|
|
7244
|
+
const workspaceFile = stringField(configPath2, "fsPath") || stringField(configPath2, "path") || (stringField(configPath2, "external") ? pathFromCursorResource(stringField(configPath2, "external")) : void 0);
|
|
7245
|
+
if (!workspaceFile) {
|
|
7246
|
+
return {};
|
|
7247
|
+
}
|
|
7248
|
+
const folders = folderPathsFromCodeWorkspace(workspaceFile);
|
|
7153
7249
|
return {
|
|
7154
|
-
cwd,
|
|
7155
|
-
project:
|
|
7250
|
+
cwd: folders[0],
|
|
7251
|
+
project: projectFromFolderPaths(folders, projectFallbackFromWorkspaceFile(workspaceFile))
|
|
7156
7252
|
};
|
|
7157
7253
|
}
|
|
7158
7254
|
function modelFromComposer(data) {
|
|
@@ -7688,6 +7784,7 @@ async function parseCursorTranscriptFile(filePath, options) {
|
|
|
7688
7784
|
push,
|
|
7689
7785
|
sessionId,
|
|
7690
7786
|
options,
|
|
7787
|
+
filePath,
|
|
7691
7788
|
fallbackTs: endedAt || lastTs,
|
|
7692
7789
|
lastTurnId,
|
|
7693
7790
|
model,
|
|
@@ -7701,7 +7798,7 @@ async function appendPersistedCursorUsage(args) {
|
|
|
7701
7798
|
}
|
|
7702
7799
|
emitPersistedCursorUsage(
|
|
7703
7800
|
args.push,
|
|
7704
|
-
await resolveCursorSessionUsage(args.options, args.sessionId),
|
|
7801
|
+
await resolveCursorSessionUsage(args.options, args.sessionId, args.filePath),
|
|
7705
7802
|
args.fallbackTs,
|
|
7706
7803
|
args.lastTurnId,
|
|
7707
7804
|
args.model,
|
|
@@ -7805,7 +7902,7 @@ async function parseCursorSessionFile(filePath, options) {
|
|
|
7805
7902
|
try {
|
|
7806
7903
|
const composers = listComposers(opened.db);
|
|
7807
7904
|
for (const composer of composers) {
|
|
7808
|
-
const usage = await resolveCursorSessionUsage(options, composer.composerId);
|
|
7905
|
+
const usage = await resolveCursorSessionUsage(options, composer.composerId, filePath);
|
|
7809
7906
|
events.push(...parseComposer(opened.db, composer, filePath, sourcePathHash, options, usage));
|
|
7810
7907
|
}
|
|
7811
7908
|
} finally {
|
|
@@ -8180,7 +8277,7 @@ async function grokBotBackfillFiles(sourceRoot, home = os7.homedir(), env, optio
|
|
|
8180
8277
|
function createGrokBotAdapter() {
|
|
8181
8278
|
return {
|
|
8182
8279
|
id: SOURCE_ID2,
|
|
8183
|
-
label: "
|
|
8280
|
+
label: "Cloud Agent",
|
|
8184
8281
|
agentName: AGENT_NAME2,
|
|
8185
8282
|
kind: "agent",
|
|
8186
8283
|
// No hooks to install — data arrives via the Cursor dashboard API.
|
|
@@ -15100,7 +15197,7 @@ async function uninstallGeneratedFile(filePath, { dryRun, onWrite }) {
|
|
|
15100
15197
|
|
|
15101
15198
|
// src/lib/config.ts
|
|
15102
15199
|
import { randomUUID } from "node:crypto";
|
|
15103
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
15200
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, rmSync, writeFileSync } from "node:fs";
|
|
15104
15201
|
import { homedir, hostname } from "node:os";
|
|
15105
15202
|
import path24 from "node:path";
|
|
15106
15203
|
function disabledBackfillSourceSet(config) {
|
|
@@ -15122,7 +15219,7 @@ function readConfig(home = homedir()) {
|
|
|
15122
15219
|
return {};
|
|
15123
15220
|
}
|
|
15124
15221
|
try {
|
|
15125
|
-
const parsed = JSON.parse(
|
|
15222
|
+
const parsed = JSON.parse(readFileSync2(file, "utf8"));
|
|
15126
15223
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
15127
15224
|
} catch {
|
|
15128
15225
|
return {};
|
|
@@ -15139,7 +15236,7 @@ function writeConfig(config, home = homedir()) {
|
|
|
15139
15236
|
function ensureLocalMachineId(home = homedir()) {
|
|
15140
15237
|
const file = machineIdPath(home);
|
|
15141
15238
|
if (existsSync2(file)) {
|
|
15142
|
-
const value =
|
|
15239
|
+
const value = readFileSync2(file, "utf8").trim();
|
|
15143
15240
|
if (value.length > 0) {
|
|
15144
15241
|
return value;
|
|
15145
15242
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yhong91/vibetime",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.67",
|
|
5
5
|
"description": "vibetime CLI — install AI-agent hooks (Claude Code, Codex, OpenCode, Pi, Cursor) and report activity to vibetime.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"publishConfig": {
|