ccusage 17.1.2 → 17.1.4
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/dist/{_types-CV6z8-9_.js → _types-Ds2jjKYK.js} +1 -1
- package/dist/{calculate-cost-CX9KwEZt.js → calculate-cost-BI5czHMM.js} +2 -2
- package/dist/calculate-cost.d.ts +1 -1
- package/dist/calculate-cost.js +2 -2
- package/dist/{data-loader-C5ZJmhZZ.js → data-loader-m6Bz_FZB.js} +333 -209
- package/dist/{data-loader-D_hlygEz.d.ts → data-loader-qw155z_a.d.ts} +2 -1
- package/dist/data-loader.d.ts +1 -1
- package/dist/data-loader.js +3 -3
- package/dist/{debug-6ElxqAsf.js → debug-DCs2jj0C.js} +4 -4
- package/dist/debug.js +4 -4
- package/dist/index.js +73 -117
- package/dist/{logger-DP1q6tgm.js → logger-_iZ9qzce.js} +8 -11
- package/dist/logger.js +1 -1
- package/dist/{prompt-BeRmYuGP.js → prompt-HWGZJndy.js} +30 -32
- package/package.json +1 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { logger } from "./logger-
|
|
1
|
+
import { A as object, C as boolean, F as string, M as parse$2, P as safeParse, R as union, S as array, _ as requestIdSchema, a as createDailyDate, b as versionSchema, c as createSessionId, f as isoTimestampSchema, g as projectPathSchema, h as monthlyDateSchema, i as createBucket, j as optional, k as number, l as createWeeklyDate, m as modelNameSchema, o as createMonthlyDate, p as messageIdSchema, r as activityDateSchema, s as createProjectPath, u as dailyDateSchema, v as sessionIdSchema, x as weeklyDateSchema, z as getTotalTokens } from "./_types-Ds2jjKYK.js";
|
|
2
|
+
import { n as logger } from "./logger-_iZ9qzce.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
+
import * as nativeFs from "node:fs";
|
|
5
|
+
import b, { createReadStream } from "node:fs";
|
|
4
6
|
import a, { readFile, stat } from "node:fs/promises";
|
|
5
7
|
import path, { basename, dirname, normalize, posix, relative, resolve, sep } from "node:path";
|
|
6
8
|
import process$1 from "node:process";
|
|
7
|
-
import
|
|
8
|
-
import b from "node:fs";
|
|
9
|
+
import { createInterface } from "node:readline";
|
|
9
10
|
import F, { homedir } from "node:os";
|
|
10
11
|
import { fileURLToPath } from "node:url";
|
|
11
12
|
var __create = Object.create;
|
|
@@ -239,7 +240,7 @@ var u = class {
|
|
|
239
240
|
this.path = t;
|
|
240
241
|
}
|
|
241
242
|
};
|
|
242
|
-
var f = class extends u {
|
|
243
|
+
var f$1 = class extends u {
|
|
243
244
|
static {
|
|
244
245
|
n(this, "Directory");
|
|
245
246
|
}
|
|
@@ -277,7 +278,7 @@ const w = n((s, t, r) => {
|
|
|
277
278
|
continue;
|
|
278
279
|
} else o = h;
|
|
279
280
|
}
|
|
280
|
-
typeof o == "string" ? i.push(new y(e, o)) : i.push(new f(e), ...w(o, e, r));
|
|
281
|
+
typeof o == "string" ? i.push(new y(e, o)) : i.push(new f$1(e), ...w(o, e, r));
|
|
281
282
|
}
|
|
282
283
|
return i;
|
|
283
284
|
}, "flattenFileTree");
|
|
@@ -295,7 +296,7 @@ n(async (s, t) => {
|
|
|
295
296
|
symlink: n((e, o) => new l(e, o), "symlink")
|
|
296
297
|
};
|
|
297
298
|
await Promise.all(w(s, i, p).map(async (e) => {
|
|
298
|
-
e instanceof f ? await a.mkdir(e.path, { recursive: !0 }) : e instanceof l ? (await a.mkdir(path.dirname(e.path), { recursive: !0 }), await a.symlink(e.target, e.path, e.type)) : e instanceof y && (await a.mkdir(path.dirname(e.path), { recursive: !0 }), await a.writeFile(e.path, e.content));
|
|
299
|
+
e instanceof f$1 ? await a.mkdir(e.path, { recursive: !0 }) : e instanceof l ? (await a.mkdir(path.dirname(e.path), { recursive: !0 }), await a.symlink(e.target, e.path, e.type)) : e instanceof y && (await a.mkdir(path.dirname(e.path), { recursive: !0 }), await a.writeFile(e.path, e.content));
|
|
299
300
|
}));
|
|
300
301
|
}
|
|
301
302
|
}
|
|
@@ -345,8 +346,7 @@ function normalizePath(path$1, options) {
|
|
|
345
346
|
if (resolvePaths) path$1 = resolve(path$1);
|
|
346
347
|
if (normalizePath$1 || pathNeedsCleaning) path$1 = cleanPath(path$1);
|
|
347
348
|
if (path$1 === ".") return "";
|
|
348
|
-
|
|
349
|
-
return convertSlashes(needsSeperator ? path$1 + pathSeparator : path$1, pathSeparator);
|
|
349
|
+
return convertSlashes(path$1[path$1.length - 1] !== pathSeparator ? path$1 + pathSeparator : path$1, pathSeparator);
|
|
350
350
|
}
|
|
351
351
|
function joinPathWithBasePath(filename, directoryPath) {
|
|
352
352
|
return directoryPath + filename;
|
|
@@ -825,12 +825,6 @@ var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
825
825
|
const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
|
|
826
826
|
const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
|
|
827
827
|
const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
|
|
828
|
-
const NO_DOT = `(?!${DOT_LITERAL})`;
|
|
829
|
-
const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
|
|
830
|
-
const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
|
|
831
|
-
const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
|
|
832
|
-
const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
|
|
833
|
-
const STAR = `${QMARK}*?`;
|
|
834
828
|
const POSIX_CHARS = {
|
|
835
829
|
DOT_LITERAL,
|
|
836
830
|
PLUS_LITERAL,
|
|
@@ -840,12 +834,12 @@ var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
840
834
|
QMARK,
|
|
841
835
|
END_ANCHOR,
|
|
842
836
|
DOTS_SLASH,
|
|
843
|
-
NO_DOT
|
|
844
|
-
NO_DOTS
|
|
845
|
-
NO_DOT_SLASH,
|
|
846
|
-
NO_DOTS_SLASH
|
|
847
|
-
QMARK_NO_DOT
|
|
848
|
-
STAR
|
|
837
|
+
NO_DOT: `(?!${DOT_LITERAL})`,
|
|
838
|
+
NO_DOTS: `(?!${START_ANCHOR}${DOTS_SLASH})`,
|
|
839
|
+
NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`,
|
|
840
|
+
NO_DOTS_SLASH: `(?!${DOTS_SLASH})`,
|
|
841
|
+
QMARK_NO_DOT: `[^.${SLASH_LITERAL}]`,
|
|
842
|
+
STAR: `${QMARK}*?`,
|
|
849
843
|
START_ANCHOR,
|
|
850
844
|
SEP: "/"
|
|
851
845
|
};
|
|
@@ -1006,9 +1000,7 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
1006
1000
|
return output;
|
|
1007
1001
|
};
|
|
1008
1002
|
exports.wrapOutput = (input, state = {}, options = {}) => {
|
|
1009
|
-
|
|
1010
|
-
const append = options.contains ? "" : "$";
|
|
1011
|
-
let output = `${prepend}(?:${input})${append}`;
|
|
1003
|
+
let output = `${options.contains ? "" : "^"}(?:${input})${options.contains ? "" : "$"}`;
|
|
1012
1004
|
if (state.negated === true) output = `(?:^(?!${output}).*$)`;
|
|
1013
1005
|
return output;
|
|
1014
1006
|
};
|
|
@@ -1322,13 +1314,13 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1322
1314
|
const capture = opts.capture ? "" : "?:";
|
|
1323
1315
|
const PLATFORM_CHARS = constants$1.globChars(opts.windows);
|
|
1324
1316
|
const EXTGLOB_CHARS = constants$1.extglobChars(PLATFORM_CHARS);
|
|
1325
|
-
const { DOT_LITERAL: DOT_LITERAL$1, PLUS_LITERAL: PLUS_LITERAL$1, SLASH_LITERAL: SLASH_LITERAL$1, ONE_CHAR: ONE_CHAR$1, DOTS_SLASH: DOTS_SLASH$1, NO_DOT
|
|
1317
|
+
const { DOT_LITERAL: DOT_LITERAL$1, PLUS_LITERAL: PLUS_LITERAL$1, SLASH_LITERAL: SLASH_LITERAL$1, ONE_CHAR: ONE_CHAR$1, DOTS_SLASH: DOTS_SLASH$1, NO_DOT, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK: QMARK$1, QMARK_NO_DOT, STAR, START_ANCHOR: START_ANCHOR$1 } = PLATFORM_CHARS;
|
|
1326
1318
|
const globstar = (opts$1) => {
|
|
1327
1319
|
return `(${capture}(?:(?!${START_ANCHOR$1}${opts$1.dot ? DOTS_SLASH$1 : DOT_LITERAL$1}).)*?)`;
|
|
1328
1320
|
};
|
|
1329
|
-
const nodot = opts.dot ? "" : NO_DOT
|
|
1330
|
-
const qmarkNoDot = opts.dot ? QMARK$1 : QMARK_NO_DOT
|
|
1331
|
-
let star = opts.bash === true ? globstar(opts) : STAR
|
|
1321
|
+
const nodot = opts.dot ? "" : NO_DOT;
|
|
1322
|
+
const qmarkNoDot = opts.dot ? QMARK$1 : QMARK_NO_DOT;
|
|
1323
|
+
let star = opts.bash === true ? globstar(opts) : STAR;
|
|
1332
1324
|
if (opts.capture) star = `(${star})`;
|
|
1333
1325
|
if (typeof opts.noext === "boolean") opts.noextglob = opts.noext;
|
|
1334
1326
|
const state = {
|
|
@@ -1525,8 +1517,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1525
1517
|
if (inner.includes(":")) {
|
|
1526
1518
|
const idx = prev.value.lastIndexOf("[");
|
|
1527
1519
|
const pre = prev.value.slice(0, idx);
|
|
1528
|
-
const
|
|
1529
|
-
const posix$1 = POSIX_REGEX_SOURCE[rest$1];
|
|
1520
|
+
const posix$1 = POSIX_REGEX_SOURCE[prev.value.slice(idx + 2)];
|
|
1530
1521
|
if (posix$1) {
|
|
1531
1522
|
prev.value = pre + posix$1;
|
|
1532
1523
|
state.backtrack = true;
|
|
@@ -1762,7 +1753,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1762
1753
|
push({
|
|
1763
1754
|
type: "qmark",
|
|
1764
1755
|
value,
|
|
1765
|
-
output: QMARK_NO_DOT
|
|
1756
|
+
output: QMARK_NO_DOT
|
|
1766
1757
|
});
|
|
1767
1758
|
continue;
|
|
1768
1759
|
}
|
|
@@ -1966,11 +1957,11 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1966
1957
|
}
|
|
1967
1958
|
if (state.index === state.start || prev.type === "slash" || prev.type === "dot") {
|
|
1968
1959
|
if (prev.type === "dot") {
|
|
1969
|
-
state.output += NO_DOT_SLASH
|
|
1970
|
-
prev.output += NO_DOT_SLASH
|
|
1960
|
+
state.output += NO_DOT_SLASH;
|
|
1961
|
+
prev.output += NO_DOT_SLASH;
|
|
1971
1962
|
} else if (opts.dot === true) {
|
|
1972
|
-
state.output += NO_DOTS_SLASH
|
|
1973
|
-
prev.output += NO_DOTS_SLASH
|
|
1963
|
+
state.output += NO_DOTS_SLASH;
|
|
1964
|
+
prev.output += NO_DOTS_SLASH;
|
|
1974
1965
|
} else {
|
|
1975
1966
|
state.output += nodot;
|
|
1976
1967
|
prev.output += nodot;
|
|
@@ -2017,15 +2008,15 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2017
2008
|
const len = input.length;
|
|
2018
2009
|
if (len > max) throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
|
|
2019
2010
|
input = REPLACEMENTS[input] || input;
|
|
2020
|
-
const { DOT_LITERAL: DOT_LITERAL$1, SLASH_LITERAL: SLASH_LITERAL$1, ONE_CHAR: ONE_CHAR$1, DOTS_SLASH: DOTS_SLASH$1, NO_DOT
|
|
2021
|
-
const nodot = opts.dot ? NO_DOTS
|
|
2022
|
-
const slashDot = opts.dot ? NO_DOTS_SLASH
|
|
2011
|
+
const { DOT_LITERAL: DOT_LITERAL$1, SLASH_LITERAL: SLASH_LITERAL$1, ONE_CHAR: ONE_CHAR$1, DOTS_SLASH: DOTS_SLASH$1, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR: START_ANCHOR$1 } = constants$1.globChars(opts.windows);
|
|
2012
|
+
const nodot = opts.dot ? NO_DOTS : NO_DOT;
|
|
2013
|
+
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
|
|
2023
2014
|
const capture = opts.capture ? "" : "?:";
|
|
2024
2015
|
const state = {
|
|
2025
2016
|
negated: false,
|
|
2026
2017
|
prefix: ""
|
|
2027
2018
|
};
|
|
2028
|
-
let star = opts.bash === true ? ".*?" : STAR
|
|
2019
|
+
let star = opts.bash === true ? ".*?" : STAR;
|
|
2029
2020
|
if (opts.capture) star = `(${star})`;
|
|
2030
2021
|
const globstar = (opts$1) => {
|
|
2031
2022
|
if (opts$1.noglobstar === true) return star;
|
|
@@ -2050,8 +2041,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2050
2041
|
}
|
|
2051
2042
|
}
|
|
2052
2043
|
};
|
|
2053
|
-
|
|
2054
|
-
let source = create(output);
|
|
2044
|
+
let source = create(utils$2.removePrefix(input, state));
|
|
2055
2045
|
if (source && opts.strictSlashes !== true) source += `${SLASH_LITERAL$1}?`;
|
|
2056
2046
|
return source;
|
|
2057
2047
|
};
|
|
@@ -2463,8 +2453,7 @@ async function glob(patternsOrOptions, options) {
|
|
|
2463
2453
|
if (patternsOrOptions && (options === null || options === void 0 ? void 0 : options.patterns)) throw new Error("Cannot pass patterns as both an argument and an option");
|
|
2464
2454
|
const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string";
|
|
2465
2455
|
const opts = isModern ? options : patternsOrOptions;
|
|
2466
|
-
const
|
|
2467
|
-
const [crawler, relative$1] = getCrawler(patterns, opts);
|
|
2456
|
+
const [crawler, relative$1] = getCrawler(isModern ? patternsOrOptions : patternsOrOptions.patterns, opts);
|
|
2468
2457
|
if (!relative$1) return crawler.withPromise();
|
|
2469
2458
|
return formatPaths(await crawler.withPromise(), relative$1);
|
|
2470
2459
|
}
|
|
@@ -2528,11 +2517,10 @@ var unpackObjectSorter = function(sortByObj) {
|
|
|
2528
2517
|
var sortBy = asc || desc;
|
|
2529
2518
|
throwInvalidConfigErrorIfTrue(!sortBy, "Expected `asc` or `desc` property");
|
|
2530
2519
|
throwInvalidConfigErrorIfTrue(asc && desc, "Ambiguous object with `asc` and `desc` config properties");
|
|
2531
|
-
var comparer = sortByObj.comparer && castComparer(sortByObj.comparer);
|
|
2532
2520
|
return {
|
|
2533
2521
|
order,
|
|
2534
2522
|
sortBy,
|
|
2535
|
-
comparer
|
|
2523
|
+
comparer: sortByObj.comparer && castComparer(sortByObj.comparer)
|
|
2536
2524
|
};
|
|
2537
2525
|
};
|
|
2538
2526
|
var multiPropertySorterProvider = function(defaultComparer$1) {
|
|
@@ -2698,10 +2686,7 @@ function formatDate(dateStr, timezone, locale) {
|
|
|
2698
2686
|
function formatDateCompact(dateStr, timezone, locale) {
|
|
2699
2687
|
const date = safeParse(dailyDateSchema, dateStr).success ? timezone != null ? /* @__PURE__ */ new Date(`${dateStr}T00:00:00Z`) : /* @__PURE__ */ new Date(`${dateStr}T00:00:00`) : new Date(dateStr);
|
|
2700
2688
|
const parts = createDatePartsFormatter(timezone, locale).formatToParts(date);
|
|
2701
|
-
|
|
2702
|
-
const month = parts.find((p) => p.type === "month")?.value ?? "";
|
|
2703
|
-
const day = parts.find((p) => p.type === "day")?.value ?? "";
|
|
2704
|
-
return `${year}\n${month}-${day}`;
|
|
2689
|
+
return `${parts.find((p) => p.type === "year")?.value ?? ""}\n${parts.find((p) => p.type === "month")?.value ?? ""}-${parts.find((p) => p.type === "day")?.value ?? ""}`;
|
|
2705
2690
|
}
|
|
2706
2691
|
function sortByDate(items, getDate, order = "desc") {
|
|
2707
2692
|
const sorted = sort(items);
|
|
@@ -2891,40 +2876,6 @@ var LiteLLMPricingFetcher = class {
|
|
|
2891
2876
|
}));
|
|
2892
2877
|
}
|
|
2893
2878
|
};
|
|
2894
|
-
function createPricingDataset() {
|
|
2895
|
-
return Object.create(null);
|
|
2896
|
-
}
|
|
2897
|
-
async function fetchLiteLLMPricingDataset() {
|
|
2898
|
-
const response = await fetch(LITELLM_PRICING_URL);
|
|
2899
|
-
if (!response.ok) throw new Error(`Failed to fetch pricing data: ${response.status} ${response.statusText}`);
|
|
2900
|
-
const rawDataset = await response.json();
|
|
2901
|
-
const dataset = createPricingDataset();
|
|
2902
|
-
for (const [modelName, modelData] of Object.entries(rawDataset)) {
|
|
2903
|
-
if (modelData == null || typeof modelData !== "object") continue;
|
|
2904
|
-
const parsed = safeParse(liteLLMModelPricingSchema, modelData);
|
|
2905
|
-
if (!parsed.success) continue;
|
|
2906
|
-
dataset[modelName] = parsed.output;
|
|
2907
|
-
}
|
|
2908
|
-
return dataset;
|
|
2909
|
-
}
|
|
2910
|
-
function filterPricingDataset(dataset, predicate) {
|
|
2911
|
-
const filtered = createPricingDataset();
|
|
2912
|
-
for (const [modelName, pricing] of Object.entries(dataset)) if (predicate(modelName, pricing)) filtered[modelName] = pricing;
|
|
2913
|
-
return filtered;
|
|
2914
|
-
}
|
|
2915
|
-
function isClaudeModel(modelName, _pricing) {
|
|
2916
|
-
return modelName.startsWith("claude-");
|
|
2917
|
-
}
|
|
2918
|
-
async function prefetchClaudePricing() {
|
|
2919
|
-
if (process$1.env.OFFLINE === "true") return createPricingDataset();
|
|
2920
|
-
try {
|
|
2921
|
-
const dataset = await fetchLiteLLMPricingDataset();
|
|
2922
|
-
return filterPricingDataset(dataset, isClaudeModel);
|
|
2923
|
-
} catch (error) {
|
|
2924
|
-
console.warn("Failed to prefetch Claude pricing data, proceeding with empty cache.", error);
|
|
2925
|
-
return createPricingDataset();
|
|
2926
|
-
}
|
|
2927
|
-
}
|
|
2928
2879
|
const CLAUDE_PROVIDER_PREFIXES = [
|
|
2929
2880
|
"anthropic/",
|
|
2930
2881
|
"claude-3-5-",
|
|
@@ -2932,7 +2883,204 @@ const CLAUDE_PROVIDER_PREFIXES = [
|
|
|
2932
2883
|
"claude-",
|
|
2933
2884
|
"openrouter/openai/"
|
|
2934
2885
|
];
|
|
2935
|
-
const PREFETCHED_CLAUDE_PRICING =
|
|
2886
|
+
const PREFETCHED_CLAUDE_PRICING = {
|
|
2887
|
+
"claude-3-5-haiku-20241022": {
|
|
2888
|
+
"input_cost_per_token": 8e-7,
|
|
2889
|
+
"output_cost_per_token": 4e-6,
|
|
2890
|
+
"cache_creation_input_token_cost": 1e-6,
|
|
2891
|
+
"cache_read_input_token_cost": 8e-8,
|
|
2892
|
+
"max_tokens": 8192,
|
|
2893
|
+
"max_input_tokens": 2e5,
|
|
2894
|
+
"max_output_tokens": 8192
|
|
2895
|
+
},
|
|
2896
|
+
"claude-3-5-haiku-latest": {
|
|
2897
|
+
"input_cost_per_token": 1e-6,
|
|
2898
|
+
"output_cost_per_token": 5e-6,
|
|
2899
|
+
"cache_creation_input_token_cost": 125e-8,
|
|
2900
|
+
"cache_read_input_token_cost": 1e-7,
|
|
2901
|
+
"max_tokens": 8192,
|
|
2902
|
+
"max_input_tokens": 2e5,
|
|
2903
|
+
"max_output_tokens": 8192
|
|
2904
|
+
},
|
|
2905
|
+
"claude-haiku-4-5-20251001": {
|
|
2906
|
+
"input_cost_per_token": 1e-6,
|
|
2907
|
+
"output_cost_per_token": 5e-6,
|
|
2908
|
+
"cache_creation_input_token_cost": 125e-8,
|
|
2909
|
+
"cache_read_input_token_cost": 1e-7,
|
|
2910
|
+
"max_tokens": 64e3,
|
|
2911
|
+
"max_input_tokens": 2e5,
|
|
2912
|
+
"max_output_tokens": 64e3
|
|
2913
|
+
},
|
|
2914
|
+
"claude-haiku-4-5": {
|
|
2915
|
+
"input_cost_per_token": 1e-6,
|
|
2916
|
+
"output_cost_per_token": 5e-6,
|
|
2917
|
+
"cache_creation_input_token_cost": 125e-8,
|
|
2918
|
+
"cache_read_input_token_cost": 1e-7,
|
|
2919
|
+
"max_tokens": 64e3,
|
|
2920
|
+
"max_input_tokens": 2e5,
|
|
2921
|
+
"max_output_tokens": 64e3
|
|
2922
|
+
},
|
|
2923
|
+
"claude-3-5-sonnet-20240620": {
|
|
2924
|
+
"input_cost_per_token": 3e-6,
|
|
2925
|
+
"output_cost_per_token": 15e-6,
|
|
2926
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
2927
|
+
"cache_read_input_token_cost": 3e-7,
|
|
2928
|
+
"max_tokens": 8192,
|
|
2929
|
+
"max_input_tokens": 2e5,
|
|
2930
|
+
"max_output_tokens": 8192
|
|
2931
|
+
},
|
|
2932
|
+
"claude-3-5-sonnet-20241022": {
|
|
2933
|
+
"input_cost_per_token": 3e-6,
|
|
2934
|
+
"output_cost_per_token": 15e-6,
|
|
2935
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
2936
|
+
"cache_read_input_token_cost": 3e-7,
|
|
2937
|
+
"max_tokens": 8192,
|
|
2938
|
+
"max_input_tokens": 2e5,
|
|
2939
|
+
"max_output_tokens": 8192
|
|
2940
|
+
},
|
|
2941
|
+
"claude-3-5-sonnet-latest": {
|
|
2942
|
+
"input_cost_per_token": 3e-6,
|
|
2943
|
+
"output_cost_per_token": 15e-6,
|
|
2944
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
2945
|
+
"cache_read_input_token_cost": 3e-7,
|
|
2946
|
+
"max_tokens": 8192,
|
|
2947
|
+
"max_input_tokens": 2e5,
|
|
2948
|
+
"max_output_tokens": 8192
|
|
2949
|
+
},
|
|
2950
|
+
"claude-3-7-sonnet-20250219": {
|
|
2951
|
+
"input_cost_per_token": 3e-6,
|
|
2952
|
+
"output_cost_per_token": 15e-6,
|
|
2953
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
2954
|
+
"cache_read_input_token_cost": 3e-7,
|
|
2955
|
+
"max_tokens": 128e3,
|
|
2956
|
+
"max_input_tokens": 2e5,
|
|
2957
|
+
"max_output_tokens": 128e3
|
|
2958
|
+
},
|
|
2959
|
+
"claude-3-7-sonnet-latest": {
|
|
2960
|
+
"input_cost_per_token": 3e-6,
|
|
2961
|
+
"output_cost_per_token": 15e-6,
|
|
2962
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
2963
|
+
"cache_read_input_token_cost": 3e-7,
|
|
2964
|
+
"max_tokens": 128e3,
|
|
2965
|
+
"max_input_tokens": 2e5,
|
|
2966
|
+
"max_output_tokens": 128e3
|
|
2967
|
+
},
|
|
2968
|
+
"claude-3-haiku-20240307": {
|
|
2969
|
+
"input_cost_per_token": 25e-8,
|
|
2970
|
+
"output_cost_per_token": 125e-8,
|
|
2971
|
+
"cache_creation_input_token_cost": 3e-7,
|
|
2972
|
+
"cache_read_input_token_cost": 3e-8,
|
|
2973
|
+
"max_tokens": 4096,
|
|
2974
|
+
"max_input_tokens": 2e5,
|
|
2975
|
+
"max_output_tokens": 4096
|
|
2976
|
+
},
|
|
2977
|
+
"claude-3-opus-20240229": {
|
|
2978
|
+
"input_cost_per_token": 15e-6,
|
|
2979
|
+
"output_cost_per_token": 75e-6,
|
|
2980
|
+
"cache_creation_input_token_cost": 1875e-8,
|
|
2981
|
+
"cache_read_input_token_cost": 15e-7,
|
|
2982
|
+
"max_tokens": 4096,
|
|
2983
|
+
"max_input_tokens": 2e5,
|
|
2984
|
+
"max_output_tokens": 4096
|
|
2985
|
+
},
|
|
2986
|
+
"claude-3-opus-latest": {
|
|
2987
|
+
"input_cost_per_token": 15e-6,
|
|
2988
|
+
"output_cost_per_token": 75e-6,
|
|
2989
|
+
"cache_creation_input_token_cost": 1875e-8,
|
|
2990
|
+
"cache_read_input_token_cost": 15e-7,
|
|
2991
|
+
"max_tokens": 4096,
|
|
2992
|
+
"max_input_tokens": 2e5,
|
|
2993
|
+
"max_output_tokens": 4096
|
|
2994
|
+
},
|
|
2995
|
+
"claude-4-opus-20250514": {
|
|
2996
|
+
"input_cost_per_token": 15e-6,
|
|
2997
|
+
"output_cost_per_token": 75e-6,
|
|
2998
|
+
"cache_creation_input_token_cost": 1875e-8,
|
|
2999
|
+
"cache_read_input_token_cost": 15e-7,
|
|
3000
|
+
"max_tokens": 32e3,
|
|
3001
|
+
"max_input_tokens": 2e5,
|
|
3002
|
+
"max_output_tokens": 32e3
|
|
3003
|
+
},
|
|
3004
|
+
"claude-4-sonnet-20250514": {
|
|
3005
|
+
"input_cost_per_token": 3e-6,
|
|
3006
|
+
"output_cost_per_token": 15e-6,
|
|
3007
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
3008
|
+
"cache_read_input_token_cost": 3e-7,
|
|
3009
|
+
"max_tokens": 1e6,
|
|
3010
|
+
"max_input_tokens": 1e6,
|
|
3011
|
+
"max_output_tokens": 64e3,
|
|
3012
|
+
"input_cost_per_token_above_200k_tokens": 6e-6,
|
|
3013
|
+
"output_cost_per_token_above_200k_tokens": 225e-7,
|
|
3014
|
+
"cache_creation_input_token_cost_above_200k_tokens": 75e-7,
|
|
3015
|
+
"cache_read_input_token_cost_above_200k_tokens": 6e-7
|
|
3016
|
+
},
|
|
3017
|
+
"claude-sonnet-4-5": {
|
|
3018
|
+
"input_cost_per_token": 3e-6,
|
|
3019
|
+
"output_cost_per_token": 15e-6,
|
|
3020
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
3021
|
+
"cache_read_input_token_cost": 3e-7,
|
|
3022
|
+
"max_tokens": 64e3,
|
|
3023
|
+
"max_input_tokens": 2e5,
|
|
3024
|
+
"max_output_tokens": 64e3,
|
|
3025
|
+
"input_cost_per_token_above_200k_tokens": 6e-6,
|
|
3026
|
+
"output_cost_per_token_above_200k_tokens": 225e-7,
|
|
3027
|
+
"cache_creation_input_token_cost_above_200k_tokens": 75e-7,
|
|
3028
|
+
"cache_read_input_token_cost_above_200k_tokens": 6e-7
|
|
3029
|
+
},
|
|
3030
|
+
"claude-sonnet-4-5-20250929": {
|
|
3031
|
+
"input_cost_per_token": 3e-6,
|
|
3032
|
+
"output_cost_per_token": 15e-6,
|
|
3033
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
3034
|
+
"cache_read_input_token_cost": 3e-7,
|
|
3035
|
+
"max_tokens": 64e3,
|
|
3036
|
+
"max_input_tokens": 2e5,
|
|
3037
|
+
"max_output_tokens": 64e3,
|
|
3038
|
+
"input_cost_per_token_above_200k_tokens": 6e-6,
|
|
3039
|
+
"output_cost_per_token_above_200k_tokens": 225e-7,
|
|
3040
|
+
"cache_creation_input_token_cost_above_200k_tokens": 75e-7,
|
|
3041
|
+
"cache_read_input_token_cost_above_200k_tokens": 6e-7
|
|
3042
|
+
},
|
|
3043
|
+
"claude-opus-4-1": {
|
|
3044
|
+
"input_cost_per_token": 15e-6,
|
|
3045
|
+
"output_cost_per_token": 75e-6,
|
|
3046
|
+
"cache_creation_input_token_cost": 1875e-8,
|
|
3047
|
+
"cache_read_input_token_cost": 15e-7,
|
|
3048
|
+
"max_tokens": 32e3,
|
|
3049
|
+
"max_input_tokens": 2e5,
|
|
3050
|
+
"max_output_tokens": 32e3
|
|
3051
|
+
},
|
|
3052
|
+
"claude-opus-4-1-20250805": {
|
|
3053
|
+
"input_cost_per_token": 15e-6,
|
|
3054
|
+
"output_cost_per_token": 75e-6,
|
|
3055
|
+
"cache_creation_input_token_cost": 1875e-8,
|
|
3056
|
+
"cache_read_input_token_cost": 15e-7,
|
|
3057
|
+
"max_tokens": 32e3,
|
|
3058
|
+
"max_input_tokens": 2e5,
|
|
3059
|
+
"max_output_tokens": 32e3
|
|
3060
|
+
},
|
|
3061
|
+
"claude-opus-4-20250514": {
|
|
3062
|
+
"input_cost_per_token": 15e-6,
|
|
3063
|
+
"output_cost_per_token": 75e-6,
|
|
3064
|
+
"cache_creation_input_token_cost": 1875e-8,
|
|
3065
|
+
"cache_read_input_token_cost": 15e-7,
|
|
3066
|
+
"max_tokens": 32e3,
|
|
3067
|
+
"max_input_tokens": 2e5,
|
|
3068
|
+
"max_output_tokens": 32e3
|
|
3069
|
+
},
|
|
3070
|
+
"claude-sonnet-4-20250514": {
|
|
3071
|
+
"input_cost_per_token": 3e-6,
|
|
3072
|
+
"output_cost_per_token": 15e-6,
|
|
3073
|
+
"cache_creation_input_token_cost": 375e-8,
|
|
3074
|
+
"cache_read_input_token_cost": 3e-7,
|
|
3075
|
+
"max_tokens": 64e3,
|
|
3076
|
+
"max_input_tokens": 1e6,
|
|
3077
|
+
"max_output_tokens": 64e3,
|
|
3078
|
+
"input_cost_per_token_above_200k_tokens": 6e-6,
|
|
3079
|
+
"output_cost_per_token_above_200k_tokens": 225e-7,
|
|
3080
|
+
"cache_creation_input_token_cost_above_200k_tokens": 75e-7,
|
|
3081
|
+
"cache_read_input_token_cost_above_200k_tokens": 6e-7
|
|
3082
|
+
}
|
|
3083
|
+
};
|
|
2936
3084
|
var PricingFetcher = class extends LiteLLMPricingFetcher {
|
|
2937
3085
|
constructor(offline = false) {
|
|
2938
3086
|
super({
|
|
@@ -3051,13 +3199,10 @@ function calculateBurnRate(block) {
|
|
|
3051
3199
|
const firstEntry = firstEntryData.timestamp;
|
|
3052
3200
|
const durationMinutes = (lastEntryData.timestamp.getTime() - firstEntry.getTime()) / (1e3 * 60);
|
|
3053
3201
|
if (durationMinutes <= 0) return null;
|
|
3054
|
-
const tokensPerMinute = getTotalTokens(block.tokenCounts) / durationMinutes;
|
|
3055
|
-
const tokensPerMinuteForIndicator = ((block.tokenCounts.inputTokens ?? 0) + (block.tokenCounts.outputTokens ?? 0)) / durationMinutes;
|
|
3056
|
-
const costPerHour = block.costUSD / durationMinutes * 60;
|
|
3057
3202
|
return {
|
|
3058
|
-
tokensPerMinute,
|
|
3059
|
-
tokensPerMinuteForIndicator,
|
|
3060
|
-
costPerHour
|
|
3203
|
+
tokensPerMinute: getTotalTokens(block.tokenCounts) / durationMinutes,
|
|
3204
|
+
tokensPerMinuteForIndicator: ((block.tokenCounts.inputTokens ?? 0) + (block.tokenCounts.outputTokens ?? 0)) / durationMinutes,
|
|
3205
|
+
costPerHour: block.costUSD / durationMinutes * 60
|
|
3061
3206
|
};
|
|
3062
3207
|
}
|
|
3063
3208
|
function projectBlockUsage(block) {
|
|
@@ -3067,9 +3212,7 @@ function projectBlockUsage(block) {
|
|
|
3067
3212
|
const now = /* @__PURE__ */ new Date();
|
|
3068
3213
|
const remainingTime = block.endTime.getTime() - now.getTime();
|
|
3069
3214
|
const remainingMinutes = Math.max(0, remainingTime / (1e3 * 60));
|
|
3070
|
-
const
|
|
3071
|
-
const projectedAdditionalTokens = burnRate.tokensPerMinute * remainingMinutes;
|
|
3072
|
-
const totalTokens = currentTokens + projectedAdditionalTokens;
|
|
3215
|
+
const totalTokens = getTotalTokens(block.tokenCounts) + burnRate.tokensPerMinute * remainingMinutes;
|
|
3073
3216
|
const projectedAdditionalCost = burnRate.costPerHour / 60 * remainingMinutes;
|
|
3074
3217
|
const totalCost = block.costUSD + projectedAdditionalCost;
|
|
3075
3218
|
return {
|
|
@@ -3094,8 +3237,7 @@ function getClaudePaths() {
|
|
|
3094
3237
|
for (const envPath of envPathList) {
|
|
3095
3238
|
const normalizedPath = path.resolve(envPath);
|
|
3096
3239
|
if (isDirectorySync(normalizedPath)) {
|
|
3097
|
-
|
|
3098
|
-
if (isDirectorySync(projectsPath)) {
|
|
3240
|
+
if (isDirectorySync(path.join(normalizedPath, CLAUDE_PROJECTS_DIR_NAME))) {
|
|
3099
3241
|
if (!normalizedPaths.has(normalizedPath)) {
|
|
3100
3242
|
normalizedPaths.add(normalizedPath);
|
|
3101
3243
|
paths.push(normalizedPath);
|
|
@@ -3111,8 +3253,7 @@ function getClaudePaths() {
|
|
|
3111
3253
|
for (const defaultPath of defaultPaths) {
|
|
3112
3254
|
const normalizedPath = path.resolve(defaultPath);
|
|
3113
3255
|
if (isDirectorySync(normalizedPath)) {
|
|
3114
|
-
|
|
3115
|
-
if (isDirectorySync(projectsPath)) {
|
|
3256
|
+
if (isDirectorySync(path.join(normalizedPath, CLAUDE_PROJECTS_DIR_NAME))) {
|
|
3116
3257
|
if (!normalizedPaths.has(normalizedPath)) {
|
|
3117
3258
|
normalizedPaths.add(normalizedPath);
|
|
3118
3259
|
paths.push(normalizedPath);
|
|
@@ -3324,12 +3465,22 @@ function createUniqueHash(data) {
|
|
|
3324
3465
|
if (messageId == null || requestId == null) return null;
|
|
3325
3466
|
return `${messageId}:${requestId}`;
|
|
3326
3467
|
}
|
|
3468
|
+
async function processJSONLFileByLine(filePath, processLine) {
|
|
3469
|
+
const rl = createInterface({
|
|
3470
|
+
input: createReadStream(filePath, { encoding: "utf-8" }),
|
|
3471
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
3472
|
+
});
|
|
3473
|
+
let lineNumber = 0;
|
|
3474
|
+
for await (const line of rl) {
|
|
3475
|
+
lineNumber++;
|
|
3476
|
+
if (line.trim().length === 0) continue;
|
|
3477
|
+
await processLine(line, lineNumber);
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3327
3480
|
async function getEarliestTimestamp(filePath) {
|
|
3328
3481
|
try {
|
|
3329
|
-
const lines = (await readFile(filePath, "utf-8")).trim().split("\n");
|
|
3330
3482
|
let earliestDate = null;
|
|
3331
|
-
|
|
3332
|
-
if (line.trim() === "") continue;
|
|
3483
|
+
await processJSONLFileByLine(filePath, (line) => {
|
|
3333
3484
|
try {
|
|
3334
3485
|
const json = JSON.parse(line);
|
|
3335
3486
|
if (json.timestamp != null && typeof json.timestamp === "string") {
|
|
@@ -3338,10 +3489,8 @@ async function getEarliestTimestamp(filePath) {
|
|
|
3338
3489
|
if (earliestDate == null || date < earliestDate) earliestDate = date;
|
|
3339
3490
|
}
|
|
3340
3491
|
}
|
|
3341
|
-
} catch {
|
|
3342
|
-
|
|
3343
|
-
}
|
|
3344
|
-
}
|
|
3492
|
+
} catch {}
|
|
3493
|
+
});
|
|
3345
3494
|
return earliestDate;
|
|
3346
3495
|
} catch (error) {
|
|
3347
3496
|
logger.debug(`Failed to get earliest timestamp for ${filePath}:`, error);
|
|
@@ -3399,46 +3548,42 @@ async function globUsageFiles(claudePaths) {
|
|
|
3399
3548
|
async function loadDailyUsageData(options) {
|
|
3400
3549
|
try {
|
|
3401
3550
|
var _usingCtx$1 = _usingCtx();
|
|
3402
|
-
const
|
|
3403
|
-
const fileList = (await globUsageFiles(claudePaths)).map((f$1) => f$1.file);
|
|
3551
|
+
const fileList = (await globUsageFiles(toArray(options?.claudePath ?? getClaudePaths()))).map((f$2) => f$2.file);
|
|
3404
3552
|
if (fileList.length === 0) return [];
|
|
3405
|
-
const
|
|
3406
|
-
const sortedFiles = await sortFilesByTimestamp(projectFilteredFiles);
|
|
3553
|
+
const sortedFiles = await sortFilesByTimestamp(filterByProject(fileList, (filePath) => extractProjectFromPath(filePath), options?.project));
|
|
3407
3554
|
const mode = options?.mode ?? "auto";
|
|
3408
3555
|
const fetcher = _usingCtx$1.u(mode === "display" ? null : new PricingFetcher(options?.offline));
|
|
3409
3556
|
const processedHashes = /* @__PURE__ */ new Set();
|
|
3410
3557
|
const allEntries = [];
|
|
3411
3558
|
for (const file of sortedFiles) {
|
|
3412
|
-
const
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
}
|
|
3431
|
-
}
|
|
3559
|
+
const project = extractProjectFromPath(file);
|
|
3560
|
+
await processJSONLFileByLine(file, async (line) => {
|
|
3561
|
+
try {
|
|
3562
|
+
const result = safeParse(usageDataSchema, JSON.parse(line));
|
|
3563
|
+
if (!result.success) return;
|
|
3564
|
+
const data = result.output;
|
|
3565
|
+
const uniqueHash = createUniqueHash(data);
|
|
3566
|
+
if (isDuplicateEntry(uniqueHash, processedHashes)) return;
|
|
3567
|
+
markAsProcessed(uniqueHash, processedHashes);
|
|
3568
|
+
const date = formatDate(data.timestamp, options?.timezone, DEFAULT_LOCALE);
|
|
3569
|
+
const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
|
|
3570
|
+
allEntries.push({
|
|
3571
|
+
data,
|
|
3572
|
+
date,
|
|
3573
|
+
cost,
|
|
3574
|
+
model: data.message.model,
|
|
3575
|
+
project
|
|
3576
|
+
});
|
|
3577
|
+
} catch {}
|
|
3578
|
+
});
|
|
3432
3579
|
}
|
|
3433
|
-
const
|
|
3434
|
-
|
|
3435
|
-
const results = Object.entries(groupedData).map(([groupKey, entries]) => {
|
|
3580
|
+
const groupedData = groupBy(allEntries, options?.groupByProject === true || options?.project != null ? (entry) => `${entry.date}\x00${entry.project}` : (entry) => entry.date);
|
|
3581
|
+
return sortByDate(filterByProject(filterByDateRange(Object.entries(groupedData).map(([groupKey, entries]) => {
|
|
3436
3582
|
if (entries == null) return;
|
|
3437
3583
|
const parts = groupKey.split("\0");
|
|
3438
3584
|
const date = parts[0] ?? groupKey;
|
|
3439
3585
|
const project = parts.length > 1 ? parts[1] : void 0;
|
|
3440
|
-
const
|
|
3441
|
-
const modelBreakdowns = createModelBreakdowns(modelAggregates);
|
|
3586
|
+
const modelBreakdowns = createModelBreakdowns(aggregateByModel(entries, (entry) => entry.model, (entry) => entry.data.message.usage, (entry) => entry.cost));
|
|
3442
3587
|
const totals = calculateTotals(entries, (entry) => entry.data.message.usage, (entry) => entry.cost);
|
|
3443
3588
|
const modelsUsed = extractUniqueModels(entries, (e) => e.model);
|
|
3444
3589
|
return {
|
|
@@ -3448,10 +3593,7 @@ async function loadDailyUsageData(options) {
|
|
|
3448
3593
|
modelBreakdowns,
|
|
3449
3594
|
...project != null && { project }
|
|
3450
3595
|
};
|
|
3451
|
-
}).filter((item) => item != null);
|
|
3452
|
-
const dateFiltered = filterByDateRange(results, (item) => item.date, options?.since, options?.until);
|
|
3453
|
-
const finalFiltered = filterByProject(dateFiltered, (item) => item.project, options?.project);
|
|
3454
|
-
return sortByDate(finalFiltered, (item) => item.date, options?.order);
|
|
3596
|
+
}).filter((item) => item != null), (item) => item.date, options?.since, options?.until), (item) => item.project, options?.project), (item) => item.date, options?.order);
|
|
3455
3597
|
} catch (_) {
|
|
3456
3598
|
_usingCtx$1.e = _;
|
|
3457
3599
|
} finally {
|
|
@@ -3461,12 +3603,11 @@ async function loadDailyUsageData(options) {
|
|
|
3461
3603
|
async function loadSessionData(options) {
|
|
3462
3604
|
try {
|
|
3463
3605
|
var _usingCtx3 = _usingCtx();
|
|
3464
|
-
const
|
|
3465
|
-
const filesWithBase = await globUsageFiles(claudePaths);
|
|
3606
|
+
const filesWithBase = await globUsageFiles(toArray(options?.claudePath ?? getClaudePaths()));
|
|
3466
3607
|
if (filesWithBase.length === 0) return [];
|
|
3467
3608
|
const projectFilteredWithBase = filterByProject(filesWithBase, (item) => extractProjectFromPath(item.file), options?.project);
|
|
3468
|
-
const fileToBaseMap = new Map(projectFilteredWithBase.map((f$
|
|
3469
|
-
const sortedFilesWithBase = await sortFilesByTimestamp(projectFilteredWithBase.map((f$
|
|
3609
|
+
const fileToBaseMap = new Map(projectFilteredWithBase.map((f$2) => [f$2.file, f$2.baseDir]));
|
|
3610
|
+
const sortedFilesWithBase = await sortFilesByTimestamp(projectFilteredWithBase.map((f$2) => f$2.file)).then((sortedFiles) => sortedFiles.map((file) => ({
|
|
3470
3611
|
file,
|
|
3471
3612
|
baseDir: fileToBaseMap.get(file) ?? ""
|
|
3472
3613
|
})));
|
|
@@ -3479,36 +3620,35 @@ async function loadSessionData(options) {
|
|
|
3479
3620
|
const sessionId = parts[parts.length - 2] ?? "unknown";
|
|
3480
3621
|
const joinedPath = parts.slice(0, -2).join(path.sep);
|
|
3481
3622
|
const projectPath = joinedPath.length > 0 ? joinedPath : "Unknown Project";
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
}
|
|
3502
|
-
}
|
|
3623
|
+
await processJSONLFileByLine(file, async (line) => {
|
|
3624
|
+
try {
|
|
3625
|
+
const result = safeParse(usageDataSchema, JSON.parse(line));
|
|
3626
|
+
if (!result.success) return;
|
|
3627
|
+
const data = result.output;
|
|
3628
|
+
const uniqueHash = createUniqueHash(data);
|
|
3629
|
+
if (isDuplicateEntry(uniqueHash, processedHashes)) return;
|
|
3630
|
+
markAsProcessed(uniqueHash, processedHashes);
|
|
3631
|
+
const sessionKey = `${projectPath}/${sessionId}`;
|
|
3632
|
+
const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
|
|
3633
|
+
allEntries.push({
|
|
3634
|
+
data,
|
|
3635
|
+
sessionKey,
|
|
3636
|
+
sessionId,
|
|
3637
|
+
projectPath,
|
|
3638
|
+
cost,
|
|
3639
|
+
timestamp: data.timestamp,
|
|
3640
|
+
model: data.message.model
|
|
3641
|
+
});
|
|
3642
|
+
} catch {}
|
|
3643
|
+
});
|
|
3503
3644
|
}
|
|
3504
3645
|
const groupedBySessions = groupBy(allEntries, (entry) => entry.sessionKey);
|
|
3505
|
-
|
|
3646
|
+
return sortByDate(filterByProject(filterByDateRange(Object.entries(groupedBySessions).map(([_, entries]) => {
|
|
3506
3647
|
if (entries == null) return;
|
|
3507
3648
|
const latestEntry = entries.reduce((latest, current) => current.timestamp > latest.timestamp ? current : latest);
|
|
3508
3649
|
const versions = [];
|
|
3509
3650
|
for (const entry of entries) if (entry.data.version != null) versions.push(entry.data.version);
|
|
3510
|
-
const
|
|
3511
|
-
const modelBreakdowns = createModelBreakdowns(modelAggregates);
|
|
3651
|
+
const modelBreakdowns = createModelBreakdowns(aggregateByModel(entries, (entry) => entry.model, (entry) => entry.data.message.usage, (entry) => entry.cost));
|
|
3512
3652
|
const totals = calculateTotals(entries, (entry) => entry.data.message.usage, (entry) => entry.cost);
|
|
3513
3653
|
const modelsUsed = extractUniqueModels(entries, (e) => e.model);
|
|
3514
3654
|
return {
|
|
@@ -3520,10 +3660,7 @@ async function loadSessionData(options) {
|
|
|
3520
3660
|
modelsUsed,
|
|
3521
3661
|
modelBreakdowns
|
|
3522
3662
|
};
|
|
3523
|
-
}).filter((item) => item != null);
|
|
3524
|
-
const dateFiltered = filterByDateRange(results, (item) => item.lastActivity, options?.since, options?.until);
|
|
3525
|
-
const sessionFiltered = filterByProject(dateFiltered, (item) => item.projectPath, options?.project);
|
|
3526
|
-
return sortByDate(sessionFiltered, (item) => item.lastActivity, options?.order);
|
|
3663
|
+
}).filter((item) => item != null), (item) => item.lastActivity, options?.since, options?.until), (item) => item.projectPath, options?.project), (item) => item.lastActivity, options?.order);
|
|
3527
3664
|
} catch (_) {
|
|
3528
3665
|
_usingCtx3.e = _;
|
|
3529
3666
|
} finally {
|
|
@@ -3546,25 +3683,24 @@ async function loadWeeklyUsageData(options) {
|
|
|
3546
3683
|
async function loadSessionUsageById(sessionId, options) {
|
|
3547
3684
|
try {
|
|
3548
3685
|
var _usingCtx4 = _usingCtx();
|
|
3549
|
-
const
|
|
3550
|
-
const jsonlFiles = await glob(patterns);
|
|
3686
|
+
const jsonlFiles = await glob(getClaudePaths().map((p) => path.join(p, "projects", "**", `${sessionId}.jsonl`).replace(/\\/g, "/")));
|
|
3551
3687
|
if (jsonlFiles.length === 0) return null;
|
|
3552
3688
|
const file = jsonlFiles[0];
|
|
3553
3689
|
if (file == null) return null;
|
|
3554
|
-
const lines = (await readFile(file, "utf-8")).trim().split("\n").filter((line) => line.length > 0);
|
|
3555
3690
|
const mode = options?.mode ?? "auto";
|
|
3556
3691
|
const fetcher = _usingCtx4.u(mode === "display" ? null : new PricingFetcher(options?.offline));
|
|
3557
3692
|
const entries = [];
|
|
3558
3693
|
let totalCost = 0;
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3694
|
+
await processJSONLFileByLine(file, async (line) => {
|
|
3695
|
+
try {
|
|
3696
|
+
const result = safeParse(usageDataSchema, JSON.parse(line));
|
|
3697
|
+
if (!result.success) return;
|
|
3698
|
+
const data = result.output;
|
|
3699
|
+
const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
|
|
3700
|
+
totalCost += cost;
|
|
3701
|
+
entries.push(data);
|
|
3702
|
+
} catch {}
|
|
3703
|
+
});
|
|
3568
3704
|
return {
|
|
3569
3705
|
totalCost,
|
|
3570
3706
|
entries
|
|
@@ -3576,22 +3712,16 @@ async function loadSessionUsageById(sessionId, options) {
|
|
|
3576
3712
|
}
|
|
3577
3713
|
}
|
|
3578
3714
|
async function loadBucketUsageData(groupingFn, options) {
|
|
3579
|
-
const
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
const projectSegment = data.project ?? "unknown";
|
|
3583
|
-
return `${bucketValue}\x00${projectSegment}`;
|
|
3584
|
-
} : (data) => `${groupingFn(data)}`;
|
|
3585
|
-
const grouped = groupBy(dailyData, groupingKey);
|
|
3715
|
+
const grouped = groupBy(await loadDailyUsageData(options), options?.groupByProject === true || options?.project != null ? (data) => {
|
|
3716
|
+
return `${groupingFn(data)}\x00${data.project ?? "unknown"}`;
|
|
3717
|
+
} : (data) => `${groupingFn(data)}`);
|
|
3586
3718
|
const buckets = [];
|
|
3587
3719
|
for (const [groupKey, dailyEntries] of Object.entries(grouped)) {
|
|
3588
3720
|
if (dailyEntries == null) continue;
|
|
3589
3721
|
const parts = groupKey.split("\0");
|
|
3590
3722
|
const bucket = createBucket(parts[0] ?? groupKey);
|
|
3591
3723
|
const project = parts.length > 1 ? parts[1] : void 0;
|
|
3592
|
-
const
|
|
3593
|
-
const modelAggregates = aggregateModelBreakdowns(allBreakdowns);
|
|
3594
|
-
const modelBreakdowns = createModelBreakdowns(modelAggregates);
|
|
3724
|
+
const modelBreakdowns = createModelBreakdowns(aggregateModelBreakdowns(dailyEntries.flatMap((daily) => daily.modelBreakdowns)));
|
|
3595
3725
|
const models = [];
|
|
3596
3726
|
for (const data of dailyEntries) for (const model of data.modelsUsed) if (model !== "<synthetic>") models.push(model);
|
|
3597
3727
|
let totalInputTokens = 0;
|
|
@@ -3634,8 +3764,7 @@ async function calculateContextTokens(transcriptPath, modelId, offline = false)
|
|
|
3634
3764
|
const trimmedLine = line.trim();
|
|
3635
3765
|
if (trimmedLine === "") continue;
|
|
3636
3766
|
try {
|
|
3637
|
-
const
|
|
3638
|
-
const result = safeParse(transcriptMessageSchema, parsed);
|
|
3767
|
+
const result = safeParse(transcriptMessageSchema, JSON.parse(trimmedLine));
|
|
3639
3768
|
if (!result.success) continue;
|
|
3640
3769
|
const obj = result.output;
|
|
3641
3770
|
if (obj.type === "assistant" && obj.message != null && obj.message.usage != null && obj.message.usage.input_tokens != null) {
|
|
@@ -3653,10 +3782,9 @@ async function calculateContextTokens(transcriptPath, modelId, offline = false)
|
|
|
3653
3782
|
} finally {
|
|
3654
3783
|
_usingCtx5.d();
|
|
3655
3784
|
}
|
|
3656
|
-
const percentage = Math.min(100, Math.max(0, Math.round(inputTokens / contextLimit * 100)));
|
|
3657
3785
|
return {
|
|
3658
3786
|
inputTokens,
|
|
3659
|
-
percentage,
|
|
3787
|
+
percentage: Math.min(100, Math.max(0, Math.round(inputTokens / contextLimit * 100))),
|
|
3660
3788
|
contextLimit
|
|
3661
3789
|
};
|
|
3662
3790
|
}
|
|
@@ -3681,21 +3809,18 @@ async function loadSessionBlockData(options) {
|
|
|
3681
3809
|
allFiles.push(...files);
|
|
3682
3810
|
}
|
|
3683
3811
|
if (allFiles.length === 0) return [];
|
|
3684
|
-
const
|
|
3685
|
-
const sortedFiles = await sortFilesByTimestamp(blocksFilteredFiles);
|
|
3812
|
+
const sortedFiles = await sortFilesByTimestamp(filterByProject(allFiles, (filePath) => extractProjectFromPath(filePath), options?.project));
|
|
3686
3813
|
const mode = options?.mode ?? "auto";
|
|
3687
3814
|
const fetcher = _usingCtx6.u(mode === "display" ? null : new PricingFetcher(options?.offline));
|
|
3688
3815
|
const processedHashes = /* @__PURE__ */ new Set();
|
|
3689
3816
|
const allEntries = [];
|
|
3690
|
-
for (const file of sortedFiles) {
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
const result = safeParse(usageDataSchema, parsed);
|
|
3695
|
-
if (!result.success) continue;
|
|
3817
|
+
for (const file of sortedFiles) await processJSONLFileByLine(file, async (line) => {
|
|
3818
|
+
try {
|
|
3819
|
+
const result = safeParse(usageDataSchema, JSON.parse(line));
|
|
3820
|
+
if (!result.success) return;
|
|
3696
3821
|
const data = result.output;
|
|
3697
3822
|
const uniqueHash = createUniqueHash(data);
|
|
3698
|
-
if (isDuplicateEntry(uniqueHash, processedHashes))
|
|
3823
|
+
if (isDuplicateEntry(uniqueHash, processedHashes)) return;
|
|
3699
3824
|
markAsProcessed(uniqueHash, processedHashes);
|
|
3700
3825
|
const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
|
|
3701
3826
|
const usageLimitResetTime = getUsageLimitResetTime(data);
|
|
@@ -3715,19 +3840,18 @@ async function loadSessionBlockData(options) {
|
|
|
3715
3840
|
} catch (error) {
|
|
3716
3841
|
logger.debug(`Skipping invalid JSON line in 5-hour blocks: ${error instanceof Error ? error.message : String(error)}`);
|
|
3717
3842
|
}
|
|
3718
|
-
}
|
|
3843
|
+
});
|
|
3719
3844
|
const blocks = identifySessionBlocks(allEntries, options?.sessionDurationHours);
|
|
3720
|
-
|
|
3845
|
+
return sortByDate(options?.since != null && options.since !== "" || options?.until != null && options.until !== "" ? blocks.filter((block) => {
|
|
3721
3846
|
const blockDateStr = formatDate(block.startTime.toISOString(), options?.timezone, DEFAULT_LOCALE).replace(/-/g, "");
|
|
3722
3847
|
if (options.since != null && options.since !== "" && blockDateStr < options.since) return false;
|
|
3723
3848
|
if (options.until != null && options.until !== "" && blockDateStr > options.until) return false;
|
|
3724
3849
|
return true;
|
|
3725
|
-
}) : blocks;
|
|
3726
|
-
return sortByDate(dateFiltered, (block) => block.startTime, options?.order);
|
|
3850
|
+
}) : blocks, (block) => block.startTime, options?.order);
|
|
3727
3851
|
} catch (_) {
|
|
3728
3852
|
_usingCtx6.e = _;
|
|
3729
3853
|
} finally {
|
|
3730
3854
|
_usingCtx6.d();
|
|
3731
3855
|
}
|
|
3732
3856
|
}
|
|
3733
|
-
export {
|
|
3857
|
+
export { uniq as $, projectBlockUsage as A, CLAUDE_PROJECTS_DIR_NAME as B, transcriptUsageSchema as C, calculateBurnRate as D, DEFAULT_SESSION_DURATION_HOURS as E, _usingCtx as F, DEFAULT_RECENT_DAYS as G, DEBUG_MATCH_THRESHOLD_PERCENT as H, BLOCKS_COMPACT_WIDTH_THRESHOLD as I, MIN_REFRESH_INTERVAL_SECONDS as J, DEFAULT_REFRESH_INTERVAL_SECONDS as K, BLOCKS_DEFAULT_TERMINAL_WIDTH as L, formatDateCompact as M, getFileModifiedTime as N, filterRecentBlocks as O, unreachable as P, glob as Q, BLOCKS_WARNING_THRESHOLD as R, transcriptMessageSchema as S, weeklyUsageSchema as T, DEFAULT_CONTEXT_USAGE_THRESHOLDS as U, CONFIG_FILE_NAME as V, DEFAULT_LOCALE as W, USAGE_DATA_GLOB_PATTERN as X, MIN_RENDER_INTERVAL_MS as Y, WEEK_DAYS as Z, loadWeeklyUsageData as _, dailyUsageSchema as a, inspect as at, sessionUsageSchema as b, getEarliestTimestamp as c, isSuccess as ct, loadBucketUsageData as d, toArray as dt, unwrap as et, loadDailyUsageData as f, __commonJSMin as ft, loadSessionUsageById as g, loadSessionData as h, createUniqueHash as i, inspectError as it, PricingFetcher as j, identifySessionBlocks as k, getUsageLimitResetTime as l, andThen as lt, loadSessionBlockData as m, __toESM as mt, calculateContextTokens as n, pipe as nt, extractProjectFromPath as o, fail as ot, loadMonthlyUsageData as p, __require$1 as pt, MAX_REFRESH_INTERVAL_SECONDS as q, calculateCostForEntry as r, map as rt, getClaudePaths as s, succeed as st, bucketUsageSchema as t, try_ as tt, globUsageFiles as u, isFailure as ut, modelBreakdownSchema as v, usageDataSchema as w, sortFilesByTimestamp as x, monthlyUsageSchema as y, BURN_RATE_THRESHOLDS as z };
|