@vibe-cafe/vibe-usage 0.9.7 → 0.9.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/README.md +1 -1
- package/package.json +1 -1
- package/src/parsers/index.js +39 -6
- package/src/parsers/kiro.js +6 -1
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ npx @vibe-cafe/vibe-usage status # Show config & detected tools
|
|
|
63
63
|
| Amp | `~/.local/share/amp/threads/` |
|
|
64
64
|
| Droid | `~/.factory/sessions/` |
|
|
65
65
|
| Hermes | `~/.hermes/state.db` + `~/.hermes/profiles/<name>/state.db` (SQLite, multi-profile) |
|
|
66
|
-
| Kiro | Kiro CLI native event streams `~/.kiro/sessions/cli/*.jsonl` (estimated tokens from message text: input = prompt + tool results, output = reply + tool calls, reasoning = thinking, cacheRead = re-sent context; thinking-block signatures excluded). Falls back to `~/Library/Application Support/kiro-cli/data.sqlite3` / `~/.local/share/kiro-cli/data.sqlite3` + optional `~/.kiro_sessions/*.json` archives, then IDE `q-client.log` credit deltas as `kiro-credits
|
|
66
|
+
| Kiro | Kiro CLI native event streams `~/.kiro/sessions/cli/*.jsonl` (estimated tokens from message text: input = prompt + tool results, output = reply + tool calls, reasoning = thinking, cacheRead = re-sent context; thinking-block signatures excluded). Falls back to `~/Library/Application Support/kiro-cli/data.sqlite3` / `~/.local/share/kiro-cli/data.sqlite3` + optional `~/.kiro_sessions/*.json` archives, then IDE `q-client.log` whole-credit deltas as `kiro-credits` (floored cumulative diff — the server stores token counts as bigint); legacy IDE `dev_data/devdata.sqlite` token telemetry is opt-in with `VIBE_USAGE_KIRO_LEGACY_TOKENS=1` |
|
|
67
67
|
| Cline | `<host>/User/globalStorage/saoudrizwan.claude-dev/{state/taskHistory.json,tasks/<id>/ui_messages.json}` (walks all VSCode-fork hosts: Code, Cursor, Windsurf, VSCodium, Trae, ...) |
|
|
68
68
|
| Roo Code | `<host>/User/globalStorage/rooveterinaryinc.roo-cline/{tasks/_index.json,tasks/<id>/{history_item,ui_messages}.json}` (walks all VSCode-fork hosts) |
|
|
69
69
|
| Antigravity | `~/.gemini/antigravity/conversations/*.pb` to discover cascades, then reads token usage + sessions from the running language server via Connect RPC (process discovered with `ps`/`lsof` on macOS/Linux, PowerShell CIM with a `wmic` fallback on Windows) |
|
package/package.json
CHANGED
package/src/parsers/index.js
CHANGED
|
@@ -46,24 +46,43 @@ export function roundToHalfHour(date) {
|
|
|
46
46
|
return d;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// Server column limits (usage_buckets: model varchar(100), project varchar(200)).
|
|
50
|
+
// Anything longer aborts the whole INSERT chunk with 22001, so clamp here.
|
|
51
|
+
const MODEL_MAX_LENGTH = 100;
|
|
52
|
+
const PROJECT_MAX_LENGTH = 200;
|
|
53
|
+
|
|
54
|
+
// Server token columns are bigint — a single fractional/NaN value aborts the
|
|
55
|
+
// whole INSERT chunk with 22P02, taking every other tool's rows in the batch
|
|
56
|
+
// down with it.
|
|
57
|
+
function toTokenCount(value) {
|
|
58
|
+
const n = Number(value);
|
|
59
|
+
if (!Number.isFinite(n) || n <= 0) return 0;
|
|
60
|
+
return Math.round(n);
|
|
61
|
+
}
|
|
62
|
+
|
|
49
63
|
export function aggregateToBuckets(entries) {
|
|
50
64
|
const map = new Map();
|
|
51
65
|
|
|
52
66
|
for (const e of entries) {
|
|
67
|
+
const model = String(e.model || 'unknown').slice(0, MODEL_MAX_LENGTH);
|
|
68
|
+
const project = String(e.project || 'unknown').slice(0, PROJECT_MAX_LENGTH);
|
|
53
69
|
const bucketStart = roundToHalfHour(e.timestamp).toISOString();
|
|
54
|
-
const key = `${e.source}|${
|
|
70
|
+
const key = `${e.source}|${model}|${project}|${e.hostname || ''}|${bucketStart}`;
|
|
55
71
|
|
|
56
72
|
if (!map.has(key)) {
|
|
57
73
|
map.set(key, {
|
|
58
74
|
source: e.source,
|
|
59
|
-
model
|
|
60
|
-
project
|
|
75
|
+
model,
|
|
76
|
+
project,
|
|
77
|
+
// Cloud-sourced parsers (cursor) pre-set a fixed hostname sentinel; it
|
|
78
|
+
// must survive aggregation, or sync.js stamps the machine hostname and
|
|
79
|
+
// every machine gets its own duplicate row server-side.
|
|
80
|
+
...(e.hostname ? { hostname: e.hostname } : {}),
|
|
61
81
|
bucketStart,
|
|
62
82
|
inputTokens: 0,
|
|
63
83
|
outputTokens: 0,
|
|
64
84
|
cachedInputTokens: 0,
|
|
65
85
|
reasoningOutputTokens: 0,
|
|
66
|
-
totalTokens: 0,
|
|
67
86
|
});
|
|
68
87
|
}
|
|
69
88
|
|
|
@@ -72,10 +91,24 @@ export function aggregateToBuckets(entries) {
|
|
|
72
91
|
b.outputTokens += e.outputTokens || 0;
|
|
73
92
|
b.cachedInputTokens += e.cachedInputTokens || 0;
|
|
74
93
|
b.reasoningOutputTokens += e.reasoningOutputTokens || 0;
|
|
75
|
-
b.totalTokens += (e.inputTokens || 0) + (e.outputTokens || 0) + (e.reasoningOutputTokens || 0);
|
|
76
94
|
}
|
|
77
95
|
|
|
78
|
-
|
|
96
|
+
// Clamp after summation, not per entry — rounding each entry first would
|
|
97
|
+
// discard sub-integer values instead of letting them accumulate.
|
|
98
|
+
return Array.from(map.values()).map((b) => {
|
|
99
|
+
const inputTokens = toTokenCount(b.inputTokens);
|
|
100
|
+
const outputTokens = toTokenCount(b.outputTokens);
|
|
101
|
+
const cachedInputTokens = toTokenCount(b.cachedInputTokens);
|
|
102
|
+
const reasoningOutputTokens = toTokenCount(b.reasoningOutputTokens);
|
|
103
|
+
return {
|
|
104
|
+
...b,
|
|
105
|
+
inputTokens,
|
|
106
|
+
outputTokens,
|
|
107
|
+
cachedInputTokens,
|
|
108
|
+
reasoningOutputTokens,
|
|
109
|
+
totalTokens: inputTokens + outputTokens + reasoningOutputTokens,
|
|
110
|
+
};
|
|
111
|
+
});
|
|
79
112
|
}
|
|
80
113
|
|
|
81
114
|
/**
|
package/src/parsers/kiro.js
CHANGED
|
@@ -736,7 +736,12 @@ export function snapshotsToCreditEntries(snapshots) {
|
|
|
736
736
|
continue;
|
|
737
737
|
}
|
|
738
738
|
|
|
739
|
-
|
|
739
|
+
// The server's token columns are bigint, so fractional credit deltas
|
|
740
|
+
// cannot be uploaded as-is. Diff floored cumulative values instead of
|
|
741
|
+
// rounding each delta: the diffs telescope, so sub-integer usage is never
|
|
742
|
+
// lost or double-counted — it surfaces on whichever snapshot crosses the
|
|
743
|
+
// next whole-credit boundary.
|
|
744
|
+
const delta = Math.floor(snapshot.currentUsage) - Math.floor(prev.currentUsage);
|
|
740
745
|
if (delta > 0) {
|
|
741
746
|
entries.push({
|
|
742
747
|
source: 'kiro',
|