@yhong91/vibetime 0.1.41 → 0.1.43
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 +72 -12
- package/package.json +1 -1
package/bin/vibetime.mjs
CHANGED
|
@@ -1928,7 +1928,7 @@ function countTextLines(text) {
|
|
|
1928
1928
|
}
|
|
1929
1929
|
|
|
1930
1930
|
// src/lib/constants.ts
|
|
1931
|
-
var PACKAGE_VERSION = true ? "0.1.
|
|
1931
|
+
var PACKAGE_VERSION = true ? "0.1.43" : "0.1.1";
|
|
1932
1932
|
var DEFAULT_API_URL = "http://121.196.224.82:3001";
|
|
1933
1933
|
var DEFAULT_BACKFILL_BATCH_SIZE = 50;
|
|
1934
1934
|
var DEFAULT_BACKFILL_BATCH_BYTES = 800 * 1024;
|
|
@@ -5815,6 +5815,18 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5815
5815
|
}
|
|
5816
5816
|
const msgTurnId = stringField(data, "turnId");
|
|
5817
5817
|
const turnId = msgTurnId !== void 0 ? `turn_${createStableHash([sessionId, msgTurnId]).slice(0, 24)}` : currentTurnId;
|
|
5818
|
+
events.push(baseCopilotEvent({
|
|
5819
|
+
ts,
|
|
5820
|
+
type: "agent.operation",
|
|
5821
|
+
operation: "model call",
|
|
5822
|
+
sessionId,
|
|
5823
|
+
turnId,
|
|
5824
|
+
cwd,
|
|
5825
|
+
project,
|
|
5826
|
+
model,
|
|
5827
|
+
confidence: "exact",
|
|
5828
|
+
metrics: { modelCalls: 1 }
|
|
5829
|
+
}));
|
|
5818
5830
|
const outputTokens = numberField(data, "outputTokens");
|
|
5819
5831
|
if (outputTokens && outputTokens > 0) {
|
|
5820
5832
|
const key = turnId || "unknown";
|
|
@@ -10751,6 +10763,8 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10751
10763
|
const toolRollups = /* @__PURE__ */ new Map();
|
|
10752
10764
|
const fileRollups = /* @__PURE__ */ new Map();
|
|
10753
10765
|
const turnRollups = /* @__PURE__ */ new Map();
|
|
10766
|
+
const turnTimings = /* @__PURE__ */ new Map();
|
|
10767
|
+
let activeTurnId;
|
|
10754
10768
|
let promptCount = 0;
|
|
10755
10769
|
let turnCount = 0;
|
|
10756
10770
|
let toolCallCount = 0;
|
|
@@ -10766,6 +10780,22 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10766
10780
|
let linesAdded = 0;
|
|
10767
10781
|
let linesRemoved = 0;
|
|
10768
10782
|
for (const event of ordered) {
|
|
10783
|
+
if (event.type === "turn.started" && event.turnId) {
|
|
10784
|
+
activeTurnId = event.turnId;
|
|
10785
|
+
const timing = turnTimings.get(event.turnId) || {};
|
|
10786
|
+
timing.taskStartedAt ??= event.ts;
|
|
10787
|
+
turnTimings.set(event.turnId, timing);
|
|
10788
|
+
}
|
|
10789
|
+
if (event.type === "model.usage" || (event.metrics?.modelCalls || 0) > 0) {
|
|
10790
|
+
const turnId = event.turnId || activeTurnId;
|
|
10791
|
+
if (turnId) {
|
|
10792
|
+
const timing = turnTimings.get(turnId) || {};
|
|
10793
|
+
if (!timing.lastCallAt || event.ts > timing.lastCallAt) {
|
|
10794
|
+
timing.lastCallAt = event.ts;
|
|
10795
|
+
}
|
|
10796
|
+
turnTimings.set(turnId, timing);
|
|
10797
|
+
}
|
|
10798
|
+
}
|
|
10769
10799
|
const eventInputTokens = Math.max(0, event.metrics?.tokensInput || 0);
|
|
10770
10800
|
const eventCachedInputTokens = Math.max(0, event.metrics?.tokensCachedInput || 0);
|
|
10771
10801
|
const eventCacheCreationInputTokens = Math.max(0, event.metrics?.tokensCacheCreationInput || 0);
|
|
@@ -10969,6 +10999,9 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10969
10999
|
fileRollups.set(pathHash, fileRollup);
|
|
10970
11000
|
}
|
|
10971
11001
|
timeBuckets.set(bucketTs, bucket);
|
|
11002
|
+
if (event.type === "turn.completed" && event.turnId === activeTurnId) {
|
|
11003
|
+
activeTurnId = void 0;
|
|
11004
|
+
}
|
|
10972
11005
|
}
|
|
10973
11006
|
const baseRollup = {
|
|
10974
11007
|
rollupKey,
|
|
@@ -10999,10 +11032,15 @@ function buildSessionRollup(rollupKey, events) {
|
|
|
10999
11032
|
modelRollups: [...modelRollups.values()].sort((a, b) => b.callCount - a.callCount || a.model.localeCompare(b.model)),
|
|
11000
11033
|
toolRollups: [...toolRollups.values()].sort((a, b) => b.callCount - a.callCount || a.tool.localeCompare(b.tool)),
|
|
11001
11034
|
fileRollups: [...fileRollups.values()].sort((a, b) => b.writes - a.writes || b.reads - a.reads || a.displayPath.localeCompare(b.displayPath)),
|
|
11002
|
-
turnRollups: [...turnRollups.values()].map((rollup) =>
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11035
|
+
turnRollups: [...turnRollups.values()].map((rollup) => {
|
|
11036
|
+
const timing = turnTimings.get(rollup.turnId);
|
|
11037
|
+
const startedAt2 = timing?.taskStartedAt || rollup.startedAt;
|
|
11038
|
+
return {
|
|
11039
|
+
...rollup,
|
|
11040
|
+
startedAt: startedAt2,
|
|
11041
|
+
durationMs: timing?.lastCallAt ? Math.max(0, Date.parse(timing.lastCallAt) - Date.parse(startedAt2)) : 0
|
|
11042
|
+
};
|
|
11043
|
+
}).sort((a, b) => a.startedAt.localeCompare(b.startedAt))
|
|
11006
11044
|
};
|
|
11007
11045
|
return {
|
|
11008
11046
|
...baseRollup,
|
|
@@ -11397,7 +11435,11 @@ async function postRollupBatch(remote, rollups, options = {}) {
|
|
|
11397
11435
|
const response = await remote.fetchImpl(joinUrl(remote.baseUrl, "/v3/agent/ingest"), {
|
|
11398
11436
|
method: "POST",
|
|
11399
11437
|
headers: buildHeaders(remote.token, options.machine),
|
|
11400
|
-
body: JSON.stringify({
|
|
11438
|
+
body: JSON.stringify({
|
|
11439
|
+
rollups,
|
|
11440
|
+
replace: options.replace !== false,
|
|
11441
|
+
allowHistoricalRewrite: options.allowHistoricalRewrite === true
|
|
11442
|
+
})
|
|
11401
11443
|
});
|
|
11402
11444
|
if (!response.ok) {
|
|
11403
11445
|
const body = await response.text();
|
|
@@ -11412,7 +11454,7 @@ async function postRollupBatch(remote, rollups, options = {}) {
|
|
|
11412
11454
|
};
|
|
11413
11455
|
}
|
|
11414
11456
|
async function deleteRollupsBySource(remote, source, machine, options = {}) {
|
|
11415
|
-
const query = `source=${encodeURIComponent(source)}${options.preserveTokens ? "&preserveTokens=1" : ""}`;
|
|
11457
|
+
const query = `source=${encodeURIComponent(source)}${options.preserveTokens ? "&preserveTokens=1" : ""}${options.allowHistoricalRewrite ? "&allowHistoricalRewrite=1" : ""}`;
|
|
11416
11458
|
const response = await remote.fetchImpl(
|
|
11417
11459
|
joinUrl(remote.baseUrl, `/v3/agent/sessions?${query}`),
|
|
11418
11460
|
{ method: "DELETE", headers: buildHeaders(remote.token, machine) }
|
|
@@ -11460,6 +11502,7 @@ async function deleteMachine(remote, id) {
|
|
|
11460
11502
|
var BACKFILL_STATE_SCHEMA_VERSION = 6;
|
|
11461
11503
|
|
|
11462
11504
|
// src/cli.ts
|
|
11505
|
+
var SESSION_REWRITE_DAYS = 7;
|
|
11463
11506
|
function createRegistry() {
|
|
11464
11507
|
const registry = new AdapterRegistry();
|
|
11465
11508
|
registry.register(createCodexAdapter());
|
|
@@ -11537,7 +11580,7 @@ function createCli(ctx, registry) {
|
|
|
11537
11580
|
cli.command("hook", "Read agent hook JSON from stdin and report a throttled event").option("--agent <name>", "Agent name").option("--project <name>", "Project name").option("--min-interval <seconds>", "Minimum seconds between similar hook reports").action((options) => hookCommand(normalizeOptions(options), ctx));
|
|
11538
11581
|
cli.command("sync-local-trigger", "Trigger one background local sync with throttle and locking").option("--min-interval <seconds>", "Minimum seconds between sync triggers").action((options) => syncLocalTriggerCommand(normalizeOptions(options), ctx, registry));
|
|
11539
11582
|
cli.command("sync-local-runner", "Internal background local sync runner").option("--lock-file <path>", "Lock file for the active sync").option("--state-file <path>", "State file for trigger metadata").action((options) => syncLocalRunnerCommand(normalizeOptions(options), ctx, registry));
|
|
11540
|
-
cli.command("backfill [action]", "Inspect local history import candidates").option("--source <source>", "Backfill source").option("--since <time>", "Only include history after this time").option("--until <time>", "Only include history before this time").option("--project <name>", "Project filter").option("--source-root <path>", "Override source history root").option("--include-source-path", "Include local source paths in output").option("--import-run <id>", "Import run id for verify/resume workflows").option("--limit <count>", "Maximum session files to parse").option("--batch-size <count>", "Max rollups per request (also bounded by --batch-bytes)").option("--batch-bytes <bytes>", "Soft byte cap for the JSON body of a single ingest POST").option("--replace", "Replace conflicting records during import (default)").option("--skip-conflicts", "Skip conflicting records instead of replacing them").option("--force", "Force
|
|
11583
|
+
cli.command("backfill [action]", "Inspect local history import candidates").option("--source <source>", "Backfill source").option("--since <time>", "Only include history after this time").option("--until <time>", "Only include history before this time").option("--project <name>", "Project filter").option("--source-root <path>", "Override source history root").option("--include-source-path", "Include local source paths in output").option("--import-run <id>", "Import run id for verify/resume workflows").option("--limit <count>", "Maximum session files to parse").option("--batch-size <count>", "Max rollups per request (also bounded by --batch-bytes)").option("--batch-bytes <bytes>", "Soft byte cap for the JSON body of a single ingest POST").option("--replace", "Replace conflicting records during import (default)").option("--skip-conflicts", "Skip conflicting records instead of replacing them").option("--force", "Force re-import of sessions active within the last 7 days").option("--purge-all", "With --force: unlock and replace history older than 7 days (DANGEROUS)").action((action, options) => backfillCommand({ ...normalizeOptions(options), action }, ctx, registry));
|
|
11541
11584
|
cli.command("token [action] [value]", "Set, show, or clear the persisted API token").option("--remote <url>", "Override API base URL when setting a token").action((action, value, options) => tokenCommand(action, value, normalizeOptions(options), ctx));
|
|
11542
11585
|
cli.command("machine [action]", "List or rename machines (requires login)").option("--name <name>", "New display name (used by `machine rename`)").option("--id <id>", "Machine id (defaults to current machine)").action((action, options) => machineCommand(action, normalizeOptions(options), ctx));
|
|
11543
11586
|
return cli;
|
|
@@ -11827,6 +11870,10 @@ async function backfillCommand(options, ctx, registry) {
|
|
|
11827
11870
|
if (action === "verify") {
|
|
11828
11871
|
return backfillVerifyCommand(options, ctx);
|
|
11829
11872
|
}
|
|
11873
|
+
if (options["purge-all"] && !options.force) {
|
|
11874
|
+
write(ctx.stderr, "--purge-all requires --force\n");
|
|
11875
|
+
return 1;
|
|
11876
|
+
}
|
|
11830
11877
|
if (action === "import" && !options["dry-run"]) {
|
|
11831
11878
|
const requested = normalizeBackfillSource(stringOption(options.source) || "all");
|
|
11832
11879
|
const supported = /* @__PURE__ */ new Set(["all", ...BACKFILL_SOURCE_IDS]);
|
|
@@ -12102,7 +12149,7 @@ async function importBackfillPlan(plan, options, ctx, registry) {
|
|
|
12102
12149
|
options,
|
|
12103
12150
|
ctx
|
|
12104
12151
|
);
|
|
12105
|
-
const rollups = buildSessionRollups(canonicalEvents);
|
|
12152
|
+
const rollups = selectRollupsForUpload(buildSessionRollups(canonicalEvents), options);
|
|
12106
12153
|
const counts = await uploadSessionRollups(rollups, canonicalEvents.length, options, ctx);
|
|
12107
12154
|
const result = {
|
|
12108
12155
|
importRunId: plan.importRun.importRunId,
|
|
@@ -12134,7 +12181,7 @@ async function purgeForcedSources(sourceDefs, home, remoteKey, options, ctx) {
|
|
|
12134
12181
|
try {
|
|
12135
12182
|
const deleted = await deleteSessionRollupsBySourceAPI(item.id, options, ctx, preserveTokens);
|
|
12136
12183
|
if (!options.json) {
|
|
12137
|
-
const suffix = preserveTokens ? " (token-bearing
|
|
12184
|
+
const suffix = preserveTokens ? " (token-bearing and sessions older than 7 days kept)" : "";
|
|
12138
12185
|
write(ctx.stdout, `purged ${item.id}: ${deleted} old rollups${suffix}
|
|
12139
12186
|
`);
|
|
12140
12187
|
}
|
|
@@ -12261,7 +12308,8 @@ async function sendSessionRollupBatch(rollups, options, ctx) {
|
|
|
12261
12308
|
};
|
|
12262
12309
|
const result = await postRollupBatch(remote, rollups, {
|
|
12263
12310
|
replace: options["skip-conflicts"] !== true,
|
|
12264
|
-
machine
|
|
12311
|
+
machine,
|
|
12312
|
+
allowHistoricalRewrite: options["purge-all"] === true
|
|
12265
12313
|
});
|
|
12266
12314
|
return result;
|
|
12267
12315
|
}
|
|
@@ -12275,7 +12323,17 @@ async function deleteSessionRollupsBySourceAPI(source, options, ctx, preserveTok
|
|
|
12275
12323
|
id: ensureLocalMachineId(home),
|
|
12276
12324
|
hostname: defaultMachineName(),
|
|
12277
12325
|
platform: process.platform
|
|
12278
|
-
}, {
|
|
12326
|
+
}, {
|
|
12327
|
+
preserveTokens,
|
|
12328
|
+
allowHistoricalRewrite: options["purge-all"] === true
|
|
12329
|
+
});
|
|
12330
|
+
}
|
|
12331
|
+
function selectRollupsForUpload(rollups, options, now = /* @__PURE__ */ new Date()) {
|
|
12332
|
+
if (!options.force || options["purge-all"]) {
|
|
12333
|
+
return rollups;
|
|
12334
|
+
}
|
|
12335
|
+
const cutoff = now.getTime() - SESSION_REWRITE_DAYS * 24 * 60 * 60 * 1e3;
|
|
12336
|
+
return rollups.filter((rollup) => Date.parse(rollup.lastEventAt) >= cutoff);
|
|
12279
12337
|
}
|
|
12280
12338
|
function shouldUseIncrementalBackfill(options) {
|
|
12281
12339
|
return !stringOption(options.since) && !stringOption(options.until) && !stringOption(options["source-root"]) && numberOption(options.limit) === void 0;
|
|
@@ -12767,8 +12825,10 @@ Environment:
|
|
|
12767
12825
|
`;
|
|
12768
12826
|
}
|
|
12769
12827
|
export {
|
|
12828
|
+
SESSION_REWRITE_DAYS,
|
|
12770
12829
|
run,
|
|
12771
12830
|
selectBackfillFilesForImport,
|
|
12831
|
+
selectRollupsForUpload,
|
|
12772
12832
|
syncLocalRunnerEntryArgs
|
|
12773
12833
|
};
|
|
12774
12834
|
const code = await run(process.argv.slice(2));process.exitCode = code;
|
package/package.json
CHANGED