tokentracker-cli 0.5.69 → 0.5.71
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 +3 -2
- package/dashboard/dist/assets/{Card-ClNKd74W.js → Card-5ebScQbM.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-DiUhik_k.js → DashboardPage-B32RhUB1.js} +2 -2
- package/dashboard/dist/assets/{FadeIn-c2wFBL_u.js → FadeIn-CHjFUAEe.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-UPn-zQGB.js → IpCheckPage-CrbKufId.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-ZpuPopCf.js → LeaderboardPage-CVKBhGzY.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardProfilePage-C62TdxVy.js → LeaderboardProfilePage-CbpzxvLA.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-CQEaB_b2.js → LimitsPage-BwQ4isbM.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-8RdfHCcA.js → SettingsPage-Y3Znzs1i.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-DiKFOpFH.js → WidgetsPage-tNojCBaj.js} +1 -1
- package/dashboard/dist/assets/{download-BmThIfGZ.js → download-CQASvwEL.js} +1 -1
- package/dashboard/dist/assets/leaderboard-columns-DFG1TWe9.js +1 -0
- package/dashboard/dist/assets/{main-D49FUfq7.js → main-Cv6YpYdZ.js} +16 -15
- package/dashboard/dist/assets/{use-limits-display-prefs-BHo0gzBa.js → use-limits-display-prefs-BUrHqTkA.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-BGttWixw.js → use-usage-limits-D-gv2i1R.js} +1 -1
- package/dashboard/dist/brand-logos/kimi.svg +1 -0
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/commands/init.js +11 -0
- package/src/commands/status.js +9 -0
- package/src/commands/sync.js +26 -0
- package/src/lib/rollout.js +172 -0
- package/dashboard/dist/assets/leaderboard-columns-9wPbwNaz.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a}from"./main-
|
|
1
|
+
import{r as a}from"./main-Cv6YpYdZ.js";const d=["claude","codex","cursor","gemini","kiro","copilot","antigravity"],v={claude:"Claude",codex:"Codex",cursor:"Cursor",gemini:"Gemini",kiro:"Kiro",copilot:"GitHub Copilot",antigravity:"Antigravity"},k={claude:"/brand-logos/claude-code.svg",codex:"/brand-logos/codex.svg",cursor:"/brand-logos/cursor.svg",gemini:"/brand-logos/gemini.svg",kiro:"/brand-logos/kiro.svg",copilot:"/brand-logos/copilot.svg",antigravity:"/brand-logos/antigravity.svg"},l="tt.limits.providerOrder",g="tt.limits.providerVisibility";function y(){if(typeof window>"u")return[...d];try{const r=window.localStorage.getItem(l);if(!r)return[...d];const s=JSON.parse(r);if(!Array.isArray(s))return[...d];const n=s.filter(c=>d.includes(c));for(const c of d)n.includes(c)||n.push(c);return n}catch{return[...d]}}function m(){const r=Object.fromEntries(d.map(s=>[s,!0]));if(typeof window>"u")return r;try{const s=window.localStorage.getItem(g);if(!s)return r;const n=JSON.parse(s);if(!n||typeof n!="object")return r;const c={...r};for(const u of d)typeof n[u]=="boolean"&&(c[u]=n[u]);return c}catch{return r}}function C(){const[r,s]=a.useState(y),[n,c]=a.useState(m);a.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(l,JSON.stringify(r))}catch{}},[r]),a.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(g,JSON.stringify(n))}catch{}},[n]),a.useEffect(()=>{if(typeof window>"u")return;const o=t=>{t.key===l&&s(y()),t.key===g&&c(m())};return window.addEventListener("storage",o),()=>window.removeEventListener("storage",o)},[]);const u=a.useCallback(o=>{c(t=>({...t,[o]:!t[o]}))},[]),b=a.useCallback(o=>{s(t=>{const e=t.indexOf(o);if(e<=0)return t;const i=[...t];return[i[e-1],i[e]]=[i[e],i[e-1]],i})},[]),p=a.useCallback(o=>{s(t=>{const e=t.indexOf(o);if(e<0||e>=t.length-1)return t;const i=[...t];return[i[e],i[e+1]]=[i[e+1],i[e]],i})},[]),O=a.useCallback((o,t)=>{o!==t&&s(e=>{const i=e.indexOf(o),w=e.indexOf(t);if(i<0||w<0)return e;const f=[...e],[E]=f.splice(i,1);return f.splice(w,0,E),f})},[]),x=a.useCallback(()=>{s([...d]),c(Object.fromEntries(d.map(o=>[o,!0])))},[]),I=a.useMemo(()=>r.filter(o=>n[o]!==!1),[r,n]);return{order:r,visibility:n,visibleOrdered:I,toggle:u,moveUp:b,moveDown:p,moveToward:O,reset:x}}export{k as L,v as a,C as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,aM as l}from"./main-
|
|
1
|
+
import{r,aM as l}from"./main-Cv6YpYdZ.js";function y(i){const[o,a]=r.useState(null),[u,s]=r.useState(null),[c,f]=r.useState(!0),n=!!i?.initialRefresh,g=r.useCallback(async()=>{try{const e=await l({refresh:!0});a(e&&typeof e=="object"?e:null),s(null)}catch(e){s(e?.message||String(e))}},[]);return r.useEffect(()=>{let e=!1;return(async()=>{try{const t=await l(n?{refresh:!0}:{});if(e)return;a(t&&typeof t=="object"?t:null),s(null)}catch(t){if(e)return;s(t?.message||String(t))}finally{e||f(!1)}})(),()=>{e=!0}},[n]),{data:o,error:u,isLoading:c,refresh:g}}export{y as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Kimi</title><path d="M21.846 0a1.923 1.923 0 110 3.846H20.15a.226.226 0 01-.227-.226V1.923C19.923.861 20.784 0 21.846 0z"></path><path d="M11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z"></path></svg>
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
]
|
|
136
136
|
}
|
|
137
137
|
</script>
|
|
138
|
-
<script type="module" crossorigin src="/assets/main-
|
|
138
|
+
<script type="module" crossorigin src="/assets/main-Cv6YpYdZ.js"></script>
|
|
139
139
|
<link rel="stylesheet" crossorigin href="/assets/main-CNzfq4Ln.css">
|
|
140
140
|
</head>
|
|
141
141
|
<body>
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"description": "Shareable Token Tracker dashboard snapshot."
|
|
52
52
|
}
|
|
53
53
|
</script>
|
|
54
|
-
<script type="module" crossorigin src="/assets/main-
|
|
54
|
+
<script type="module" crossorigin src="/assets/main-Cv6YpYdZ.js"></script>
|
|
55
55
|
<link rel="stylesheet" crossorigin href="/assets/main-CNzfq4Ln.css">
|
|
56
56
|
</head>
|
|
57
57
|
<body>
|
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -404,6 +404,17 @@ async function applyIntegrationSetup({ home, trackerDir, notifyPath, notifyOrigi
|
|
|
404
404
|
summary.push({ label: "Cursor", status: "skipped", detail: "Not installed" });
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
+
// Kimi: passive reader — no hook installation needed.
|
|
408
|
+
// TokenTracker reads ~/.kimi/sessions/**/wire.jsonl directly.
|
|
409
|
+
{
|
|
410
|
+
const kimiHome = process.env.KIMI_HOME || path.join(home, ".kimi");
|
|
411
|
+
const kimiSessions = path.join(kimiHome, "sessions");
|
|
412
|
+
const fssync = require("node:fs");
|
|
413
|
+
if (fssync.existsSync(kimiSessions)) {
|
|
414
|
+
summary.push({ label: "Kimi Code", status: "detected", detail: "Passive reader (no hook needed)" });
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
407
418
|
const openclawBefore = await probeOpenclawSessionPluginState({
|
|
408
419
|
home,
|
|
409
420
|
trackerDir,
|
package/src/commands/status.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const os = require("node:os");
|
|
2
2
|
const path = require("node:path");
|
|
3
3
|
const fs = require("node:fs/promises");
|
|
4
|
+
const fssync = require("node:fs");
|
|
4
5
|
|
|
5
6
|
const { readJson } = require("../lib/fs");
|
|
6
7
|
const { readCodexNotify, readEveryCodeNotify } = require("../lib/codex-config");
|
|
@@ -19,6 +20,7 @@ const { collectTrackerDiagnostics } = require("../lib/diagnostics");
|
|
|
19
20
|
const { probeOpenclawHookState } = require("../lib/openclaw-hook");
|
|
20
21
|
const { probeOpenclawSessionPluginState } = require("../lib/openclaw-session-plugin");
|
|
21
22
|
const { resolveTrackerPaths } = require("../lib/tracker-paths");
|
|
23
|
+
const { resolveKimiWireFiles } = require("../lib/rollout");
|
|
22
24
|
|
|
23
25
|
async function cmdStatus(argv = []) {
|
|
24
26
|
const opts = parseArgs(argv);
|
|
@@ -112,6 +114,10 @@ async function cmdStatus(argv = []) {
|
|
|
112
114
|
const subscriptionLines =
|
|
113
115
|
subscriptions.length > 0 ? subscriptions.map(formatSubscriptionLine) : [];
|
|
114
116
|
|
|
117
|
+
const kimiWireFiles = resolveKimiWireFiles(process.env);
|
|
118
|
+
const kimiHome = process.env.KIMI_HOME || path.join(home, ".kimi");
|
|
119
|
+
const kimiInstalled = fssync.existsSync(path.join(kimiHome, "sessions"));
|
|
120
|
+
|
|
115
121
|
const copilotToken = readCopilotOauthToken({ home });
|
|
116
122
|
const copilotOtel = describeCopilotOtelStatus({ home, env: process.env });
|
|
117
123
|
const copilotLines = formatCopilotLines({ token: copilotToken, otel: copilotOtel });
|
|
@@ -138,6 +144,9 @@ async function cmdStatus(argv = []) {
|
|
|
138
144
|
`- Opencode plugin: ${opencodePluginConfigured ? "set" : "unset"}`,
|
|
139
145
|
`- OpenClaw session plugin: ${openclawSessionPluginState?.configured ? "set" : "unset"}`,
|
|
140
146
|
`- OpenClaw hook (legacy): ${openclawHookState?.configured ? "set" : "unset"}`,
|
|
147
|
+
kimiInstalled
|
|
148
|
+
? `- Kimi Code: passive reader (${kimiWireFiles.length} wire.jsonl file${kimiWireFiles.length !== 1 ? "s" : ""} found)`
|
|
149
|
+
: null,
|
|
141
150
|
...copilotLines,
|
|
142
151
|
...subscriptionLines,
|
|
143
152
|
"",
|
package/src/commands/sync.js
CHANGED
|
@@ -25,6 +25,8 @@ const {
|
|
|
25
25
|
parseKiroIncremental,
|
|
26
26
|
parseHermesIncremental,
|
|
27
27
|
parseCopilotIncremental,
|
|
28
|
+
resolveKimiWireFiles,
|
|
29
|
+
parseKimiIncremental,
|
|
28
30
|
} = require("../lib/rollout");
|
|
29
31
|
const { createProgress, renderBar, formatNumber, formatBytes } = require("../lib/progress");
|
|
30
32
|
const {
|
|
@@ -354,6 +356,28 @@ async function cmdSync(argv) {
|
|
|
354
356
|
});
|
|
355
357
|
}
|
|
356
358
|
|
|
359
|
+
// ── Kimi (passive wire.jsonl reader) ──
|
|
360
|
+
let kimiResult = { recordsProcessed: 0, eventsAggregated: 0, bucketsQueued: 0 };
|
|
361
|
+
const kimiWireFiles = resolveKimiWireFiles(process.env);
|
|
362
|
+
if (kimiWireFiles.length > 0) {
|
|
363
|
+
if (progress?.enabled) {
|
|
364
|
+
progress.start(`Parsing Kimi Code ${renderBar(0)} | buckets 0`);
|
|
365
|
+
}
|
|
366
|
+
kimiResult = await parseKimiIncremental({
|
|
367
|
+
wireFiles: kimiWireFiles,
|
|
368
|
+
cursors,
|
|
369
|
+
queuePath,
|
|
370
|
+
env: process.env,
|
|
371
|
+
onProgress: (p) => {
|
|
372
|
+
if (!progress?.enabled) return;
|
|
373
|
+
const pct = p.total > 0 ? p.index / p.total : 1;
|
|
374
|
+
progress.update(
|
|
375
|
+
`Parsing Kimi Code ${renderBar(pct)} ${formatNumber(p.index)}/${formatNumber(p.total)} files | buckets ${formatNumber(p.bucketsQueued)}`,
|
|
376
|
+
);
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
357
381
|
// ── GitHub Copilot CLI (OTEL JSONL files) ──
|
|
358
382
|
let copilotResult = { recordsProcessed: 0, eventsAggregated: 0, bucketsQueued: 0 };
|
|
359
383
|
const copilotPaths = resolveCopilotOtelPaths(process.env);
|
|
@@ -453,6 +477,7 @@ async function cmdSync(argv) {
|
|
|
453
477
|
cursorResult.recordsProcessed +
|
|
454
478
|
kiroResult.recordsProcessed +
|
|
455
479
|
hermesResult.recordsProcessed +
|
|
480
|
+
kimiResult.recordsProcessed +
|
|
456
481
|
copilotResult.recordsProcessed;
|
|
457
482
|
const totalBuckets =
|
|
458
483
|
parseResult.bucketsQueued +
|
|
@@ -463,6 +488,7 @@ async function cmdSync(argv) {
|
|
|
463
488
|
cursorResult.bucketsQueued +
|
|
464
489
|
kiroResult.bucketsQueued +
|
|
465
490
|
hermesResult.bucketsQueued +
|
|
491
|
+
kimiResult.bucketsQueued +
|
|
466
492
|
copilotResult.bucketsQueued;
|
|
467
493
|
process.stdout.write(
|
|
468
494
|
[
|
package/src/lib/rollout.js
CHANGED
|
@@ -2999,6 +2999,175 @@ async function parseHermesIncremental({ dbPath, cursors, queuePath, onProgress }
|
|
|
2999
2999
|
return { recordsProcessed: rows.length, eventsAggregated, bucketsQueued };
|
|
3000
3000
|
}
|
|
3001
3001
|
|
|
3002
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3003
|
+
// Kimi — passive JSONL reader (~/.kimi/sessions/**/wire.jsonl)
|
|
3004
|
+
// No hook installation needed; Kimi writes wire.jsonl automatically.
|
|
3005
|
+
|
|
3006
|
+
function resolveKimiDefaultModel(env = process.env) {
|
|
3007
|
+
const fallback = "kimi-for-coding";
|
|
3008
|
+
try {
|
|
3009
|
+
const home = env.HOME || require("node:os").homedir();
|
|
3010
|
+
const cfgPath = path.join(env.KIMI_HOME || path.join(home, ".kimi"), "config.toml");
|
|
3011
|
+
const raw = fssync.readFileSync(cfgPath, "utf8");
|
|
3012
|
+
const defaultMatch = raw.match(/^\s*default_model\s*=\s*"([^"]+)"/m);
|
|
3013
|
+
if (!defaultMatch) return fallback;
|
|
3014
|
+
const sectionKey = defaultMatch[1];
|
|
3015
|
+
const escaped = sectionKey.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3016
|
+
const sectionRe = new RegExp(
|
|
3017
|
+
`\\[models\\."${escaped}"\\]([\\s\\S]*?)(?:\\n\\[|$)`,
|
|
3018
|
+
);
|
|
3019
|
+
const section = raw.match(sectionRe);
|
|
3020
|
+
if (section) {
|
|
3021
|
+
const modelMatch = section[1].match(/^\s*model\s*=\s*"([^"]+)"/m);
|
|
3022
|
+
if (modelMatch && modelMatch[1]) return modelMatch[1];
|
|
3023
|
+
}
|
|
3024
|
+
if (sectionKey.includes("/")) return sectionKey.split("/").pop();
|
|
3025
|
+
return sectionKey || fallback;
|
|
3026
|
+
} catch {
|
|
3027
|
+
return fallback;
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3031
|
+
|
|
3032
|
+
function resolveKimiWireFiles(env = process.env) {
|
|
3033
|
+
const home = require("node:os").homedir();
|
|
3034
|
+
const kimiHome = env.KIMI_HOME || path.join(home, ".kimi");
|
|
3035
|
+
const sessionsDir = path.join(kimiHome, "sessions");
|
|
3036
|
+
if (!fssync.existsSync(sessionsDir)) return [];
|
|
3037
|
+
const files = [];
|
|
3038
|
+
try {
|
|
3039
|
+
for (const ws of fssync.readdirSync(sessionsDir)) {
|
|
3040
|
+
const wsDir = path.join(sessionsDir, ws);
|
|
3041
|
+
let wsStat;
|
|
3042
|
+
try { wsStat = fssync.statSync(wsDir); } catch { continue; }
|
|
3043
|
+
if (!wsStat.isDirectory()) continue;
|
|
3044
|
+
for (const sess of fssync.readdirSync(wsDir)) {
|
|
3045
|
+
const wireFile = path.join(wsDir, sess, "wire.jsonl");
|
|
3046
|
+
if (fssync.existsSync(wireFile)) files.push(wireFile);
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
} catch { /* ignore */ }
|
|
3050
|
+
return files;
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
async function parseKimiIncremental({ wireFiles, cursors, queuePath, onProgress, env, model } = {}) {
|
|
3054
|
+
await ensureDir(path.dirname(queuePath));
|
|
3055
|
+
const kimiState = cursors.kimi && typeof cursors.kimi === "object" ? cursors.kimi : {};
|
|
3056
|
+
const seenIds = new Set(Array.isArray(kimiState.seenIds) ? kimiState.seenIds : []);
|
|
3057
|
+
const fileOffsets =
|
|
3058
|
+
kimiState.fileOffsets && typeof kimiState.fileOffsets === "object"
|
|
3059
|
+
? { ...kimiState.fileOffsets }
|
|
3060
|
+
: {};
|
|
3061
|
+
|
|
3062
|
+
const files = Array.isArray(wireFiles)
|
|
3063
|
+
? wireFiles
|
|
3064
|
+
: resolveKimiWireFiles(env || process.env);
|
|
3065
|
+
const kimiModel = model || resolveKimiDefaultModel(env || process.env);
|
|
3066
|
+
if (files.length === 0) {
|
|
3067
|
+
cursors.kimi = { ...kimiState, seenIds: Array.from(seenIds), fileOffsets, updatedAt: new Date().toISOString() };
|
|
3068
|
+
return { recordsProcessed: 0, eventsAggregated: 0, bucketsQueued: 0 };
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
const hourlyState = normalizeHourlyState(cursors?.hourly);
|
|
3072
|
+
const touchedBuckets = new Set();
|
|
3073
|
+
const cb = typeof onProgress === "function" ? onProgress : null;
|
|
3074
|
+
let recordsProcessed = 0;
|
|
3075
|
+
let eventsAggregated = 0;
|
|
3076
|
+
|
|
3077
|
+
for (let fileIdx = 0; fileIdx < files.length; fileIdx++) {
|
|
3078
|
+
const filePath = files[fileIdx];
|
|
3079
|
+
let stat;
|
|
3080
|
+
try { stat = fssync.statSync(filePath); } catch { continue; }
|
|
3081
|
+
|
|
3082
|
+
const prevEntry = fileOffsets[filePath] || {};
|
|
3083
|
+
const prevSize = Number(prevEntry.size) || 0;
|
|
3084
|
+
const prevIno = prevEntry.ino;
|
|
3085
|
+
const inodeChanged = typeof prevIno === "number" && prevIno !== stat.ino;
|
|
3086
|
+
const startOffset = stat.size < prevSize || inodeChanged ? 0 : prevSize;
|
|
3087
|
+
if (stat.size <= startOffset) continue;
|
|
3088
|
+
|
|
3089
|
+
let stream;
|
|
3090
|
+
try {
|
|
3091
|
+
stream = fssync.createReadStream(filePath, { encoding: "utf8", start: startOffset });
|
|
3092
|
+
} catch { continue; }
|
|
3093
|
+
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
3094
|
+
|
|
3095
|
+
for await (const line of rl) {
|
|
3096
|
+
if (!line || !line.trim()) continue;
|
|
3097
|
+
let entry;
|
|
3098
|
+
try { entry = JSON.parse(line); } catch { continue; }
|
|
3099
|
+
|
|
3100
|
+
const msg = entry.message;
|
|
3101
|
+
if (!msg || msg.type !== "StatusUpdate") continue;
|
|
3102
|
+
|
|
3103
|
+
const payload = msg.payload;
|
|
3104
|
+
if (!payload) continue;
|
|
3105
|
+
const { token_usage, message_id } = payload;
|
|
3106
|
+
if (!token_usage || !message_id) continue;
|
|
3107
|
+
if (seenIds.has(message_id)) continue;
|
|
3108
|
+
|
|
3109
|
+
recordsProcessed++;
|
|
3110
|
+
|
|
3111
|
+
const input = toNonNegativeInt(token_usage.input_other);
|
|
3112
|
+
const output = toNonNegativeInt(token_usage.output);
|
|
3113
|
+
const cacheRead = toNonNegativeInt(token_usage.input_cache_read);
|
|
3114
|
+
const cacheCreation = toNonNegativeInt(token_usage.input_cache_creation);
|
|
3115
|
+
if (input === 0 && output === 0 && cacheRead === 0 && cacheCreation === 0) {
|
|
3116
|
+
seenIds.add(message_id);
|
|
3117
|
+
continue;
|
|
3118
|
+
}
|
|
3119
|
+
|
|
3120
|
+
const epochSec = entry.timestamp ?? payload.timestamp;
|
|
3121
|
+
if (epochSec == null || !Number.isFinite(Number(epochSec))) continue;
|
|
3122
|
+
const tsIso = new Date(Number(epochSec) * 1000).toISOString();
|
|
3123
|
+
const bucketStart = toUtcHalfHourStart(tsIso);
|
|
3124
|
+
if (!bucketStart) continue;
|
|
3125
|
+
|
|
3126
|
+
const delta = {
|
|
3127
|
+
input_tokens: input,
|
|
3128
|
+
cached_input_tokens: cacheRead,
|
|
3129
|
+
cache_creation_input_tokens: cacheCreation,
|
|
3130
|
+
output_tokens: output,
|
|
3131
|
+
reasoning_output_tokens: 0,
|
|
3132
|
+
total_tokens: input + output + cacheRead + cacheCreation,
|
|
3133
|
+
conversation_count: 1,
|
|
3134
|
+
};
|
|
3135
|
+
|
|
3136
|
+
const bucket = getHourlyBucket(hourlyState, "kimi", kimiModel, bucketStart);
|
|
3137
|
+
addTotals(bucket.totals, delta);
|
|
3138
|
+
touchedBuckets.add(bucketKey("kimi", kimiModel, bucketStart));
|
|
3139
|
+
seenIds.add(message_id);
|
|
3140
|
+
eventsAggregated++;
|
|
3141
|
+
|
|
3142
|
+
if (cb) {
|
|
3143
|
+
cb({
|
|
3144
|
+
index: fileIdx + 1,
|
|
3145
|
+
total: files.length,
|
|
3146
|
+
recordsProcessed,
|
|
3147
|
+
eventsAggregated,
|
|
3148
|
+
bucketsQueued: touchedBuckets.size,
|
|
3149
|
+
});
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
|
|
3153
|
+
let postStat = stat;
|
|
3154
|
+
try { postStat = fssync.statSync(filePath); } catch {}
|
|
3155
|
+
fileOffsets[filePath] = { size: postStat.size, mtimeMs: postStat.mtimeMs, ino: postStat.ino };
|
|
3156
|
+
}
|
|
3157
|
+
|
|
3158
|
+
// Cap seenIds to last 10k to bound cursor state size
|
|
3159
|
+
const seenArr = Array.from(seenIds);
|
|
3160
|
+
const cappedSeen = seenArr.length > 10_000 ? seenArr.slice(seenArr.length - 10_000) : seenArr;
|
|
3161
|
+
|
|
3162
|
+
const bucketsQueued = await enqueueTouchedBuckets({ queuePath, hourlyState, touchedBuckets });
|
|
3163
|
+
const updatedAt = new Date().toISOString();
|
|
3164
|
+
hourlyState.updatedAt = updatedAt;
|
|
3165
|
+
cursors.hourly = hourlyState;
|
|
3166
|
+
cursors.kimi = { ...kimiState, seenIds: cappedSeen, fileOffsets, updatedAt };
|
|
3167
|
+
|
|
3168
|
+
return { recordsProcessed, eventsAggregated, bucketsQueued };
|
|
3169
|
+
}
|
|
3170
|
+
|
|
3002
3171
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
3003
3172
|
// GitHub Copilot CLI — OpenTelemetry JSONL exporter
|
|
3004
3173
|
// User must opt in by setting:
|
|
@@ -3209,4 +3378,7 @@ module.exports = {
|
|
|
3209
3378
|
parseKiroIncremental,
|
|
3210
3379
|
parseHermesIncremental,
|
|
3211
3380
|
parseCopilotIncremental,
|
|
3381
|
+
resolveKimiWireFiles,
|
|
3382
|
+
resolveKimiDefaultModel,
|
|
3383
|
+
parseKimiIncremental,
|
|
3212
3384
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ad as l,D as n,az as i}from"./main-D49FUfq7.js";function y(r){let e=0;const o=String(r??"");for(let a=0;a<o.length;a+=1)e=Math.imul(31,e)+o.charCodeAt(a)|0;return Math.abs(e)%360}function m(r){const e=String(r??"").trim();if(!e)return"?";const o=e.split(/\s+/).filter(Boolean);if(o.length>=2){const a=o[0][0]||"",t=o[1][0]||"";return`${a}${t}`.toUpperCase()}return e.slice(0,2).toUpperCase()}const g={sm:"h-7 w-7 min-h-7 min-w-7 text-[10px]",md:"h-8 w-8 min-h-8 min-w-8 text-[11px]",lg:"h-14 w-14 min-h-14 min-w-14 text-base"};function h({avatarUrl:r,displayName:e,seed:o,size:a="md",className:t}){const d=g[a]||g.md,b=y(o??e??""),s=typeof r=="string"?r.trim():"",[p,c]=l.useState(!1);return l.useEffect(()=>{c(!1)},[s]),s&&!p?n.jsx("img",{src:s,alt:"",referrerPolicy:"no-referrer",onError:()=>c(!0),className:i("rounded-full object-cover ring-1 ring-white/10",d,t)}):n.jsx("div",{className:i("flex shrink-0 items-center justify-center rounded-full font-semibold text-white ring-1 ring-white/10",d,t),style:{backgroundColor:`hsl(${b} 42% 34%)`},"aria-hidden":!0,children:m(e)})}const u=new Set(["/brand-logos/cursor.svg","/brand-logos/kiro.svg","/brand-logos/copilot.svg"]);function w({iconSrc:r,label:e}){return n.jsxs("span",{className:"inline-flex items-center gap-3",children:[r?n.jsx("img",{src:r,alt:"",width:16,height:16,className:`h-4 w-4 shrink-0 object-contain opacity-90 ${u.has(r)?"dark:invert":""}`}):null,n.jsx("span",{className:"whitespace-nowrap",children:e})]})}const x=[{key:"gpt_tokens",copyKey:"leaderboard.column.codex",icon:"/brand-logos/codex.svg"},{key:"claude_tokens",copyKey:"leaderboard.column.claude",icon:"/brand-logos/claude-code.svg"},{key:"gemini_tokens",copyKey:"leaderboard.column.gemini",icon:"/brand-logos/gemini.svg"},{key:"cursor_tokens",copyKey:"leaderboard.column.cursor",icon:"/brand-logos/cursor.svg"},{key:"kiro_tokens",copyKey:"leaderboard.column.kiro",icon:"/brand-logos/kiro.svg"},{key:"copilot_tokens",copyKey:"leaderboard.column.copilot",icon:"/brand-logos/copilot.svg"},{key:"opencode_tokens",copyKey:"leaderboard.column.opencode",icon:"/brand-logos/opencode.svg"},{key:"openclaw_tokens",copyKey:"leaderboard.column.openclaw",icon:"/brand-logos/openclaw.svg"},{key:"hermes_tokens",copyKey:"leaderboard.column.hermes",icon:null},{key:"other_tokens",copyKey:"leaderboard.column.supplemental",icon:null}],f="sticky left-0 z-40 w-[72px] min-w-[72px] max-w-[72px] border-r border-oai-gray-200 dark:border-oai-gray-800 bg-white dark:bg-oai-gray-950 px-4 py-4 align-middle",_="sticky left-[72px] z-40 min-w-[140px] max-w-[min(180px,35vw)] border-r border-oai-gray-200 dark:border-oai-gray-800 bg-white dark:bg-oai-gray-950 px-4 py-4 align-middle",v="sticky left-[72px] z-40 min-w-[6rem] border-r border-oai-gray-200 dark:border-oai-gray-800 bg-white dark:bg-oai-gray-950 px-4 py-4";function K(r){return i("sticky left-0 z-30 w-[72px] min-w-[72px] max-w-[72px] border-r border-oai-gray-200 dark:border-oai-gray-800 px-4 py-4 whitespace-nowrap",r?"bg-oai-brand-50 dark:bg-emerald-950":"bg-white dark:bg-oai-gray-950 group-hover:bg-oai-gray-50 dark:group-hover:bg-oai-gray-900/60")}function T(r){return i("sticky left-[72px] z-30 min-w-[140px] max-w-[min(180px,35vw)] border-r border-oai-gray-200 dark:border-oai-gray-800 px-4 py-4 min-w-0",r?"bg-oai-brand-50 dark:bg-emerald-950":"bg-white dark:bg-oai-gray-950 group-hover:bg-oai-gray-50 dark:group-hover:bg-oai-gray-900/60")}function S(r){return i("sticky left-[72px] z-30 min-w-[6rem] border-r border-oai-gray-200 dark:border-oai-gray-800 px-4 py-4 whitespace-nowrap","bg-white dark:bg-oai-gray-950")}export{f as L,_ as a,x as b,T as c,w as d,h as e,S as f,v as g,K as l};
|