@yhong91/vibetime 0.1.30 → 0.1.31

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.
Files changed (2) hide show
  1. package/bin/vibetime.mjs +52 -6
  2. 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.30" : "0.1.1";
1931
+ var PACKAGE_VERSION = true ? "0.1.31" : "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;
@@ -4913,8 +4913,10 @@ async function parseCodexSessionFile(filePath, options) {
4913
4913
  let lastTurnIdForComplete;
4914
4914
  let turnIdAtLastUserMessage;
4915
4915
  let sessionMetaLocked = false;
4916
+ let forkedSession = false;
4916
4917
  let lastTotalTokenUsage;
4917
4918
  let lastPerCallUsageKey;
4919
+ let compactionPending = false;
4918
4920
  const pendingToolCalls = /* @__PURE__ */ new Map();
4919
4921
  for (const [index, line] of lines.entries()) {
4920
4922
  const lineNumber = index + 1;
@@ -4932,6 +4934,7 @@ async function parseCodexSessionFile(filePath, options) {
4932
4934
  }
4933
4935
  sessionMetaLocked = true;
4934
4936
  const forkedFromId = stringField(payload, "forked_from_id");
4937
+ forkedSession = Boolean(forkedFromId);
4935
4938
  const inherited = forkedFromId ? await readPersistedSessionContextFromOptions(options, forkedFromId) : void 0;
4936
4939
  sessionId = stringField(payload, "id") || sessionId;
4937
4940
  cwd = inherited?.cwd || stringField(payload, "cwd") || cwd;
@@ -4953,6 +4956,10 @@ async function parseCodexSessionFile(filePath, options) {
4953
4956
  sessionStartEmitted = true;
4954
4957
  continue;
4955
4958
  }
4959
+ if (topType === "compacted") {
4960
+ compactionPending = true;
4961
+ continue;
4962
+ }
4956
4963
  if (topType === "turn_context") {
4957
4964
  currentTurnId = stringField(payload, "turn_id") || currentTurnId;
4958
4965
  cwd = stringField(payload, "cwd") || cwd;
@@ -5080,12 +5087,32 @@ async function parseCodexSessionFile(filePath, options) {
5080
5087
  project,
5081
5088
  model: rewriteCodexModelForTier(model, serviceTier),
5082
5089
  confidence: "partial",
5083
- metrics: usage
5090
+ metrics: excludeForkInheritedCache(usage, forkedSession)
5084
5091
  }), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
5085
5092
  lastPerCallUsageKey = usageKey;
5086
5093
  }
5087
5094
  break;
5088
5095
  }
5096
+ if (compactionPending && lastTotalTokenUsage && total < lastTotalTokenUsage.total) {
5097
+ const lastUsage = lastTokenUsageFromPayload(payload);
5098
+ if (lastUsage) {
5099
+ events.push(withBackfillRefs(baseCodexEvent({
5100
+ ts,
5101
+ type: "model.usage",
5102
+ sessionId,
5103
+ turnId: currentTurnId,
5104
+ cwd,
5105
+ project,
5106
+ model: rewriteCodexModelForTier(model, serviceTier),
5107
+ confidence: "partial",
5108
+ metrics: excludeForkInheritedCache({ ...lastUsage, reasoningEffort }, forkedSession)
5109
+ }), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
5110
+ }
5111
+ lastTotalTokenUsage = { input, cached, output, reasoning, total };
5112
+ compactionPending = false;
5113
+ break;
5114
+ }
5115
+ compactionPending = false;
5089
5116
  if (lastTotalTokenUsage && total >= lastTotalTokenUsage.total) {
5090
5117
  const deltaInput = input - lastTotalTokenUsage.input;
5091
5118
  const deltaCached = cached - lastTotalTokenUsage.cached;
@@ -5102,7 +5129,7 @@ async function parseCodexSessionFile(filePath, options) {
5102
5129
  project,
5103
5130
  model: rewriteCodexModelForTier(model, serviceTier),
5104
5131
  confidence: "partial",
5105
- metrics: {
5132
+ metrics: excludeForkInheritedCache({
5106
5133
  tokensInput: deltaInput > 0 ? deltaInput : void 0,
5107
5134
  tokensCachedInput: deltaCached > 0 ? deltaCached : void 0,
5108
5135
  tokensOutput: deltaOutput > 0 ? deltaOutput : void 0,
@@ -5110,7 +5137,7 @@ async function parseCodexSessionFile(filePath, options) {
5110
5137
  tokensTotal: deltaTotal > 0 ? deltaTotal : void 0,
5111
5138
  modelContextWindow: usage.modelContextWindow,
5112
5139
  reasoningEffort
5113
- }
5140
+ }, forkedSession)
5114
5141
  }), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
5115
5142
  }
5116
5143
  } else {
@@ -5123,7 +5150,7 @@ async function parseCodexSessionFile(filePath, options) {
5123
5150
  project,
5124
5151
  model: rewriteCodexModelForTier(model, serviceTier),
5125
5152
  confidence: "partial",
5126
- metrics: {
5153
+ metrics: excludeForkInheritedCache({
5127
5154
  tokensInput: input,
5128
5155
  tokensCachedInput: cached,
5129
5156
  tokensOutput: output,
@@ -5131,7 +5158,7 @@ async function parseCodexSessionFile(filePath, options) {
5131
5158
  tokensTotal: total,
5132
5159
  modelContextWindow: usage.modelContextWindow,
5133
5160
  reasoningEffort
5134
- }
5161
+ }, forkedSession)
5135
5162
  }), { filePath, sourcePathHash, lineNumber, topType, payloadType, options }));
5136
5163
  }
5137
5164
  lastTotalTokenUsage = { input, cached, output, reasoning, total };
@@ -5389,6 +5416,13 @@ function tokenUsageFromPayload(payload) {
5389
5416
  const info = objectField(payload, "info");
5390
5417
  const totalUsage = objectField(info, "total_token_usage");
5391
5418
  const usage = Object.keys(totalUsage).length > 0 ? totalUsage : objectField(info, "last_token_usage");
5419
+ return tokenUsageFromRecord(usage, info);
5420
+ }
5421
+ function lastTokenUsageFromPayload(payload) {
5422
+ const info = objectField(payload, "info");
5423
+ return tokenUsageFromRecord(objectField(info, "last_token_usage"), info);
5424
+ }
5425
+ function tokenUsageFromRecord(usage, info) {
5392
5426
  if (Object.keys(usage).length === 0) {
5393
5427
  return;
5394
5428
  }
@@ -5410,6 +5444,18 @@ function tokenUsageFromPayload(payload) {
5410
5444
  modelContextWindow: numberField(info, "model_context_window")
5411
5445
  };
5412
5446
  }
5447
+ function excludeForkInheritedCache(usage, forked) {
5448
+ if (!forked || !usage) {
5449
+ return usage;
5450
+ }
5451
+ const cached = usage.tokensCachedInput ?? 0;
5452
+ return {
5453
+ ...usage,
5454
+ tokensInput: Math.max(0, (usage.tokensInput ?? 0) - cached) || void 0,
5455
+ tokensCachedInput: void 0,
5456
+ tokensTotal: Math.max(0, (usage.tokensTotal ?? 0) - cached) || void 0
5457
+ };
5458
+ }
5413
5459
  function toolNameFromPayload(payload, payloadType) {
5414
5460
  if (payloadType === "web_search_call") {
5415
5461
  return "web_search";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yhong91/vibetime",
3
3
  "type": "module",
4
- "version": "0.1.30",
4
+ "version": "0.1.31",
5
5
  "description": "vibetime CLI — install AI-agent hooks (Claude Code, Codex, OpenCode, Pi) and report activity to vibetime.",
6
6
  "license": "MIT",
7
7
  "publishConfig": {