ccusage 17.1.3 → 17.1.5

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.
@@ -1,11 +1,12 @@
1
- import { activityDateSchema, array, boolean, createBucket, createDailyDate, createMonthlyDate, createProjectPath, createSessionId, createWeeklyDate, dailyDateSchema, getTotalTokens, isoTimestampSchema, messageIdSchema, modelNameSchema, monthlyDateSchema, number, object, optional, parse as parse$2, projectPathSchema, requestIdSchema, safeParse, sessionIdSchema, string, union, versionSchema, weeklyDateSchema } from "./_types-CV6z8-9_.js";
2
- import { logger } from "./logger-Dti-igUw.js";
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-_VjiKYLh.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 * as nativeFs from "node:fs";
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
- const needsSeperator = path$1[path$1.length - 1] !== pathSeparator;
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
- const prepend = options.contains ? "" : "^";
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: NO_DOT$1, NO_DOT_SLASH: NO_DOT_SLASH$1, NO_DOTS_SLASH: NO_DOTS_SLASH$1, QMARK: QMARK$1, QMARK_NO_DOT: QMARK_NO_DOT$1, STAR: STAR$1, START_ANCHOR: START_ANCHOR$1 } = PLATFORM_CHARS;
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$1;
1330
- const qmarkNoDot = opts.dot ? QMARK$1 : QMARK_NO_DOT$1;
1331
- let star = opts.bash === true ? globstar(opts) : STAR$1;
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 rest$1 = prev.value.slice(idx + 2);
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$1
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$1;
1970
- prev.output += NO_DOT_SLASH$1;
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$1;
1973
- prev.output += NO_DOTS_SLASH$1;
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: NO_DOT$1, NO_DOTS: NO_DOTS$1, NO_DOTS_SLASH: NO_DOTS_SLASH$1, STAR: STAR$1, START_ANCHOR: START_ANCHOR$1 } = constants$1.globChars(opts.windows);
2021
- const nodot = opts.dot ? NO_DOTS$1 : NO_DOT$1;
2022
- const slashDot = opts.dot ? NO_DOTS_SLASH$1 : NO_DOT$1;
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$1;
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
- const output = utils$2.removePrefix(input, state);
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 patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns;
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
- const year = parts.find((p) => p.type === "year")?.value ?? "";
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);
@@ -2917,6 +2902,24 @@ const PREFETCHED_CLAUDE_PRICING = {
2917
2902
  "max_input_tokens": 2e5,
2918
2903
  "max_output_tokens": 8192
2919
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
+ },
2920
2923
  "claude-3-5-sonnet-20240620": {
2921
2924
  "input_cost_per_token": 3e-6,
2922
2925
  "output_cost_per_token": 15e-6,
@@ -3005,7 +3008,7 @@ const PREFETCHED_CLAUDE_PRICING = {
3005
3008
  "cache_read_input_token_cost": 3e-7,
3006
3009
  "max_tokens": 1e6,
3007
3010
  "max_input_tokens": 1e6,
3008
- "max_output_tokens": 1e6,
3011
+ "max_output_tokens": 64e3,
3009
3012
  "input_cost_per_token_above_200k_tokens": 6e-6,
3010
3013
  "output_cost_per_token_above_200k_tokens": 225e-7,
3011
3014
  "cache_creation_input_token_cost_above_200k_tokens": 75e-7,
@@ -3016,7 +3019,7 @@ const PREFETCHED_CLAUDE_PRICING = {
3016
3019
  "output_cost_per_token": 15e-6,
3017
3020
  "cache_creation_input_token_cost": 375e-8,
3018
3021
  "cache_read_input_token_cost": 3e-7,
3019
- "max_tokens": 2e5,
3022
+ "max_tokens": 64e3,
3020
3023
  "max_input_tokens": 2e5,
3021
3024
  "max_output_tokens": 64e3,
3022
3025
  "input_cost_per_token_above_200k_tokens": 6e-6,
@@ -3029,7 +3032,7 @@ const PREFETCHED_CLAUDE_PRICING = {
3029
3032
  "output_cost_per_token": 15e-6,
3030
3033
  "cache_creation_input_token_cost": 375e-8,
3031
3034
  "cache_read_input_token_cost": 3e-7,
3032
- "max_tokens": 2e5,
3035
+ "max_tokens": 64e3,
3033
3036
  "max_input_tokens": 2e5,
3034
3037
  "max_output_tokens": 64e3,
3035
3038
  "input_cost_per_token_above_200k_tokens": 6e-6,
@@ -3196,13 +3199,10 @@ function calculateBurnRate(block) {
3196
3199
  const firstEntry = firstEntryData.timestamp;
3197
3200
  const durationMinutes = (lastEntryData.timestamp.getTime() - firstEntry.getTime()) / (1e3 * 60);
3198
3201
  if (durationMinutes <= 0) return null;
3199
- const tokensPerMinute = getTotalTokens(block.tokenCounts) / durationMinutes;
3200
- const tokensPerMinuteForIndicator = ((block.tokenCounts.inputTokens ?? 0) + (block.tokenCounts.outputTokens ?? 0)) / durationMinutes;
3201
- const costPerHour = block.costUSD / durationMinutes * 60;
3202
3202
  return {
3203
- tokensPerMinute,
3204
- tokensPerMinuteForIndicator,
3205
- costPerHour
3203
+ tokensPerMinute: getTotalTokens(block.tokenCounts) / durationMinutes,
3204
+ tokensPerMinuteForIndicator: ((block.tokenCounts.inputTokens ?? 0) + (block.tokenCounts.outputTokens ?? 0)) / durationMinutes,
3205
+ costPerHour: block.costUSD / durationMinutes * 60
3206
3206
  };
3207
3207
  }
3208
3208
  function projectBlockUsage(block) {
@@ -3212,9 +3212,7 @@ function projectBlockUsage(block) {
3212
3212
  const now = /* @__PURE__ */ new Date();
3213
3213
  const remainingTime = block.endTime.getTime() - now.getTime();
3214
3214
  const remainingMinutes = Math.max(0, remainingTime / (1e3 * 60));
3215
- const currentTokens = getTotalTokens(block.tokenCounts);
3216
- const projectedAdditionalTokens = burnRate.tokensPerMinute * remainingMinutes;
3217
- const totalTokens = currentTokens + projectedAdditionalTokens;
3215
+ const totalTokens = getTotalTokens(block.tokenCounts) + burnRate.tokensPerMinute * remainingMinutes;
3218
3216
  const projectedAdditionalCost = burnRate.costPerHour / 60 * remainingMinutes;
3219
3217
  const totalCost = block.costUSD + projectedAdditionalCost;
3220
3218
  return {
@@ -3239,8 +3237,7 @@ function getClaudePaths() {
3239
3237
  for (const envPath of envPathList) {
3240
3238
  const normalizedPath = path.resolve(envPath);
3241
3239
  if (isDirectorySync(normalizedPath)) {
3242
- const projectsPath = path.join(normalizedPath, CLAUDE_PROJECTS_DIR_NAME);
3243
- if (isDirectorySync(projectsPath)) {
3240
+ if (isDirectorySync(path.join(normalizedPath, CLAUDE_PROJECTS_DIR_NAME))) {
3244
3241
  if (!normalizedPaths.has(normalizedPath)) {
3245
3242
  normalizedPaths.add(normalizedPath);
3246
3243
  paths.push(normalizedPath);
@@ -3256,8 +3253,7 @@ function getClaudePaths() {
3256
3253
  for (const defaultPath of defaultPaths) {
3257
3254
  const normalizedPath = path.resolve(defaultPath);
3258
3255
  if (isDirectorySync(normalizedPath)) {
3259
- const projectsPath = path.join(normalizedPath, CLAUDE_PROJECTS_DIR_NAME);
3260
- if (isDirectorySync(projectsPath)) {
3256
+ if (isDirectorySync(path.join(normalizedPath, CLAUDE_PROJECTS_DIR_NAME))) {
3261
3257
  if (!normalizedPaths.has(normalizedPath)) {
3262
3258
  normalizedPaths.add(normalizedPath);
3263
3259
  paths.push(normalizedPath);
@@ -3469,12 +3465,22 @@ function createUniqueHash(data) {
3469
3465
  if (messageId == null || requestId == null) return null;
3470
3466
  return `${messageId}:${requestId}`;
3471
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
+ }
3472
3480
  async function getEarliestTimestamp(filePath) {
3473
3481
  try {
3474
- const lines = (await readFile(filePath, "utf-8")).trim().split("\n");
3475
3482
  let earliestDate = null;
3476
- for (const line of lines) {
3477
- if (line.trim() === "") continue;
3483
+ await processJSONLFileByLine(filePath, (line) => {
3478
3484
  try {
3479
3485
  const json = JSON.parse(line);
3480
3486
  if (json.timestamp != null && typeof json.timestamp === "string") {
@@ -3483,10 +3489,8 @@ async function getEarliestTimestamp(filePath) {
3483
3489
  if (earliestDate == null || date < earliestDate) earliestDate = date;
3484
3490
  }
3485
3491
  }
3486
- } catch {
3487
- continue;
3488
- }
3489
- }
3492
+ } catch {}
3493
+ });
3490
3494
  return earliestDate;
3491
3495
  } catch (error) {
3492
3496
  logger.debug(`Failed to get earliest timestamp for ${filePath}:`, error);
@@ -3544,46 +3548,42 @@ async function globUsageFiles(claudePaths) {
3544
3548
  async function loadDailyUsageData(options) {
3545
3549
  try {
3546
3550
  var _usingCtx$1 = _usingCtx();
3547
- const claudePaths = toArray(options?.claudePath ?? getClaudePaths());
3548
- 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);
3549
3552
  if (fileList.length === 0) return [];
3550
- const projectFilteredFiles = filterByProject(fileList, (filePath) => extractProjectFromPath(filePath), options?.project);
3551
- const sortedFiles = await sortFilesByTimestamp(projectFilteredFiles);
3553
+ const sortedFiles = await sortFilesByTimestamp(filterByProject(fileList, (filePath) => extractProjectFromPath(filePath), options?.project));
3552
3554
  const mode = options?.mode ?? "auto";
3553
3555
  const fetcher = _usingCtx$1.u(mode === "display" ? null : new PricingFetcher(options?.offline));
3554
3556
  const processedHashes = /* @__PURE__ */ new Set();
3555
3557
  const allEntries = [];
3556
3558
  for (const file of sortedFiles) {
3557
- const lines = (await readFile(file, "utf-8")).trim().split("\n").filter((line) => line.length > 0);
3558
- for (const line of lines) try {
3559
- const parsed = JSON.parse(line);
3560
- const result = safeParse(usageDataSchema, parsed);
3561
- if (!result.success) continue;
3562
- const data = result.output;
3563
- const uniqueHash = createUniqueHash(data);
3564
- if (isDuplicateEntry(uniqueHash, processedHashes)) continue;
3565
- markAsProcessed(uniqueHash, processedHashes);
3566
- const date = formatDate(data.timestamp, options?.timezone, DEFAULT_LOCALE);
3567
- const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
3568
- const project = extractProjectFromPath(file);
3569
- allEntries.push({
3570
- data,
3571
- date,
3572
- cost,
3573
- model: data.message.model,
3574
- project
3575
- });
3576
- } catch {}
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
+ });
3577
3579
  }
3578
- const groupingKey = options?.groupByProject === true || options?.project != null ? (entry) => `${entry.date}\x00${entry.project}` : (entry) => entry.date;
3579
- const groupedData = groupBy(allEntries, groupingKey);
3580
- 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]) => {
3581
3582
  if (entries == null) return;
3582
3583
  const parts = groupKey.split("\0");
3583
3584
  const date = parts[0] ?? groupKey;
3584
3585
  const project = parts.length > 1 ? parts[1] : void 0;
3585
- const modelAggregates = aggregateByModel(entries, (entry) => entry.model, (entry) => entry.data.message.usage, (entry) => entry.cost);
3586
- const modelBreakdowns = createModelBreakdowns(modelAggregates);
3586
+ const modelBreakdowns = createModelBreakdowns(aggregateByModel(entries, (entry) => entry.model, (entry) => entry.data.message.usage, (entry) => entry.cost));
3587
3587
  const totals = calculateTotals(entries, (entry) => entry.data.message.usage, (entry) => entry.cost);
3588
3588
  const modelsUsed = extractUniqueModels(entries, (e) => e.model);
3589
3589
  return {
@@ -3593,10 +3593,7 @@ async function loadDailyUsageData(options) {
3593
3593
  modelBreakdowns,
3594
3594
  ...project != null && { project }
3595
3595
  };
3596
- }).filter((item) => item != null);
3597
- const dateFiltered = filterByDateRange(results, (item) => item.date, options?.since, options?.until);
3598
- const finalFiltered = filterByProject(dateFiltered, (item) => item.project, options?.project);
3599
- 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);
3600
3597
  } catch (_) {
3601
3598
  _usingCtx$1.e = _;
3602
3599
  } finally {
@@ -3606,12 +3603,11 @@ async function loadDailyUsageData(options) {
3606
3603
  async function loadSessionData(options) {
3607
3604
  try {
3608
3605
  var _usingCtx3 = _usingCtx();
3609
- const claudePaths = toArray(options?.claudePath ?? getClaudePaths());
3610
- const filesWithBase = await globUsageFiles(claudePaths);
3606
+ const filesWithBase = await globUsageFiles(toArray(options?.claudePath ?? getClaudePaths()));
3611
3607
  if (filesWithBase.length === 0) return [];
3612
3608
  const projectFilteredWithBase = filterByProject(filesWithBase, (item) => extractProjectFromPath(item.file), options?.project);
3613
- const fileToBaseMap = new Map(projectFilteredWithBase.map((f$1) => [f$1.file, f$1.baseDir]));
3614
- const sortedFilesWithBase = await sortFilesByTimestamp(projectFilteredWithBase.map((f$1) => f$1.file)).then((sortedFiles) => sortedFiles.map((file) => ({
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) => ({
3615
3611
  file,
3616
3612
  baseDir: fileToBaseMap.get(file) ?? ""
3617
3613
  })));
@@ -3624,36 +3620,35 @@ async function loadSessionData(options) {
3624
3620
  const sessionId = parts[parts.length - 2] ?? "unknown";
3625
3621
  const joinedPath = parts.slice(0, -2).join(path.sep);
3626
3622
  const projectPath = joinedPath.length > 0 ? joinedPath : "Unknown Project";
3627
- const lines = (await readFile(file, "utf-8")).trim().split("\n").filter((line) => line.length > 0);
3628
- for (const line of lines) try {
3629
- const parsed = JSON.parse(line);
3630
- const result = safeParse(usageDataSchema, parsed);
3631
- if (!result.success) continue;
3632
- const data = result.output;
3633
- const uniqueHash = createUniqueHash(data);
3634
- if (isDuplicateEntry(uniqueHash, processedHashes)) continue;
3635
- markAsProcessed(uniqueHash, processedHashes);
3636
- const sessionKey = `${projectPath}/${sessionId}`;
3637
- const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
3638
- allEntries.push({
3639
- data,
3640
- sessionKey,
3641
- sessionId,
3642
- projectPath,
3643
- cost,
3644
- timestamp: data.timestamp,
3645
- model: data.message.model
3646
- });
3647
- } catch {}
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
+ });
3648
3644
  }
3649
3645
  const groupedBySessions = groupBy(allEntries, (entry) => entry.sessionKey);
3650
- const results = Object.entries(groupedBySessions).map(([_, entries]) => {
3646
+ return sortByDate(filterByProject(filterByDateRange(Object.entries(groupedBySessions).map(([_, entries]) => {
3651
3647
  if (entries == null) return;
3652
3648
  const latestEntry = entries.reduce((latest, current) => current.timestamp > latest.timestamp ? current : latest);
3653
3649
  const versions = [];
3654
3650
  for (const entry of entries) if (entry.data.version != null) versions.push(entry.data.version);
3655
- const modelAggregates = aggregateByModel(entries, (entry) => entry.model, (entry) => entry.data.message.usage, (entry) => entry.cost);
3656
- const modelBreakdowns = createModelBreakdowns(modelAggregates);
3651
+ const modelBreakdowns = createModelBreakdowns(aggregateByModel(entries, (entry) => entry.model, (entry) => entry.data.message.usage, (entry) => entry.cost));
3657
3652
  const totals = calculateTotals(entries, (entry) => entry.data.message.usage, (entry) => entry.cost);
3658
3653
  const modelsUsed = extractUniqueModels(entries, (e) => e.model);
3659
3654
  return {
@@ -3665,10 +3660,7 @@ async function loadSessionData(options) {
3665
3660
  modelsUsed,
3666
3661
  modelBreakdowns
3667
3662
  };
3668
- }).filter((item) => item != null);
3669
- const dateFiltered = filterByDateRange(results, (item) => item.lastActivity, options?.since, options?.until);
3670
- const sessionFiltered = filterByProject(dateFiltered, (item) => item.projectPath, options?.project);
3671
- 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);
3672
3664
  } catch (_) {
3673
3665
  _usingCtx3.e = _;
3674
3666
  } finally {
@@ -3691,25 +3683,24 @@ async function loadWeeklyUsageData(options) {
3691
3683
  async function loadSessionUsageById(sessionId, options) {
3692
3684
  try {
3693
3685
  var _usingCtx4 = _usingCtx();
3694
- const patterns = getClaudePaths().map((p) => path.join(p, "projects", "**", `${sessionId}.jsonl`).replace(/\\/g, "/"));
3695
- const jsonlFiles = await glob(patterns);
3686
+ const jsonlFiles = await glob(getClaudePaths().map((p) => path.join(p, "projects", "**", `${sessionId}.jsonl`).replace(/\\/g, "/")));
3696
3687
  if (jsonlFiles.length === 0) return null;
3697
3688
  const file = jsonlFiles[0];
3698
3689
  if (file == null) return null;
3699
- const lines = (await readFile(file, "utf-8")).trim().split("\n").filter((line) => line.length > 0);
3700
3690
  const mode = options?.mode ?? "auto";
3701
3691
  const fetcher = _usingCtx4.u(mode === "display" ? null : new PricingFetcher(options?.offline));
3702
3692
  const entries = [];
3703
3693
  let totalCost = 0;
3704
- for (const line of lines) try {
3705
- const parsed = JSON.parse(line);
3706
- const result = safeParse(usageDataSchema, parsed);
3707
- if (!result.success) continue;
3708
- const data = result.output;
3709
- const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
3710
- totalCost += cost;
3711
- entries.push(data);
3712
- } catch {}
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
+ });
3713
3704
  return {
3714
3705
  totalCost,
3715
3706
  entries
@@ -3721,22 +3712,16 @@ async function loadSessionUsageById(sessionId, options) {
3721
3712
  }
3722
3713
  }
3723
3714
  async function loadBucketUsageData(groupingFn, options) {
3724
- const dailyData = await loadDailyUsageData(options);
3725
- const groupingKey = options?.groupByProject === true || options?.project != null ? (data) => {
3726
- const bucketValue = groupingFn(data);
3727
- const projectSegment = data.project ?? "unknown";
3728
- return `${bucketValue}\x00${projectSegment}`;
3729
- } : (data) => `${groupingFn(data)}`;
3730
- 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)}`);
3731
3718
  const buckets = [];
3732
3719
  for (const [groupKey, dailyEntries] of Object.entries(grouped)) {
3733
3720
  if (dailyEntries == null) continue;
3734
3721
  const parts = groupKey.split("\0");
3735
3722
  const bucket = createBucket(parts[0] ?? groupKey);
3736
3723
  const project = parts.length > 1 ? parts[1] : void 0;
3737
- const allBreakdowns = dailyEntries.flatMap((daily) => daily.modelBreakdowns);
3738
- const modelAggregates = aggregateModelBreakdowns(allBreakdowns);
3739
- const modelBreakdowns = createModelBreakdowns(modelAggregates);
3724
+ const modelBreakdowns = createModelBreakdowns(aggregateModelBreakdowns(dailyEntries.flatMap((daily) => daily.modelBreakdowns)));
3740
3725
  const models = [];
3741
3726
  for (const data of dailyEntries) for (const model of data.modelsUsed) if (model !== "<synthetic>") models.push(model);
3742
3727
  let totalInputTokens = 0;
@@ -3779,8 +3764,7 @@ async function calculateContextTokens(transcriptPath, modelId, offline = false)
3779
3764
  const trimmedLine = line.trim();
3780
3765
  if (trimmedLine === "") continue;
3781
3766
  try {
3782
- const parsed = JSON.parse(trimmedLine);
3783
- const result = safeParse(transcriptMessageSchema, parsed);
3767
+ const result = safeParse(transcriptMessageSchema, JSON.parse(trimmedLine));
3784
3768
  if (!result.success) continue;
3785
3769
  const obj = result.output;
3786
3770
  if (obj.type === "assistant" && obj.message != null && obj.message.usage != null && obj.message.usage.input_tokens != null) {
@@ -3798,10 +3782,9 @@ async function calculateContextTokens(transcriptPath, modelId, offline = false)
3798
3782
  } finally {
3799
3783
  _usingCtx5.d();
3800
3784
  }
3801
- const percentage = Math.min(100, Math.max(0, Math.round(inputTokens / contextLimit * 100)));
3802
3785
  return {
3803
3786
  inputTokens,
3804
- percentage,
3787
+ percentage: Math.min(100, Math.max(0, Math.round(inputTokens / contextLimit * 100))),
3805
3788
  contextLimit
3806
3789
  };
3807
3790
  }
@@ -3826,21 +3809,18 @@ async function loadSessionBlockData(options) {
3826
3809
  allFiles.push(...files);
3827
3810
  }
3828
3811
  if (allFiles.length === 0) return [];
3829
- const blocksFilteredFiles = filterByProject(allFiles, (filePath) => extractProjectFromPath(filePath), options?.project);
3830
- const sortedFiles = await sortFilesByTimestamp(blocksFilteredFiles);
3812
+ const sortedFiles = await sortFilesByTimestamp(filterByProject(allFiles, (filePath) => extractProjectFromPath(filePath), options?.project));
3831
3813
  const mode = options?.mode ?? "auto";
3832
3814
  const fetcher = _usingCtx6.u(mode === "display" ? null : new PricingFetcher(options?.offline));
3833
3815
  const processedHashes = /* @__PURE__ */ new Set();
3834
3816
  const allEntries = [];
3835
- for (const file of sortedFiles) {
3836
- const lines = (await readFile(file, "utf-8")).trim().split("\n").filter((line) => line.length > 0);
3837
- for (const line of lines) try {
3838
- const parsed = JSON.parse(line);
3839
- const result = safeParse(usageDataSchema, parsed);
3840
- 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;
3841
3821
  const data = result.output;
3842
3822
  const uniqueHash = createUniqueHash(data);
3843
- if (isDuplicateEntry(uniqueHash, processedHashes)) continue;
3823
+ if (isDuplicateEntry(uniqueHash, processedHashes)) return;
3844
3824
  markAsProcessed(uniqueHash, processedHashes);
3845
3825
  const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
3846
3826
  const usageLimitResetTime = getUsageLimitResetTime(data);
@@ -3860,19 +3840,18 @@ async function loadSessionBlockData(options) {
3860
3840
  } catch (error) {
3861
3841
  logger.debug(`Skipping invalid JSON line in 5-hour blocks: ${error instanceof Error ? error.message : String(error)}`);
3862
3842
  }
3863
- }
3843
+ });
3864
3844
  const blocks = identifySessionBlocks(allEntries, options?.sessionDurationHours);
3865
- const dateFiltered = options?.since != null && options.since !== "" || options?.until != null && options.until !== "" ? blocks.filter((block) => {
3845
+ return sortByDate(options?.since != null && options.since !== "" || options?.until != null && options.until !== "" ? blocks.filter((block) => {
3866
3846
  const blockDateStr = formatDate(block.startTime.toISOString(), options?.timezone, DEFAULT_LOCALE).replace(/-/g, "");
3867
3847
  if (options.since != null && options.since !== "" && blockDateStr < options.since) return false;
3868
3848
  if (options.until != null && options.until !== "" && blockDateStr > options.until) return false;
3869
3849
  return true;
3870
- }) : blocks;
3871
- return sortByDate(dateFiltered, (block) => block.startTime, options?.order);
3850
+ }) : blocks, (block) => block.startTime, options?.order);
3872
3851
  } catch (_) {
3873
3852
  _usingCtx6.e = _;
3874
3853
  } finally {
3875
3854
  _usingCtx6.d();
3876
3855
  }
3877
3856
  }
3878
- export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CLAUDE_PROJECTS_DIR_NAME, CONFIG_FILE_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, DEFAULT_CONTEXT_USAGE_THRESHOLDS, DEFAULT_LOCALE, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, DEFAULT_SESSION_DURATION_HOURS, MAX_REFRESH_INTERVAL_SECONDS, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, WEEK_DAYS, __commonJSMin, __require$1 as __require, __toESM, _usingCtx, andThen, bucketUsageSchema, calculateBurnRate, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, fail, filterRecentBlocks, formatDateCompact, getClaudePaths, getEarliestTimestamp, getFileModifiedTime, getUsageLimitResetTime, glob, globUsageFiles, identifySessionBlocks, inspect, inspectError, isFailure, isSuccess, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, map, modelBreakdownSchema, monthlyUsageSchema, pipe, projectBlockUsage, sessionUsageSchema, sortFilesByTimestamp, succeed, toArray, transcriptMessageSchema, transcriptUsageSchema, try_, uniq, unreachable, unwrap, usageDataSchema, weeklyUsageSchema };
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 };