@yhong91/vibetime 0.1.73 → 0.1.75
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 +161 -166
- package/package.json +1 -1
package/bin/vibetime.mjs
CHANGED
|
@@ -884,8 +884,8 @@ var init_esm = __esm({
|
|
|
884
884
|
|
|
885
885
|
// src/cli.ts
|
|
886
886
|
import { spawn as spawn2, spawnSync } from "node:child_process";
|
|
887
|
-
import { mkdir as mkdir6, open, rm, stat as
|
|
888
|
-
import
|
|
887
|
+
import { mkdir as mkdir6, open, rm, stat as stat17, writeFile as writeFile5 } from "node:fs/promises";
|
|
888
|
+
import os13 from "node:os";
|
|
889
889
|
import path27 from "node:path";
|
|
890
890
|
import { fileURLToPath } from "node:url";
|
|
891
891
|
|
|
@@ -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.75" : "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;
|
|
@@ -2103,6 +2103,9 @@ function msToIso(ms) {
|
|
|
2103
2103
|
}
|
|
2104
2104
|
|
|
2105
2105
|
// src/lib/backfill.ts
|
|
2106
|
+
function rollupKeyForSourceSession(source, sessionId) {
|
|
2107
|
+
return createImportKey(["rollup", source, sessionId]);
|
|
2108
|
+
}
|
|
2106
2109
|
function withBackfillRefs(event, context) {
|
|
2107
2110
|
const importKey = createImportKey([
|
|
2108
2111
|
event.source,
|
|
@@ -4936,8 +4939,8 @@ async function codebuddyBackfillFiles(sourceRoot, home, env) {
|
|
|
4936
4939
|
}
|
|
4937
4940
|
const filePath = path9.join(traceDir, entry);
|
|
4938
4941
|
try {
|
|
4939
|
-
const
|
|
4940
|
-
files.push({ path: filePath, modifiedAt:
|
|
4942
|
+
const stat18 = await import("node:fs/promises").then((fs) => fs.stat(filePath));
|
|
4943
|
+
files.push({ path: filePath, modifiedAt: stat18.mtime.toISOString(), groupId: pidDir.name });
|
|
4941
4944
|
} catch {
|
|
4942
4945
|
}
|
|
4943
4946
|
}
|
|
@@ -5163,7 +5166,6 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5163
5166
|
let lastTurnIdForComplete;
|
|
5164
5167
|
let turnIdAtLastUserMessage;
|
|
5165
5168
|
let sessionMetaLocked = false;
|
|
5166
|
-
let forkedSession = false;
|
|
5167
5169
|
let lastTotalTokenUsage;
|
|
5168
5170
|
let lastPerCallUsageKey;
|
|
5169
5171
|
let compactionPending = false;
|
|
@@ -5184,7 +5186,6 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5184
5186
|
}
|
|
5185
5187
|
sessionMetaLocked = true;
|
|
5186
5188
|
const forkedFromId = stringField(payload, "forked_from_id");
|
|
5187
|
-
forkedSession = Boolean(forkedFromId);
|
|
5188
5189
|
const inherited = forkedFromId ? await readPersistedSessionContextFromOptions(options, forkedFromId) : void 0;
|
|
5189
5190
|
sessionId = stringField(payload, "id") || sessionId;
|
|
5190
5191
|
cwd = inherited?.cwd || stringField(payload, "cwd") || cwd;
|
|
@@ -5336,7 +5337,7 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5336
5337
|
project,
|
|
5337
5338
|
model: rewriteCodexModelForTier(model, serviceTier),
|
|
5338
5339
|
confidence: "partial",
|
|
5339
|
-
metrics:
|
|
5340
|
+
metrics: usage
|
|
5340
5341
|
}), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
|
|
5341
5342
|
lastPerCallUsageKey = usageKey;
|
|
5342
5343
|
}
|
|
@@ -5354,7 +5355,7 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5354
5355
|
project,
|
|
5355
5356
|
model: rewriteCodexModelForTier(model, serviceTier),
|
|
5356
5357
|
confidence: "partial",
|
|
5357
|
-
metrics:
|
|
5358
|
+
metrics: { ...lastUsage, reasoningEffort }
|
|
5358
5359
|
}), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
|
|
5359
5360
|
}
|
|
5360
5361
|
lastTotalTokenUsage = { input, cached, output, reasoning, total };
|
|
@@ -5378,7 +5379,7 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5378
5379
|
project,
|
|
5379
5380
|
model: rewriteCodexModelForTier(model, serviceTier),
|
|
5380
5381
|
confidence: "partial",
|
|
5381
|
-
metrics:
|
|
5382
|
+
metrics: {
|
|
5382
5383
|
tokensInput: deltaInput > 0 ? deltaInput : void 0,
|
|
5383
5384
|
tokensCachedInput: deltaCached > 0 ? deltaCached : void 0,
|
|
5384
5385
|
tokensOutput: deltaOutput > 0 ? deltaOutput : void 0,
|
|
@@ -5386,7 +5387,7 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5386
5387
|
tokensTotal: deltaTotal > 0 ? deltaTotal : void 0,
|
|
5387
5388
|
modelContextWindow: usage.modelContextWindow,
|
|
5388
5389
|
reasoningEffort
|
|
5389
|
-
}
|
|
5390
|
+
}
|
|
5390
5391
|
}), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
|
|
5391
5392
|
}
|
|
5392
5393
|
} else {
|
|
@@ -5399,7 +5400,7 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5399
5400
|
project,
|
|
5400
5401
|
model: rewriteCodexModelForTier(model, serviceTier),
|
|
5401
5402
|
confidence: "partial",
|
|
5402
|
-
metrics:
|
|
5403
|
+
metrics: {
|
|
5403
5404
|
tokensInput: input,
|
|
5404
5405
|
tokensCachedInput: cached,
|
|
5405
5406
|
tokensOutput: output,
|
|
@@ -5407,7 +5408,7 @@ async function parseCodexSessionFile(filePath, options) {
|
|
|
5407
5408
|
tokensTotal: total,
|
|
5408
5409
|
modelContextWindow: usage.modelContextWindow,
|
|
5409
5410
|
reasoningEffort
|
|
5410
|
-
}
|
|
5411
|
+
}
|
|
5411
5412
|
}), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
|
|
5412
5413
|
}
|
|
5413
5414
|
lastTotalTokenUsage = { input, cached, output, reasoning, total };
|
|
@@ -5708,18 +5709,6 @@ function tokenUsageFromRecord(usage, info) {
|
|
|
5708
5709
|
modelContextWindow: numberField(info, "model_context_window")
|
|
5709
5710
|
};
|
|
5710
5711
|
}
|
|
5711
|
-
function excludeForkInheritedCache(usage, forked) {
|
|
5712
|
-
if (!forked || !usage) {
|
|
5713
|
-
return usage;
|
|
5714
|
-
}
|
|
5715
|
-
const cached = usage.tokensCachedInput ?? 0;
|
|
5716
|
-
return {
|
|
5717
|
-
...usage,
|
|
5718
|
-
tokensInput: Math.max(0, (usage.tokensInput ?? 0) - cached) || void 0,
|
|
5719
|
-
tokensCachedInput: void 0,
|
|
5720
|
-
tokensTotal: Math.max(0, (usage.tokensTotal ?? 0) - cached) || void 0
|
|
5721
|
-
};
|
|
5722
|
-
}
|
|
5723
5712
|
function toolNameFromPayload(payload, payloadType) {
|
|
5724
5713
|
if (payloadType === "web_search_call") {
|
|
5725
5714
|
return "web_search";
|
|
@@ -6514,10 +6503,10 @@ function cloudAgentSessionFromEvents(conversationId, events) {
|
|
|
6514
6503
|
};
|
|
6515
6504
|
}
|
|
6516
6505
|
function hookUncachedInputTokens(turn) {
|
|
6517
|
-
return Math.max(0, (turn.tokensInput || 0) - (turn.tokensCacheReadInput || 0));
|
|
6506
|
+
return Math.max(0, (turn.tokensInput || 0) - (turn.tokensCacheReadInput || 0) - (turn.tokensCacheCreationInput || 0));
|
|
6518
6507
|
}
|
|
6519
6508
|
function cloudEventMatchesHookTurn(event, turn) {
|
|
6520
|
-
return event.tokensInput === hookUncachedInputTokens(turn) && event.tokensOutput === (turn.tokensOutput || 0) && event.tokensCacheReadInput === (turn.tokensCacheReadInput || 0);
|
|
6509
|
+
return event.tokensInput === hookUncachedInputTokens(turn) && event.tokensOutput === (turn.tokensOutput || 0) && event.tokensCacheReadInput === (turn.tokensCacheReadInput || 0) && event.tokensCacheCreationInput === (turn.tokensCacheCreationInput || 0);
|
|
6521
6510
|
}
|
|
6522
6511
|
function unmatchedCloudEvents(events, turns) {
|
|
6523
6512
|
const used = /* @__PURE__ */ new Set();
|
|
@@ -6860,6 +6849,11 @@ async function loadCursorCloudUsageMap(options, filePath) {
|
|
|
6860
6849
|
return cached;
|
|
6861
6850
|
}
|
|
6862
6851
|
const home = stringOption(options.home) || os6.homedir();
|
|
6852
|
+
if (options.skipCursorCloud) {
|
|
6853
|
+
return cloudUsageMapFromSessions(
|
|
6854
|
+
parseCursorCloudUsageCache(await readJsonIfExists(cursorCloudUsageCachePath(home)))
|
|
6855
|
+
);
|
|
6856
|
+
}
|
|
6863
6857
|
const intervalSeconds = cursorCloudFetchIntervalSeconds();
|
|
6864
6858
|
if (intervalSeconds > 0 && !options.force) {
|
|
6865
6859
|
const lastFetchedMs = await readLastCloudFetchAt(home);
|
|
@@ -6981,7 +6975,7 @@ async function writeCursorCloudUsageCache(cachePath, sessions) {
|
|
|
6981
6975
|
const info = await stat8(cachePath);
|
|
6982
6976
|
return info.mtime.toISOString();
|
|
6983
6977
|
}
|
|
6984
|
-
function parseCursorCloudAgentSessions(filePath, options, sessions, localIds
|
|
6978
|
+
function parseCursorCloudAgentSessions(filePath, options, sessions, localIds) {
|
|
6985
6979
|
const events = [];
|
|
6986
6980
|
const sourcePathHash = `sha256:${createStableHash(filePath)}`;
|
|
6987
6981
|
const project = CURSOR_CLOUD_AGENT_PROJECT;
|
|
@@ -6998,8 +6992,8 @@ function parseCursorCloudAgentSessions(filePath, options, sessions, localIds, id
|
|
|
6998
6992
|
lineNumber += 1;
|
|
6999
6993
|
const event = {
|
|
7000
6994
|
schemaVersion: AGENT_TIME_SCHEMA_VERSION,
|
|
7001
|
-
source:
|
|
7002
|
-
agent:
|
|
6995
|
+
source: SOURCE_ID,
|
|
6996
|
+
agent: AGENT_NAME,
|
|
7003
6997
|
workspaceId,
|
|
7004
6998
|
project,
|
|
7005
6999
|
model: lastModel,
|
|
@@ -7056,7 +7050,7 @@ function parseCursorCloudAgentSessions(filePath, options, sessions, localIds, id
|
|
|
7056
7050
|
}
|
|
7057
7051
|
return events;
|
|
7058
7052
|
}
|
|
7059
|
-
async function parseCursorCloudAgentFile(filePath, options
|
|
7053
|
+
async function parseCursorCloudAgentFile(filePath, options) {
|
|
7060
7054
|
const home = stringOption(options.home) || os6.homedir();
|
|
7061
7055
|
const env = {
|
|
7062
7056
|
CURSOR_HOME: process.env.CURSOR_HOME,
|
|
@@ -7068,7 +7062,7 @@ async function parseCursorCloudAgentFile(filePath, options, identity) {
|
|
|
7068
7062
|
return session ? [session] : [];
|
|
7069
7063
|
}) : parseCursorCloudUsageCache(await readJsonIfExists(filePath));
|
|
7070
7064
|
const localIds = await listLocalCursorSessionIds(home, env);
|
|
7071
|
-
return parseCursorCloudAgentSessions(filePath, options, sessions, localIds
|
|
7065
|
+
return parseCursorCloudAgentSessions(filePath, options, sessions, localIds);
|
|
7072
7066
|
}
|
|
7073
7067
|
function decodeKv(value) {
|
|
7074
7068
|
if (typeof value === "string") {
|
|
@@ -7927,6 +7921,9 @@ async function parseCursorSessionFile(filePath, options) {
|
|
|
7927
7921
|
if (base.endsWith(".jsonl")) {
|
|
7928
7922
|
return parseCursorTranscriptFile(filePath, options);
|
|
7929
7923
|
}
|
|
7924
|
+
if (base === CURSOR_CLOUD_USAGE_FILENAME) {
|
|
7925
|
+
return parseCursorCloudAgentFile(filePath, options);
|
|
7926
|
+
}
|
|
7930
7927
|
if (base === "store.db") {
|
|
7931
7928
|
return [];
|
|
7932
7929
|
}
|
|
@@ -8161,7 +8158,36 @@ function parseComposer(db, composer, filePath, sourcePathHash, options, persiste
|
|
|
8161
8158
|
emitPersistedCursorUsage(push, persistedUsage, endedAt || startedAt, currentTurnId, model, sessionId, events.some((event) => event.type === "model.usage"));
|
|
8162
8159
|
return events;
|
|
8163
8160
|
}
|
|
8164
|
-
async function
|
|
8161
|
+
async function cursorCloudUsageBackfillFiles(home, options) {
|
|
8162
|
+
if (options?.skipCursorCloud || cursorCloudUsageDisabled()) {
|
|
8163
|
+
return [];
|
|
8164
|
+
}
|
|
8165
|
+
const cachePath = cursorCloudUsageCachePath(home);
|
|
8166
|
+
if (!options) {
|
|
8167
|
+
const info = await stat8(cachePath).catch(() => null);
|
|
8168
|
+
return info ? [{ path: cachePath, modifiedAt: info.mtime.toISOString() }] : [];
|
|
8169
|
+
}
|
|
8170
|
+
const map = await loadCursorCloudUsageMap(options);
|
|
8171
|
+
if (map.size === 0) {
|
|
8172
|
+
const info = await stat8(cachePath).catch(() => null);
|
|
8173
|
+
return info ? [{ path: cachePath, modifiedAt: info.mtime.toISOString() }] : [];
|
|
8174
|
+
}
|
|
8175
|
+
const sessions = [];
|
|
8176
|
+
for (const [conversationId, events] of map) {
|
|
8177
|
+
const session = cloudAgentSessionFromEvents(conversationId, events);
|
|
8178
|
+
if (session) {
|
|
8179
|
+
sessions.push(session);
|
|
8180
|
+
}
|
|
8181
|
+
}
|
|
8182
|
+
if (sessions.length === 0) {
|
|
8183
|
+
return [];
|
|
8184
|
+
}
|
|
8185
|
+
return [{
|
|
8186
|
+
path: cachePath,
|
|
8187
|
+
modifiedAt: await writeCursorCloudUsageCache(cachePath, sessions)
|
|
8188
|
+
}];
|
|
8189
|
+
}
|
|
8190
|
+
async function cursorBackfillFiles(sourceRoot, home = os6.homedir(), env, options) {
|
|
8165
8191
|
if (sourceRoot) {
|
|
8166
8192
|
const info = await stat8(sourceRoot).catch(() => null);
|
|
8167
8193
|
if (!info) {
|
|
@@ -8191,6 +8217,9 @@ async function cursorBackfillFiles(sourceRoot, home = os6.homedir(), env) {
|
|
|
8191
8217
|
files2.push(...await collectCursorTranscriptFiles(sourceRoot, home, skipIds2));
|
|
8192
8218
|
return files2;
|
|
8193
8219
|
}
|
|
8220
|
+
if (path13.basename(sourceRoot) === CURSOR_CLOUD_USAGE_FILENAME) {
|
|
8221
|
+
return [{ path: sourceRoot, modifiedAt: info.mtime.toISOString() }];
|
|
8222
|
+
}
|
|
8194
8223
|
if (path13.basename(sourceRoot) === "store.db") {
|
|
8195
8224
|
return [];
|
|
8196
8225
|
}
|
|
@@ -8228,6 +8257,7 @@ async function cursorBackfillFiles(sourceRoot, home = os6.homedir(), env) {
|
|
|
8228
8257
|
break;
|
|
8229
8258
|
}
|
|
8230
8259
|
files.push(...await collectCursorTranscriptFiles(cursorProjectsDir(home, env), home, skipIds));
|
|
8260
|
+
files.push(...await cursorCloudUsageBackfillFiles(home, options));
|
|
8231
8261
|
return files;
|
|
8232
8262
|
}
|
|
8233
8263
|
function cursorHookConfig() {
|
|
@@ -8265,85 +8295,22 @@ function createCursorAdapter() {
|
|
|
8265
8295
|
return [
|
|
8266
8296
|
...cursorStateDbCandidates(home, env),
|
|
8267
8297
|
cursorProjectsDir(home, env),
|
|
8268
|
-
cursorChatsDir(home, env)
|
|
8298
|
+
cursorChatsDir(home, env),
|
|
8299
|
+
cursorCloudUsageCachePath(home)
|
|
8269
8300
|
];
|
|
8270
8301
|
},
|
|
8271
8302
|
parseSessionFile: parseCursorSessionFile
|
|
8272
8303
|
};
|
|
8273
8304
|
}
|
|
8274
8305
|
|
|
8275
|
-
// src/adapters/grok-bot.ts
|
|
8276
|
-
import { stat as stat9 } from "node:fs/promises";
|
|
8277
|
-
import os7 from "node:os";
|
|
8278
|
-
var SOURCE_ID2 = "grok-bot";
|
|
8279
|
-
var AGENT_NAME2 = "grok-bot";
|
|
8280
|
-
var IDENTITY = { source: SOURCE_ID2, agent: AGENT_NAME2 };
|
|
8281
|
-
async function grokBotBackfillFiles(sourceRoot, home = os7.homedir(), _env, options) {
|
|
8282
|
-
if (sourceRoot) {
|
|
8283
|
-
const info = await stat9(sourceRoot).catch(() => null);
|
|
8284
|
-
return info ? [{ path: sourceRoot, modifiedAt: info.mtime.toISOString() }] : [];
|
|
8285
|
-
}
|
|
8286
|
-
if (!options) {
|
|
8287
|
-
return [];
|
|
8288
|
-
}
|
|
8289
|
-
const cachePath = cursorCloudUsageCachePath(home);
|
|
8290
|
-
const map = await loadCursorCloudUsageMap(options);
|
|
8291
|
-
if (map.size === 0) {
|
|
8292
|
-
const info = await stat9(cachePath).catch(() => null);
|
|
8293
|
-
return info ? [{ path: cachePath, modifiedAt: info.mtime.toISOString() }] : [];
|
|
8294
|
-
}
|
|
8295
|
-
const sessions = [];
|
|
8296
|
-
for (const [conversationId, events] of map) {
|
|
8297
|
-
const session = cloudAgentSessionFromEvents(conversationId, events);
|
|
8298
|
-
if (session) {
|
|
8299
|
-
sessions.push(session);
|
|
8300
|
-
}
|
|
8301
|
-
}
|
|
8302
|
-
if (sessions.length === 0) {
|
|
8303
|
-
return [];
|
|
8304
|
-
}
|
|
8305
|
-
return [{
|
|
8306
|
-
path: cachePath,
|
|
8307
|
-
modifiedAt: await writeCursorCloudUsageCache(cachePath, sessions)
|
|
8308
|
-
}];
|
|
8309
|
-
}
|
|
8310
|
-
function createGrokBotAdapter() {
|
|
8311
|
-
return {
|
|
8312
|
-
id: SOURCE_ID2,
|
|
8313
|
-
label: "Grok Bot",
|
|
8314
|
-
agentName: AGENT_NAME2,
|
|
8315
|
-
kind: "agent",
|
|
8316
|
-
// No hooks to install — data arrives via the Cursor dashboard API.
|
|
8317
|
-
// The cache file stands in as the detect/install marker.
|
|
8318
|
-
detectPath(home) {
|
|
8319
|
-
return cursorCloudUsageCachePath(home);
|
|
8320
|
-
},
|
|
8321
|
-
installedPath(home) {
|
|
8322
|
-
return cursorCloudUsageCachePath(home);
|
|
8323
|
-
},
|
|
8324
|
-
async isInstalled() {
|
|
8325
|
-
return false;
|
|
8326
|
-
},
|
|
8327
|
-
installEntries() {
|
|
8328
|
-
return [];
|
|
8329
|
-
},
|
|
8330
|
-
sourcePaths(home) {
|
|
8331
|
-
return [cursorCloudUsageCachePath(home)];
|
|
8332
|
-
},
|
|
8333
|
-
parseSessionFile(filePath, options) {
|
|
8334
|
-
return parseCursorCloudAgentFile(filePath, options, IDENTITY);
|
|
8335
|
-
}
|
|
8336
|
-
};
|
|
8337
|
-
}
|
|
8338
|
-
|
|
8339
8306
|
// src/adapters/grok-build.ts
|
|
8340
|
-
import { readdir as readdir7, readFile as readFile9, stat as
|
|
8307
|
+
import { readdir as readdir7, readFile as readFile9, stat as stat9 } from "node:fs/promises";
|
|
8341
8308
|
import path14 from "node:path";
|
|
8342
8309
|
init_fs();
|
|
8343
8310
|
var GROK_COST_TICKS_PER_USD = 1e9;
|
|
8344
|
-
var
|
|
8345
|
-
var
|
|
8346
|
-
var HOOK_COMMAND2 = `vibetime hook --agent ${
|
|
8311
|
+
var SOURCE_ID2 = "grok-build";
|
|
8312
|
+
var AGENT_NAME2 = "grok-build";
|
|
8313
|
+
var HOOK_COMMAND2 = `vibetime hook --agent ${SOURCE_ID2}`;
|
|
8347
8314
|
function grokHome(home, env) {
|
|
8348
8315
|
const override = env?.GROK_HOME;
|
|
8349
8316
|
if (override && override.trim()) {
|
|
@@ -8377,7 +8344,7 @@ async function grokBackfillFiles(sourceRoot, home, env) {
|
|
|
8377
8344
|
continue;
|
|
8378
8345
|
}
|
|
8379
8346
|
try {
|
|
8380
|
-
const info = await
|
|
8347
|
+
const info = await stat9(entryPath);
|
|
8381
8348
|
files.push({ path: entryPath, modifiedAt: info.mtime.toISOString() });
|
|
8382
8349
|
} catch {
|
|
8383
8350
|
}
|
|
@@ -8429,8 +8396,8 @@ async function parseGrokSessionFile(filePath, options) {
|
|
|
8429
8396
|
};
|
|
8430
8397
|
const base = (partial) => ({
|
|
8431
8398
|
schemaVersion: AGENT_TIME_SCHEMA_VERSION,
|
|
8432
|
-
source:
|
|
8433
|
-
agent:
|
|
8399
|
+
source: SOURCE_ID2,
|
|
8400
|
+
agent: AGENT_NAME2,
|
|
8434
8401
|
workspaceId,
|
|
8435
8402
|
project,
|
|
8436
8403
|
cwd,
|
|
@@ -8990,7 +8957,7 @@ async function loadHunkFileActivities(hunkPath, cwd) {
|
|
|
8990
8957
|
}
|
|
8991
8958
|
return activities;
|
|
8992
8959
|
}
|
|
8993
|
-
var grokHandler = (msg) => hookHandler(
|
|
8960
|
+
var grokHandler = (msg) => hookHandler(SOURCE_ID2, msg);
|
|
8994
8961
|
function hookConfig5() {
|
|
8995
8962
|
const anyTool = [{ matcher: ".*", hooks: [grokHandler("Reporting tool activity")] }];
|
|
8996
8963
|
return {
|
|
@@ -9012,9 +8979,9 @@ function hookConfig5() {
|
|
|
9012
8979
|
}
|
|
9013
8980
|
function createGrokBuildAdapter() {
|
|
9014
8981
|
return {
|
|
9015
|
-
id:
|
|
8982
|
+
id: SOURCE_ID2,
|
|
9016
8983
|
label: "Grok Build",
|
|
9017
|
-
agentName:
|
|
8984
|
+
agentName: AGENT_NAME2,
|
|
9018
8985
|
kind: "agent",
|
|
9019
8986
|
detectPath(home, env) {
|
|
9020
8987
|
return grokHome(home, env);
|
|
@@ -9040,7 +9007,7 @@ function createGrokBuildAdapter() {
|
|
|
9040
9007
|
}
|
|
9041
9008
|
|
|
9042
9009
|
// src/adapters/hermes.ts
|
|
9043
|
-
import { readdir as readdir8, stat as
|
|
9010
|
+
import { readdir as readdir8, stat as stat10 } from "node:fs/promises";
|
|
9044
9011
|
import path15 from "node:path";
|
|
9045
9012
|
init_fs();
|
|
9046
9013
|
var SOURCE = "hermes";
|
|
@@ -9333,11 +9300,11 @@ function hermesToolAlias(tool) {
|
|
|
9333
9300
|
}
|
|
9334
9301
|
async function sqliteMtime(filePath) {
|
|
9335
9302
|
try {
|
|
9336
|
-
const info = await
|
|
9303
|
+
const info = await stat10(filePath);
|
|
9337
9304
|
let modifiedMs = info.mtimeMs;
|
|
9338
9305
|
for (const suffix of ["-wal", "-shm"]) {
|
|
9339
9306
|
try {
|
|
9340
|
-
const sidecar = await
|
|
9307
|
+
const sidecar = await stat10(`${filePath}${suffix}`);
|
|
9341
9308
|
modifiedMs = Math.max(modifiedMs, sidecar.mtimeMs);
|
|
9342
9309
|
} catch {
|
|
9343
9310
|
}
|
|
@@ -10630,7 +10597,7 @@ function createKimiCodeAdapter() {
|
|
|
10630
10597
|
}
|
|
10631
10598
|
|
|
10632
10599
|
// src/adapters/opencode.ts
|
|
10633
|
-
import
|
|
10600
|
+
import os7 from "node:os";
|
|
10634
10601
|
import path17 from "node:path";
|
|
10635
10602
|
async function parseOpenCodeSessionFile(dbPath, options) {
|
|
10636
10603
|
const { DatabaseSync } = await import("node:sqlite");
|
|
@@ -11085,20 +11052,20 @@ function opencodeDataCandidates(home, env) {
|
|
|
11085
11052
|
const primary = xdgData && xdgData.trim() ? path17.join(path17.resolve(xdgData), "opencode", "opencode.db") : path17.join(home, ".local", "share", "opencode", "opencode.db");
|
|
11086
11053
|
return [primary, path17.join(home, ".opencode", "opencode.db")];
|
|
11087
11054
|
}
|
|
11088
|
-
async function opencodeBackfillFiles(sourceRoot, home =
|
|
11089
|
-
const { stat:
|
|
11055
|
+
async function opencodeBackfillFiles(sourceRoot, home = os7.homedir(), env) {
|
|
11056
|
+
const { stat: stat18 } = await import("node:fs/promises");
|
|
11090
11057
|
if (sourceRoot) {
|
|
11091
11058
|
if (!sourceRoot.endsWith(".db")) {
|
|
11092
11059
|
return [];
|
|
11093
11060
|
}
|
|
11094
|
-
const info = await
|
|
11061
|
+
const info = await stat18(sourceRoot).catch(() => null);
|
|
11095
11062
|
if (!info) {
|
|
11096
11063
|
return [];
|
|
11097
11064
|
}
|
|
11098
11065
|
return [{ path: sourceRoot, modifiedAt: info.mtime.toISOString() }];
|
|
11099
11066
|
}
|
|
11100
11067
|
for (const candidatePath of opencodeDataCandidates(home, env)) {
|
|
11101
|
-
const info = await
|
|
11068
|
+
const info = await stat18(candidatePath).catch(() => null);
|
|
11102
11069
|
if (info) {
|
|
11103
11070
|
return [{ path: candidatePath, modifiedAt: info.mtime.toISOString() }];
|
|
11104
11071
|
}
|
|
@@ -11198,8 +11165,8 @@ function createOpenCodeAdapter() {
|
|
|
11198
11165
|
}
|
|
11199
11166
|
|
|
11200
11167
|
// src/adapters/pi.ts
|
|
11201
|
-
import { readdir as readdir9, readFile as readFile11, stat as
|
|
11202
|
-
import
|
|
11168
|
+
import { readdir as readdir9, readFile as readFile11, stat as stat11 } from "node:fs/promises";
|
|
11169
|
+
import os8 from "node:os";
|
|
11203
11170
|
import path18 from "node:path";
|
|
11204
11171
|
init_fs();
|
|
11205
11172
|
function piHostSessionIdFromBasename(basename) {
|
|
@@ -11610,7 +11577,7 @@ async function parsePiWorkflowRunFile(filePath, options) {
|
|
|
11610
11577
|
return state.events.filter((event) => matchesBackfillFilters(event, options));
|
|
11611
11578
|
}
|
|
11612
11579
|
async function findPiSessionFileById(sessionId, options) {
|
|
11613
|
-
const sessionsDir = piSessionDir(path18.resolve(stringOption(options.home) ||
|
|
11580
|
+
const sessionsDir = piSessionDir(path18.resolve(stringOption(options.home) || os8.homedir()));
|
|
11614
11581
|
try {
|
|
11615
11582
|
const projectDirs = await readdir9(sessionsDir, { withFileTypes: true });
|
|
11616
11583
|
for (const dir of projectDirs) {
|
|
@@ -11887,14 +11854,14 @@ async function workflowRunGroupId(filePath) {
|
|
|
11887
11854
|
return void 0;
|
|
11888
11855
|
}
|
|
11889
11856
|
}
|
|
11890
|
-
async function piBackfillFiles(sourceRoot, home =
|
|
11857
|
+
async function piBackfillFiles(sourceRoot, home = os8.homedir(), env) {
|
|
11891
11858
|
const lists = sourceRoot ? [await listFilesByExtensions(sourceRoot, [".jsonl", ".json"])] : await Promise.all([
|
|
11892
11859
|
listFilesByExtensions(piSessionDir(home, env), [".jsonl"]),
|
|
11893
11860
|
listFilesByExtensions(piWorkflowProjectsDir(home), [".json"])
|
|
11894
11861
|
]);
|
|
11895
11862
|
const files = lists.flat().sort();
|
|
11896
11863
|
return Promise.all(files.map(async (filePath) => {
|
|
11897
|
-
const info = await
|
|
11864
|
+
const info = await stat11(filePath);
|
|
11898
11865
|
let groupId = resolvePiBackfillGroupId(filePath);
|
|
11899
11866
|
if (!groupId && filePath.endsWith(".json")) {
|
|
11900
11867
|
groupId = await workflowRunGroupId(filePath);
|
|
@@ -11941,13 +11908,13 @@ function createPiAdapter() {
|
|
|
11941
11908
|
}
|
|
11942
11909
|
|
|
11943
11910
|
// src/adapters/qoder-cn.ts
|
|
11944
|
-
import { readdir as readdir10, readFile as readFile12, stat as
|
|
11945
|
-
import
|
|
11911
|
+
import { readdir as readdir10, readFile as readFile12, stat as stat12 } from "node:fs/promises";
|
|
11912
|
+
import os10 from "node:os";
|
|
11946
11913
|
import path20 from "node:path";
|
|
11947
11914
|
|
|
11948
11915
|
// src/adapters/qoder-local-db.ts
|
|
11949
11916
|
import { access } from "node:fs/promises";
|
|
11950
|
-
import
|
|
11917
|
+
import os9 from "node:os";
|
|
11951
11918
|
import path19 from "node:path";
|
|
11952
11919
|
function takeQoderDbModelCall(calls, requestId, blockStart) {
|
|
11953
11920
|
if (requestId) {
|
|
@@ -11965,7 +11932,7 @@ function takeQoderDbModelCall(calls, requestId, blockStart) {
|
|
|
11965
11932
|
}
|
|
11966
11933
|
return calls.ordered.shift();
|
|
11967
11934
|
}
|
|
11968
|
-
function appDataRoot(appDirName, home =
|
|
11935
|
+
function appDataRoot(appDirName, home = os9.homedir()) {
|
|
11969
11936
|
if (process.platform === "darwin") {
|
|
11970
11937
|
return path19.join(home, "Library", "Application Support", appDirName);
|
|
11971
11938
|
}
|
|
@@ -12274,7 +12241,7 @@ async function parseQoderCnSessionFile(filePath, options) {
|
|
|
12274
12241
|
let cwd;
|
|
12275
12242
|
let project = projectContext.project;
|
|
12276
12243
|
let model;
|
|
12277
|
-
const home = path20.resolve(stringOption(options.home) ||
|
|
12244
|
+
const home = path20.resolve(stringOption(options.home) || os10.homedir());
|
|
12278
12245
|
const modelMap = await loadQoderCnModelNames(configDir2, home);
|
|
12279
12246
|
const isSubagentSession = filePath.includes("subagents");
|
|
12280
12247
|
const segmentModelCalls = await loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMap);
|
|
@@ -12844,7 +12811,7 @@ async function gitRootFromCwds2(cwds) {
|
|
|
12844
12811
|
while (!seen.has(current)) {
|
|
12845
12812
|
seen.add(current);
|
|
12846
12813
|
try {
|
|
12847
|
-
await
|
|
12814
|
+
await stat12(path20.join(current, ".git"));
|
|
12848
12815
|
return current;
|
|
12849
12816
|
} catch {
|
|
12850
12817
|
}
|
|
@@ -12878,7 +12845,7 @@ function encodeQoderCnProjectPath(value) {
|
|
|
12878
12845
|
}
|
|
12879
12846
|
async function qoderCnProjectFromFilePath(filePath, options) {
|
|
12880
12847
|
const projectDir = path20.basename(path20.dirname(filePath));
|
|
12881
|
-
const home = options ? path20.resolve(stringOption(options.home) ||
|
|
12848
|
+
const home = options ? path20.resolve(stringOption(options.home) || os10.homedir()) : os10.homedir();
|
|
12882
12849
|
const resolved = await resolveQoderCnProjectPath(projectDir, home);
|
|
12883
12850
|
if (resolved) {
|
|
12884
12851
|
return path20.basename(resolved);
|
|
@@ -12994,8 +12961,8 @@ function createQoderCnAdapter() {
|
|
|
12994
12961
|
|
|
12995
12962
|
// src/adapters/qoder.ts
|
|
12996
12963
|
import { existsSync } from "node:fs";
|
|
12997
|
-
import { readdir as readdir11, readFile as readFile13, stat as
|
|
12998
|
-
import
|
|
12964
|
+
import { readdir as readdir11, readFile as readFile13, stat as stat13 } from "node:fs/promises";
|
|
12965
|
+
import os11 from "node:os";
|
|
12999
12966
|
import path21 from "node:path";
|
|
13000
12967
|
function parseQoderPaths(filePath) {
|
|
13001
12968
|
const parts = filePath.split(path21.sep);
|
|
@@ -13160,7 +13127,7 @@ async function parseQoderSessionFile(filePath, options) {
|
|
|
13160
13127
|
let cwd;
|
|
13161
13128
|
let project = projectContext.project;
|
|
13162
13129
|
let model;
|
|
13163
|
-
const home = path21.resolve(stringOption(options.home) ||
|
|
13130
|
+
const home = path21.resolve(stringOption(options.home) || os11.homedir());
|
|
13164
13131
|
const modelMap = await loadQoderModelNames(configDir2, home);
|
|
13165
13132
|
const qwenworkRoot = isQwenworkConfigRoot(configDir2);
|
|
13166
13133
|
const isSubagentSession = filePath.includes("subagents");
|
|
@@ -13696,7 +13663,7 @@ async function gitRootFromCwds3(cwds) {
|
|
|
13696
13663
|
while (!seen.has(current)) {
|
|
13697
13664
|
seen.add(current);
|
|
13698
13665
|
try {
|
|
13699
|
-
await
|
|
13666
|
+
await stat13(path21.join(current, ".git"));
|
|
13700
13667
|
return current;
|
|
13701
13668
|
} catch {
|
|
13702
13669
|
}
|
|
@@ -13748,7 +13715,7 @@ function qoderEncodedProjectSuffix(projectDir, home) {
|
|
|
13748
13715
|
}
|
|
13749
13716
|
async function qoderProjectFromFilePath(filePath, options) {
|
|
13750
13717
|
const projectDir = path21.basename(path21.dirname(filePath));
|
|
13751
|
-
const home = options ? path21.resolve(stringOption(options.home) ||
|
|
13718
|
+
const home = options ? path21.resolve(stringOption(options.home) || os11.homedir()) : os11.homedir();
|
|
13752
13719
|
const resolved = await resolveQoderProjectPath(projectDir, home);
|
|
13753
13720
|
if (resolved) {
|
|
13754
13721
|
return path21.basename(resolved);
|
|
@@ -13900,11 +13867,14 @@ function normalizeId(id) {
|
|
|
13900
13867
|
if (id === "claude") {
|
|
13901
13868
|
return "claude-code";
|
|
13902
13869
|
}
|
|
13870
|
+
if (id === "grok-bot") {
|
|
13871
|
+
return "cursor";
|
|
13872
|
+
}
|
|
13903
13873
|
return id;
|
|
13904
13874
|
}
|
|
13905
13875
|
|
|
13906
13876
|
// src/adapters/workbuddy.ts
|
|
13907
|
-
import { readdir as readdir12, readFile as readFile14, stat as
|
|
13877
|
+
import { readdir as readdir12, readFile as readFile14, stat as stat14 } from "node:fs/promises";
|
|
13908
13878
|
import path22 from "node:path";
|
|
13909
13879
|
function workbuddyProjectsDir(home, env) {
|
|
13910
13880
|
const override = env?.WORKBUDDY_PROJECTS_DIR || env?.WORKBUDDY_HOME;
|
|
@@ -14357,7 +14327,7 @@ async function workbuddyBackfillFiles(sourceRoot, home, env) {
|
|
|
14357
14327
|
for (const entry of entries) {
|
|
14358
14328
|
if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
14359
14329
|
const filePath = path22.join(projectDir, entry.name);
|
|
14360
|
-
const info = await
|
|
14330
|
+
const info = await stat14(filePath);
|
|
14361
14331
|
files.push({ path: filePath, modifiedAt: info.mtime.toISOString() });
|
|
14362
14332
|
}
|
|
14363
14333
|
}
|
|
@@ -14418,7 +14388,7 @@ function createWorkbuddyAdapter() {
|
|
|
14418
14388
|
|
|
14419
14389
|
// src/adapters/zcode.ts
|
|
14420
14390
|
import { execFile } from "node:child_process";
|
|
14421
|
-
import { readFile as readFile15, stat as
|
|
14391
|
+
import { readFile as readFile15, stat as stat15 } from "node:fs/promises";
|
|
14422
14392
|
import path23 from "node:path";
|
|
14423
14393
|
import { promisify as promisify2 } from "node:util";
|
|
14424
14394
|
var execFileAsync = promisify2(execFile);
|
|
@@ -14457,7 +14427,7 @@ var providerNameCache = null;
|
|
|
14457
14427
|
async function loadProviderNames(configPath2) {
|
|
14458
14428
|
let fileMtime = 0;
|
|
14459
14429
|
try {
|
|
14460
|
-
const info = await
|
|
14430
|
+
const info = await stat15(configPath2);
|
|
14461
14431
|
fileMtime = info.mtimeMs;
|
|
14462
14432
|
} catch {
|
|
14463
14433
|
return /* @__PURE__ */ new Map();
|
|
@@ -14685,7 +14655,7 @@ async function parseZCodeDb(filePath, options) {
|
|
|
14685
14655
|
for (let i = 0; i < 12; i++) {
|
|
14686
14656
|
const probe = path23.join(candidate, ".zcode", "v2", "config.json");
|
|
14687
14657
|
try {
|
|
14688
|
-
await
|
|
14658
|
+
await stat15(probe);
|
|
14689
14659
|
configPath2 = probe;
|
|
14690
14660
|
break;
|
|
14691
14661
|
} catch {
|
|
@@ -14919,11 +14889,11 @@ async function zcodeBackfillFiles(sourceRoot, home, env) {
|
|
|
14919
14889
|
const candidate = sourceRoot || zcodeDbPath(home, env);
|
|
14920
14890
|
const filePath = candidate.endsWith(".sqlite") ? candidate : path23.join(candidate, "db", "db.sqlite");
|
|
14921
14891
|
try {
|
|
14922
|
-
const info = await
|
|
14892
|
+
const info = await stat15(filePath);
|
|
14923
14893
|
let modifiedMs = info.mtimeMs;
|
|
14924
14894
|
for (const suffix of ["-wal", "-shm"]) {
|
|
14925
14895
|
try {
|
|
14926
|
-
const sidecar = await
|
|
14896
|
+
const sidecar = await stat15(`${filePath}${suffix}`);
|
|
14927
14897
|
modifiedMs = Math.max(modifiedMs, sidecar.mtimeMs);
|
|
14928
14898
|
} catch {
|
|
14929
14899
|
}
|
|
@@ -14966,7 +14936,7 @@ function createZCodeAdapter() {
|
|
|
14966
14936
|
}
|
|
14967
14937
|
|
|
14968
14938
|
// src/adapters/zed.ts
|
|
14969
|
-
import
|
|
14939
|
+
import os12 from "node:os";
|
|
14970
14940
|
import path24 from "node:path";
|
|
14971
14941
|
function zedThreadsCandidates(home, env) {
|
|
14972
14942
|
const candidates = [];
|
|
@@ -15318,20 +15288,20 @@ async function parseZedSessionFile(dbPath, options) {
|
|
|
15318
15288
|
}
|
|
15319
15289
|
return events.filter((event) => matchesBackfillFilters(event, options));
|
|
15320
15290
|
}
|
|
15321
|
-
async function zedBackfillFiles(sourceRoot, home =
|
|
15322
|
-
const { stat:
|
|
15291
|
+
async function zedBackfillFiles(sourceRoot, home = os12.homedir(), env) {
|
|
15292
|
+
const { stat: stat18 } = await import("node:fs/promises");
|
|
15323
15293
|
if (sourceRoot) {
|
|
15324
15294
|
if (!sourceRoot.endsWith(".db")) {
|
|
15325
15295
|
return [];
|
|
15326
15296
|
}
|
|
15327
|
-
const info = await
|
|
15297
|
+
const info = await stat18(sourceRoot).catch(() => null);
|
|
15328
15298
|
if (!info) {
|
|
15329
15299
|
return [];
|
|
15330
15300
|
}
|
|
15331
15301
|
return [{ path: sourceRoot, modifiedAt: info.mtime.toISOString() }];
|
|
15332
15302
|
}
|
|
15333
15303
|
for (const candidatePath of zedThreadsCandidates(home, env)) {
|
|
15334
|
-
const info = await
|
|
15304
|
+
const info = await stat18(candidatePath).catch(() => null);
|
|
15335
15305
|
if (info) {
|
|
15336
15306
|
return [{ path: candidatePath, modifiedAt: info.mtime.toISOString() }];
|
|
15337
15307
|
}
|
|
@@ -16222,7 +16192,7 @@ function defaultMachineName() {
|
|
|
16222
16192
|
init_fs();
|
|
16223
16193
|
|
|
16224
16194
|
// src/lib/logger.ts
|
|
16225
|
-
import { appendFile, mkdir as mkdir5, rename as rename2, stat as
|
|
16195
|
+
import { appendFile, mkdir as mkdir5, rename as rename2, stat as stat16 } from "node:fs/promises";
|
|
16226
16196
|
import { homedir as homedir2 } from "node:os";
|
|
16227
16197
|
import path26 from "node:path";
|
|
16228
16198
|
var MAX_BYTES = 1 * 1024 * 1024;
|
|
@@ -16240,7 +16210,7 @@ function serializeError(error) {
|
|
|
16240
16210
|
}
|
|
16241
16211
|
async function rotateIfNeeded(file) {
|
|
16242
16212
|
try {
|
|
16243
|
-
const info = await
|
|
16213
|
+
const info = await stat16(file);
|
|
16244
16214
|
if (info.size > MAX_BYTES) {
|
|
16245
16215
|
await rename2(file, `${file}.1`).catch(() => {
|
|
16246
16216
|
});
|
|
@@ -16476,7 +16446,7 @@ async function deleteMachine(remote, id) {
|
|
|
16476
16446
|
}
|
|
16477
16447
|
|
|
16478
16448
|
// src/lib/types.ts
|
|
16479
|
-
var BACKFILL_STATE_SCHEMA_VERSION =
|
|
16449
|
+
var BACKFILL_STATE_SCHEMA_VERSION = 11;
|
|
16480
16450
|
|
|
16481
16451
|
// src/cli.ts
|
|
16482
16452
|
function createRegistry() {
|
|
@@ -16497,7 +16467,6 @@ function createRegistry() {
|
|
|
16497
16467
|
registry.register(createZedAdapter());
|
|
16498
16468
|
registry.register(createKimiCodeAdapter());
|
|
16499
16469
|
registry.register(createCursorAdapter());
|
|
16500
|
-
registry.register(createGrokBotAdapter());
|
|
16501
16470
|
registry.register(createHermesAdapter());
|
|
16502
16471
|
return registry;
|
|
16503
16472
|
}
|
|
@@ -17058,10 +17027,14 @@ async function listBackfillSourceFiles(source, options, ctx) {
|
|
|
17058
17027
|
return zedBackfillFiles(stringOption(options["source-root"]), resolveHome3(options, ctx), ctx.env);
|
|
17059
17028
|
}
|
|
17060
17029
|
if (source.id === "cursor") {
|
|
17061
|
-
|
|
17062
|
-
|
|
17063
|
-
|
|
17064
|
-
|
|
17030
|
+
const requested = normalizeBackfillSource(stringOption(options.source) || "all");
|
|
17031
|
+
const skipCursorCloud = requested === "all" && disabledBackfillSourceSet(readConfig(resolveHome3(options, ctx))).has("grok-bot");
|
|
17032
|
+
return cursorBackfillFiles(
|
|
17033
|
+
stringOption(options["source-root"]),
|
|
17034
|
+
resolveHome3(options, ctx),
|
|
17035
|
+
ctx.env,
|
|
17036
|
+
{ ...options, skipCursorCloud }
|
|
17037
|
+
);
|
|
17065
17038
|
}
|
|
17066
17039
|
if (source.id === "hermes") {
|
|
17067
17040
|
return hermesBackfillFiles(stringOption(options["source-root"]), resolveHome3(options, ctx), ctx.env);
|
|
@@ -17073,7 +17046,7 @@ async function listBackfillSourceFiles(source, options, ctx) {
|
|
|
17073
17046
|
const fileLists = await Promise.all(roots.map((r) => listJsonlFiles(r)));
|
|
17074
17047
|
const files = fileLists.flat().sort().slice(0, numberOption(options.limit) || void 0);
|
|
17075
17048
|
return Promise.all(files.map(async (filePath) => {
|
|
17076
|
-
const info = await
|
|
17049
|
+
const info = await stat17(filePath);
|
|
17077
17050
|
return { path: filePath, modifiedAt: info.mtime.toISOString() };
|
|
17078
17051
|
}));
|
|
17079
17052
|
}
|
|
@@ -17324,20 +17297,36 @@ async function sendSessionRollupBatch(rollups, options, ctx) {
|
|
|
17324
17297
|
machine,
|
|
17325
17298
|
allowHistoricalRewrite: options.force === true
|
|
17326
17299
|
});
|
|
17327
|
-
if (
|
|
17328
|
-
|
|
17329
|
-
for (const
|
|
17330
|
-
|
|
17331
|
-
|
|
17332
|
-
|
|
17333
|
-
|
|
17334
|
-
|
|
17335
|
-
|
|
17336
|
-
|
|
17300
|
+
if (result.conflicts === 0) {
|
|
17301
|
+
if (options.force) {
|
|
17302
|
+
for (const rollup of rollups) {
|
|
17303
|
+
for (const sessionId of rollup.supersededSessionIds ?? []) {
|
|
17304
|
+
try {
|
|
17305
|
+
await deleteRollupsBySource(remote, rollup.source, machine, {
|
|
17306
|
+
rollupKey: rollupKeyForSourceSession(rollup.source, sessionId),
|
|
17307
|
+
allowHistoricalRewrite: true
|
|
17308
|
+
});
|
|
17309
|
+
} catch (error) {
|
|
17310
|
+
debug(ctx, `Failed to delete superseded ${rollup.source} session ${sessionId}: ${error.message}
|
|
17337
17311
|
`);
|
|
17312
|
+
}
|
|
17338
17313
|
}
|
|
17339
17314
|
}
|
|
17340
17315
|
}
|
|
17316
|
+
for (const rollup of rollups) {
|
|
17317
|
+
if (rollup.source !== "cursor") {
|
|
17318
|
+
continue;
|
|
17319
|
+
}
|
|
17320
|
+
try {
|
|
17321
|
+
await deleteRollupsBySource(remote, "grok-bot", machine, {
|
|
17322
|
+
rollupKey: rollupKeyForSourceSession("grok-bot", rollup.sessionId),
|
|
17323
|
+
allowHistoricalRewrite: true
|
|
17324
|
+
});
|
|
17325
|
+
} catch (error) {
|
|
17326
|
+
debug(ctx, `Failed to delete grok-bot twin of cursor session ${rollup.sessionId}: ${error.message}
|
|
17327
|
+
`);
|
|
17328
|
+
}
|
|
17329
|
+
}
|
|
17341
17330
|
}
|
|
17342
17331
|
return result;
|
|
17343
17332
|
}
|
|
@@ -17625,7 +17614,7 @@ function syncLocalRunnerEntryArgs(cliPath) {
|
|
|
17625
17614
|
return [path27.resolve(path27.dirname(cliPath), "../bin/vibetime.mjs")];
|
|
17626
17615
|
}
|
|
17627
17616
|
function resolveHome3(options, ctx) {
|
|
17628
|
-
return path27.resolve(stringOption(options.home) || ctx.env.HOME ||
|
|
17617
|
+
return path27.resolve(stringOption(options.home) || ctx.env.HOME || os13.homedir());
|
|
17629
17618
|
}
|
|
17630
17619
|
function requestedTargets(options) {
|
|
17631
17620
|
const value = options.target || options.targets;
|
|
@@ -17635,7 +17624,13 @@ function requestedTargets(options) {
|
|
|
17635
17624
|
return valuesOption(value).flatMap((item) => item.split(",")).map((t) => t.trim()).filter(Boolean);
|
|
17636
17625
|
}
|
|
17637
17626
|
function normalizeBackfillSource(source) {
|
|
17638
|
-
|
|
17627
|
+
if (source === "claude") {
|
|
17628
|
+
return "claude-code";
|
|
17629
|
+
}
|
|
17630
|
+
if (source === "grok-bot") {
|
|
17631
|
+
return "cursor";
|
|
17632
|
+
}
|
|
17633
|
+
return source;
|
|
17639
17634
|
}
|
|
17640
17635
|
function requiredOption(options, name) {
|
|
17641
17636
|
const value = stringOption(options[name]);
|
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.75",
|
|
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": {
|