ccusage 17.1.3 → 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.
@@ -2190,6 +2190,7 @@ declare function createUniqueHash(data: UsageData): string | null;
2190
2190
  /**
2191
2191
  * Extract the earliest timestamp from a JSONL file
2192
2192
  * Scans through the file until it finds a valid timestamp
2193
+ * Uses streaming to handle large files without loading entire content into memory
2193
2194
  */
2194
2195
  declare function getEarliestTimestamp(filePath: string): Promise<Date | null>;
2195
2196
  /**
@@ -2304,4 +2305,4 @@ declare function calculateContextTokens(transcriptPath: string, modelId?: string
2304
2305
  */
2305
2306
  declare function loadSessionBlockData(options?: LoadOptions): Promise<SessionBlock[]>;
2306
2307
  //#endregion
2307
- export { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema };
2308
+ export { sessionUsageSchema as A, loadMonthlyUsageData as C, loadWeeklyUsageData as D, loadSessionUsageById as E, weeklyUsageSchema as F, transcriptMessageSchema as M, transcriptUsageSchema as N, modelBreakdownSchema as O, usageDataSchema as P, loadDailyUsageData as S, loadSessionData as T, getClaudePaths as _, LoadOptions as a, globUsageFiles as b, SessionUsage as c, bucketUsageSchema as d, calculateContextTokens as f, extractProjectFromPath as g, dailyUsageSchema as h, GlobResult as i, sortFilesByTimestamp as j, monthlyUsageSchema as k, UsageData as l, createUniqueHash as m, DailyUsage as n, ModelBreakdown as o, calculateCostForEntry as p, DateFilter as r, MonthlyUsage as s, BucketUsage as t, WeeklyUsage as u, getEarliestTimestamp as v, loadSessionBlockData as w, loadBucketUsageData as x, getUsageLimitResetTime as y };
@@ -1,2 +1,2 @@
1
- import { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema } from "./data-loader-D_hlygEz.js";
1
+ import { A as sessionUsageSchema, C as loadMonthlyUsageData, D as loadWeeklyUsageData, E as loadSessionUsageById, F as weeklyUsageSchema, M as transcriptMessageSchema, N as transcriptUsageSchema, O as modelBreakdownSchema, P as usageDataSchema, S as loadDailyUsageData, T as loadSessionData, _ as getClaudePaths, a as LoadOptions, b as globUsageFiles, c as SessionUsage, d as bucketUsageSchema, f as calculateContextTokens, g as extractProjectFromPath, h as dailyUsageSchema, i as GlobResult, j as sortFilesByTimestamp, k as monthlyUsageSchema, l as UsageData, m as createUniqueHash, n as DailyUsage, o as ModelBreakdown, p as calculateCostForEntry, r as DateFilter, s as MonthlyUsage, t as BucketUsage, u as WeeklyUsage, v as getEarliestTimestamp, w as loadSessionBlockData, x as loadBucketUsageData, y as getUsageLimitResetTime } from "./data-loader-qw155z_a.js";
2
2
  export { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema };
@@ -1,4 +1,4 @@
1
- import { bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema } from "./data-loader-BGg_9orY.js";
2
- import "./_types-CV6z8-9_.js";
3
- import "./logger-Dti-igUw.js";
1
+ import { C as transcriptUsageSchema, S as transcriptMessageSchema, T as weeklyUsageSchema, _ as loadWeeklyUsageData, a as dailyUsageSchema, b as sessionUsageSchema, c as getEarliestTimestamp, d as loadBucketUsageData, f as loadDailyUsageData, g as loadSessionUsageById, h as loadSessionData, i as createUniqueHash, l as getUsageLimitResetTime, m as loadSessionBlockData, n as calculateContextTokens, o as extractProjectFromPath, p as loadMonthlyUsageData, r as calculateCostForEntry, s as getClaudePaths, t as bucketUsageSchema, u as globUsageFiles, v as modelBreakdownSchema, w as usageDataSchema, x as sortFilesByTimestamp, y as monthlyUsageSchema } from "./data-loader-m6Bz_FZB.js";
2
+ import "./_types-Ds2jjKYK.js";
3
+ import "./logger-_iZ9qzce.js";
4
4
  export { bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema };
@@ -1,6 +1,6 @@
1
- import { CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, PricingFetcher, USAGE_DATA_GLOB_PATTERN, _usingCtx, getClaudePaths, glob, isFailure, try_, unwrap, usageDataSchema } from "./data-loader-BGg_9orY.js";
2
- import { safeParse } from "./_types-CV6z8-9_.js";
3
- import { logger } from "./logger-Dti-igUw.js";
1
+ import { B as CLAUDE_PROJECTS_DIR_NAME, F as _usingCtx, H as DEBUG_MATCH_THRESHOLD_PERCENT, Q as glob, X as USAGE_DATA_GLOB_PATTERN, et as unwrap, j as PricingFetcher, s as getClaudePaths, tt as try_, ut as isFailure, w as usageDataSchema } from "./data-loader-m6Bz_FZB.js";
2
+ import { P as safeParse } from "./_types-Ds2jjKYK.js";
3
+ import { n as logger } from "./logger-_iZ9qzce.js";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  async function detectMismatches(claudePath) {
@@ -145,4 +145,4 @@ function printMismatchReport(stats, sampleCount = 5) {
145
145
  }
146
146
  }
147
147
  }
148
- export { detectMismatches, printMismatchReport };
148
+ export { printMismatchReport as n, detectMismatches as t };
package/dist/debug.js CHANGED
@@ -1,5 +1,5 @@
1
- import "./data-loader-BGg_9orY.js";
2
- import "./_types-CV6z8-9_.js";
3
- import "./logger-Dti-igUw.js";
4
- import { detectMismatches, printMismatchReport } from "./debug-6nuaXAbb.js";
1
+ import "./data-loader-m6Bz_FZB.js";
2
+ import "./_types-Ds2jjKYK.js";
3
+ import "./logger-_iZ9qzce.js";
4
+ import { n as printMismatchReport, t as detectMismatches } from "./debug-DCs2jj0C.js";
5
5
  export { detectMismatches, printMismatchReport };
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CONFIG_FILE_NAME, 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, WEEK_DAYS, __commonJSMin, __require, __toESM, _usingCtx, andThen, calculateBurnRate, calculateContextTokens, calculateCostForEntry, createUniqueHash, fail, filterRecentBlocks, formatDateCompact, getClaudePaths, getEarliestTimestamp, getFileModifiedTime, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, inspect, inspectError, isFailure, isSuccess, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, map as map$2, pipe, projectBlockUsage, sortFilesByTimestamp, succeed, toArray, try_, uniq, unreachable, unwrap, usageDataSchema } from "./data-loader-BGg_9orY.js";
3
- import { CostModes, SortOrders, check, filterDateSchema, flatten, getTotalTokens, integer as integer$1, maxValue, minValue, number, parse as parse$1, pipe as pipe$1, safeParse, statuslineHookJsonSchema, string, transform, trim, union } from "./_types-CV6z8-9_.js";
4
- import { calculateTotals, createTotalsObject } from "./calculate-cost-CX9KwEZt.js";
5
- import { description, log, logger, name, version } from "./logger-Dti-igUw.js";
6
- import { detectMismatches, printMismatchReport } from "./debug-6nuaXAbb.js";
2
+ import { $ as uniq, A as projectBlockUsage, D as calculateBurnRate, E as DEFAULT_SESSION_DURATION_HOURS, F as _usingCtx, G as DEFAULT_RECENT_DAYS, I as BLOCKS_COMPACT_WIDTH_THRESHOLD, J as MIN_REFRESH_INTERVAL_SECONDS, K as DEFAULT_REFRESH_INTERVAL_SECONDS, L as BLOCKS_DEFAULT_TERMINAL_WIDTH, M as formatDateCompact, N as getFileModifiedTime, O as filterRecentBlocks, P as unreachable, R as BLOCKS_WARNING_THRESHOLD, U as DEFAULT_CONTEXT_USAGE_THRESHOLDS, V as CONFIG_FILE_NAME, W as DEFAULT_LOCALE, Y as MIN_RENDER_INTERVAL_MS, Z as WEEK_DAYS, _ as loadWeeklyUsageData, at as inspect, c as getEarliestTimestamp, ct as isSuccess, dt as toArray, et as unwrap, f as loadDailyUsageData, ft as __commonJSMin, g as loadSessionUsageById, h as loadSessionData, i as createUniqueHash, it as inspectError, j as PricingFetcher, k as identifySessionBlocks, l as getUsageLimitResetTime, lt as andThen, m as loadSessionBlockData, mt as __toESM, n as calculateContextTokens, nt as pipe, ot as fail, p as loadMonthlyUsageData, pt as __require, q as MAX_REFRESH_INTERVAL_SECONDS, r as calculateCostForEntry, rt as map$2, s as getClaudePaths, st as succeed, tt as try_, u as globUsageFiles, ut as isFailure, w as usageDataSchema, x as sortFilesByTimestamp, z as BURN_RATE_THRESHOLDS } from "./data-loader-m6Bz_FZB.js";
3
+ import { D as maxValue, E as integer$1, F as string, I as transform, L as trim, M as parse$1, N as pipe$1, O as minValue, P as safeParse, R as union, T as flatten, d as filterDateSchema, k as number, n as SortOrders, t as CostModes, w as check, y as statuslineHookJsonSchema, z as getTotalTokens } from "./_types-Ds2jjKYK.js";
4
+ import { n as createTotalsObject, t as calculateTotals } from "./calculate-cost-BI5czHMM.js";
5
+ import { a as version, i as name, n as logger, r as description, t as log } from "./logger-_iZ9qzce.js";
6
+ import { n as printMismatchReport, t as detectMismatches } from "./debug-DCs2jj0C.js";
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
8
  import a, { readFile, stat } from "node:fs/promises";
8
9
  import path, { join } from "node:path";
9
10
  import process$1 from "node:process";
10
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
11
11
  import { tmpdir } from "node:os";
12
12
  import { fileURLToPath } from "node:url";
13
13
  import { stripVTControlCharacters } from "node:util";
@@ -203,8 +203,7 @@ async function createCommandContext({ args, values, positionals, rest, argv: arg
203
203
  translate
204
204
  }));
205
205
  const defaultCommandResource = Object.entries(args).map(([key, arg]) => {
206
- const description$1 = arg.description || "";
207
- return [key, description$1];
206
+ return [key, arg.description || ""];
208
207
  }).reduce((res, [key, value$1]) => {
209
208
  res[resolveArgKey(key)] = value$1;
210
209
  return res;
@@ -728,8 +727,7 @@ function parse(token, option, schema) {
728
727
  }
729
728
  }
730
729
  function createRequireError(option, schema) {
731
- const message = schema.type === "positional" ? `Positional argument '${option}' is required` : `Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}is required`;
732
- return new ArgResolveError(message, option, "required", schema);
730
+ return new ArgResolveError(schema.type === "positional" ? `Positional argument '${option}' is required` : `Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}is required`, option, "required", schema);
733
731
  }
734
732
  var ArgResolveError = class extends Error {
735
733
  name;
@@ -971,8 +969,7 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
971
969
  break;
972
970
  case "center": {
973
971
  let right = Math.ceil(padlen / 2);
974
- let left = padlen - right;
975
- str$1 = repeat(pad$1, left) + str$1 + repeat(pad$1, right);
972
+ str$1 = repeat(pad$1, padlen - right) + str$1 + repeat(pad$1, right);
976
973
  break;
977
974
  }
978
975
  default:
@@ -1350,8 +1347,7 @@ var require_supports_colors = /* @__PURE__ */ __commonJSMin(((exports, module) =
1350
1347
  return min;
1351
1348
  }
1352
1349
  function getSupportLevel(stream) {
1353
- var level$1 = supportsColor(stream);
1354
- return translateLevel(level$1);
1350
+ return translateLevel(supportsColor(stream));
1355
1351
  }
1356
1352
  module.exports = {
1357
1353
  supportsColor: getSupportLevel,
@@ -2162,13 +2158,12 @@ var require_layout_manager = /* @__PURE__ */ __commonJSMin(((exports, module) =>
2162
2158
  let yMin1 = cell1.y;
2163
2159
  let yMax1 = cell1.y - 1 + (cell1.rowSpan || 1);
2164
2160
  let yMin2 = cell2.y;
2165
- let yMax2 = cell2.y - 1 + (cell2.rowSpan || 1);
2166
- let yConflict = !(yMin1 > yMax2 || yMin2 > yMax1);
2161
+ let yConflict = !(yMin1 > cell2.y - 1 + (cell2.rowSpan || 1) || yMin2 > yMax1);
2167
2162
  let xMin1 = cell1.x;
2168
2163
  let xMax1 = cell1.x - 1 + (cell1.colSpan || 1);
2169
2164
  let xMin2 = cell2.x;
2170
- let xMax2 = cell2.x - 1 + (cell2.colSpan || 1);
2171
- return yConflict && !(xMin1 > xMax2 || xMin2 > xMax1);
2165
+ let xConflict = !(xMin1 > cell2.x - 1 + (cell2.colSpan || 1) || xMin2 > xMax1);
2166
+ return yConflict && xConflict;
2172
2167
  }
2173
2168
  function conflictExists(rows, x, y) {
2174
2169
  let i_max = Math.min(rows.length - 1, y);
@@ -2607,7 +2602,7 @@ var ResponsiveTable = class {
2607
2602
  const adjustedWidths = columnWidths.map((width, index) => {
2608
2603
  const align = colAligns[index];
2609
2604
  let adjustedWidth = Math.floor(width * scaleFactor);
2610
- if (align === "right") adjustedWidth = Math.max(adjustedWidth, 10);
2605
+ if (align === "right") adjustedWidth = Math.max(adjustedWidth, 14);
2611
2606
  else if (index === 0) adjustedWidth = Math.max(adjustedWidth, 10);
2612
2607
  else if (index === 1) adjustedWidth = Math.max(adjustedWidth, 12);
2613
2608
  else adjustedWidth = Math.max(adjustedWidth, 8);
@@ -3743,9 +3738,7 @@ function prettyMilliseconds(milliseconds, options) {
3743
3738
  add(Number.parseFloat(millisecondsString), "millisecond", "ms", millisecondsString);
3744
3739
  }
3745
3740
  } else {
3746
- const seconds = (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) / 1e3 % 60;
3747
- const secondsDecimalDigits = typeof options.secondsDecimalDigits === "number" ? options.secondsDecimalDigits : 1;
3748
- const secondsFixed = floorDecimals(seconds, secondsDecimalDigits);
3741
+ const secondsFixed = floorDecimals((isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) / 1e3 % 60, typeof options.secondsDecimalDigits === "number" ? options.secondsDecimalDigits : 1);
3749
3742
  const secondsString = options.keepDecimalsOnWholeSeconds ? secondsFixed : secondsFixed.replace(/\.0+$/, "");
3750
3743
  add(Number.parseFloat(secondsString), "second", "s", secondsString);
3751
3744
  }
@@ -4148,8 +4141,7 @@ const blocksCommand = define({
4148
4141
  },
4149
4142
  toKebab: true,
4150
4143
  async run(ctx) {
4151
- const config = loadConfig(ctx.values.config, ctx.values.debug);
4152
- const mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug);
4144
+ const mergedOptions = mergeConfigWithArgs(ctx, loadConfig(ctx.values.config, ctx.values.debug), ctx.values.debug);
4153
4145
  const useJson = mergedOptions.json || mergedOptions.jq != null;
4154
4146
  if (useJson) logger.level = 0;
4155
4147
  if (ctx.values.sessionLength <= 0) {
@@ -4488,8 +4480,7 @@ const dailyCommand = define({
4488
4480
  }
4489
4481
  },
4490
4482
  async run(ctx) {
4491
- const config = loadConfig(ctx.values.config, ctx.values.debug);
4492
- const mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug);
4483
+ const mergedOptions = mergeConfigWithArgs(ctx, loadConfig(ctx.values.config, ctx.values.debug), ctx.values.debug);
4493
4484
  let projectAliases;
4494
4485
  if (mergedOptions.projectAliases != null && typeof mergedOptions.projectAliases === "string") {
4495
4486
  projectAliases = /* @__PURE__ */ new Map();
@@ -4513,10 +4504,7 @@ const dailyCommand = define({
4513
4504
  process$1.exit(0);
4514
4505
  }
4515
4506
  const totals = calculateTotals(dailyData);
4516
- if (mergedOptions.debug && !useJson) {
4517
- const mismatchStats = await detectMismatches(void 0);
4518
- printMismatchReport(mismatchStats, mergedOptions.debugSamples);
4519
- }
4507
+ if (mergedOptions.debug && !useJson) printMismatchReport(await detectMismatches(void 0), mergedOptions.debugSamples);
4520
4508
  if (useJson) {
4521
4509
  const jsonOutput = Boolean(mergedOptions.instances) && dailyData.some((d) => d.project != null) ? {
4522
4510
  projects: groupByProject(dailyData),
@@ -4546,12 +4534,11 @@ const dailyCommand = define({
4546
4534
  } else log(JSON.stringify(jsonOutput, null, 2));
4547
4535
  } else {
4548
4536
  logger.box("Claude Code Token Usage Report - Daily");
4549
- const tableConfig = {
4537
+ const table = createUsageReportTable({
4550
4538
  firstColumnName: "Date",
4551
4539
  dateFormatter: (dateStr) => formatDateCompact(dateStr, mergedOptions.timezone, mergedOptions.locale ?? void 0),
4552
4540
  forceCompact: ctx.values.compact
4553
- };
4554
- const table = createUsageReportTable(tableConfig);
4541
+ });
4555
4542
  if (Boolean(mergedOptions.instances) && dailyData.some((d) => d.project != null)) {
4556
4543
  const projectGroups = groupDataByProject(dailyData);
4557
4544
  let isFirstProject = true;
@@ -4624,8 +4611,7 @@ const monthlyCommand = define({
4624
4611
  description: "Show usage report grouped by month",
4625
4612
  ...sharedCommandConfig,
4626
4613
  async run(ctx) {
4627
- const config = loadConfig(ctx.values.config, ctx.values.debug);
4628
- const mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug);
4614
+ const mergedOptions = mergeConfigWithArgs(ctx, loadConfig(ctx.values.config, ctx.values.debug), ctx.values.debug);
4629
4615
  const useJson = Boolean(mergedOptions.json) || mergedOptions.jq != null;
4630
4616
  if (useJson) logger.level = 0;
4631
4617
  const monthlyData = await loadMonthlyUsageData(mergedOptions);
@@ -4645,10 +4631,7 @@ const monthlyCommand = define({
4645
4631
  process$1.exit(0);
4646
4632
  }
4647
4633
  const totals = calculateTotals(monthlyData);
4648
- if (mergedOptions.debug && !useJson) {
4649
- const mismatchStats = await detectMismatches(void 0);
4650
- printMismatchReport(mismatchStats, mergedOptions.debugSamples);
4651
- }
4634
+ if (mergedOptions.debug && !useJson) printMismatchReport(await detectMismatches(void 0), mergedOptions.debugSamples);
4652
4635
  if (useJson) {
4653
4636
  const jsonOutput = {
4654
4637
  monthly: monthlyData.map((data) => ({
@@ -4674,12 +4657,11 @@ const monthlyCommand = define({
4674
4657
  } else log(JSON.stringify(jsonOutput, null, 2));
4675
4658
  } else {
4676
4659
  logger.box("Claude Code Token Usage Report - Monthly");
4677
- const tableConfig = {
4660
+ const table = createUsageReportTable({
4678
4661
  firstColumnName: "Month",
4679
4662
  dateFormatter: (dateStr) => formatDateCompact(dateStr, mergedOptions.timezone, mergedOptions.locale ?? DEFAULT_LOCALE),
4680
4663
  forceCompact: ctx.values.compact
4681
- };
4682
- const table = createUsageReportTable(tableConfig);
4664
+ });
4683
4665
  for (const data of monthlyData) {
4684
4666
  const row = formatUsageDataRow(data.month, {
4685
4667
  inputTokens: data.inputTokens,
@@ -4805,8 +4787,7 @@ const sessionCommand = define({
4805
4787
  },
4806
4788
  toKebab: true,
4807
4789
  async run(ctx) {
4808
- const config = loadConfig(ctx.values.config, ctx.values.debug);
4809
- const mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug);
4790
+ const mergedOptions = mergeConfigWithArgs(ctx, loadConfig(ctx.values.config, ctx.values.debug), ctx.values.debug);
4810
4791
  const useJson = mergedOptions.json || mergedOptions.jq != null;
4811
4792
  if (useJson) logger.level = 0;
4812
4793
  if (mergedOptions.id != null) return handleSessionIdLookup({ values: {
@@ -4831,10 +4812,7 @@ const sessionCommand = define({
4831
4812
  process$1.exit(0);
4832
4813
  }
4833
4814
  const totals = calculateTotals(sessionData);
4834
- if (ctx.values.debug && !useJson) {
4835
- const mismatchStats = await detectMismatches(void 0);
4836
- printMismatchReport(mismatchStats, ctx.values.debugSamples);
4837
- }
4815
+ if (ctx.values.debug && !useJson) printMismatchReport(await detectMismatches(void 0), ctx.values.debugSamples);
4838
4816
  if (useJson) {
4839
4817
  const jsonOutput = {
4840
4818
  sessions: sessionData.map((data) => ({
@@ -4862,13 +4840,12 @@ const sessionCommand = define({
4862
4840
  } else log(JSON.stringify(jsonOutput, null, 2));
4863
4841
  } else {
4864
4842
  logger.box("Claude Code Token Usage Report - By Session");
4865
- const tableConfig = {
4843
+ const table = createUsageReportTable({
4866
4844
  firstColumnName: "Session",
4867
4845
  includeLastActivity: true,
4868
4846
  dateFormatter: (dateStr) => formatDateCompact(dateStr, ctx.values.timezone, ctx.values.locale),
4869
4847
  forceCompact: ctx.values.compact
4870
- };
4871
- const table = createUsageReportTable(tableConfig);
4848
+ });
4872
4849
  let maxSessionLength = 0;
4873
4850
  for (const data of sessionData) {
4874
4851
  const sessionDisplay = data.sessionId.split("-").slice(-2).join("-");
@@ -5212,8 +5189,7 @@ function infinity(scanner) {
5212
5189
  if (!match) return failure();
5213
5190
  const string$1 = match[0];
5214
5191
  scanner.next(string$1.length);
5215
- const value$1 = INFINITY_MAP.get(string$1);
5216
- return success(value$1);
5192
+ return success(INFINITY_MAP.get(string$1));
5217
5193
  }
5218
5194
  const NAN_REGEXP = /[+-]?nan\b/y;
5219
5195
  function nan(scanner) {
@@ -5820,11 +5796,10 @@ function createSchema({ explicitTypes = [], implicitTypes = [], include }) {
5820
5796
  implicitTypes.push(...include.implicitTypes);
5821
5797
  explicitTypes.push(...include.explicitTypes);
5822
5798
  }
5823
- const typeMap = createTypeMap(implicitTypes, explicitTypes);
5824
5799
  return {
5825
5800
  implicitTypes,
5826
5801
  explicitTypes,
5827
- typeMap
5802
+ typeMap: createTypeMap(implicitTypes, explicitTypes)
5828
5803
  };
5829
5804
  }
5830
5805
  const FAILSAFE_SCHEMA = createSchema({ explicitTypes: [
@@ -5832,7 +5807,7 @@ const FAILSAFE_SCHEMA = createSchema({ explicitTypes: [
5832
5807
  seq,
5833
5808
  map
5834
5809
  ] });
5835
- const JSON_SCHEMA = createSchema({
5810
+ const CORE_SCHEMA = createSchema({ include: createSchema({
5836
5811
  implicitTypes: [
5837
5812
  nil,
5838
5813
  bool,
@@ -5840,8 +5815,7 @@ const JSON_SCHEMA = createSchema({
5840
5815
  float
5841
5816
  ],
5842
5817
  include: FAILSAFE_SCHEMA
5843
- });
5844
- const CORE_SCHEMA = createSchema({ include: JSON_SCHEMA });
5818
+ }) });
5845
5819
  const DEFAULT_SCHEMA = createSchema({
5846
5820
  explicitTypes: [
5847
5821
  binary,
@@ -6043,16 +6017,14 @@ const statuslineCommand = define({
6043
6017
  async run(ctx) {
6044
6018
  logger.level = 0;
6045
6019
  if (ctx.values.contextLowThreshold >= ctx.values.contextMediumThreshold) throw new Error(`Context low threshold (${ctx.values.contextLowThreshold}) must be less than medium threshold (${ctx.values.contextMediumThreshold})`);
6046
- const config = loadConfig(ctx.values.config, ctx.values.debug);
6047
- const mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug);
6020
+ const mergedOptions = mergeConfigWithArgs(ctx, loadConfig(ctx.values.config, ctx.values.debug), ctx.values.debug);
6048
6021
  const refreshInterval = mergedOptions.refreshInterval;
6049
6022
  const stdin$2 = await getStdin();
6050
6023
  if (stdin$2.length === 0) {
6051
6024
  log("❌ No input provided");
6052
6025
  process$1.exit(1);
6053
6026
  }
6054
- const hookDataJson = JSON.parse(stdin$2.trim());
6055
- const hookDataParseResult = safeParse(statuslineHookJsonSchema, hookDataJson);
6027
+ const hookDataParseResult = safeParse(statuslineHookJsonSchema, JSON.parse(stdin$2.trim()));
6056
6028
  if (!hookDataParseResult.success) {
6057
6029
  log("❌ Invalid input format:", flatten(hookDataParseResult.issues));
6058
6030
  process$1.exit(1);
@@ -6122,14 +6094,10 @@ const statuslineCommand = define({
6122
6094
  catch: (error) => error
6123
6095
  })(), map$2((sessionCost$1) => sessionCost$1?.totalCost), inspectError((error) => logger.error("Failed to load session data:", error)), unwrap(void 0));
6124
6096
  };
6125
- if (costSource === "both") {
6126
- const ccCost$1 = hookData.cost?.total_cost_usd;
6127
- const ccusageCost$1 = await getCcusageCost();
6128
- return {
6129
- ccCost: ccCost$1,
6130
- ccusageCost: ccusageCost$1
6131
- };
6132
- }
6097
+ if (costSource === "both") return {
6098
+ ccCost: hookData.cost?.total_cost_usd,
6099
+ ccusageCost: await getCcusageCost()
6100
+ };
6133
6101
  if (costSource === "cc") return { sessionCost: hookData.cost?.total_cost_usd };
6134
6102
  if (costSource === "ccusage") return { sessionCost: await getCcusageCost() };
6135
6103
  if (costSource === "auto") {
@@ -6173,37 +6141,36 @@ const statuslineCommand = define({
6173
6141
  const blockCost = activeBlock.costUSD;
6174
6142
  const blockInfo$1 = `${formatCurrency(blockCost)} block (${formatRemainingTime(remaining)})`;
6175
6143
  const burnRate = calculateBurnRate(activeBlock);
6176
- const burnRateInfo$1 = burnRate != null ? (() => {
6177
- const renderEmojiStatus = ctx.values.visualBurnRate === "emoji" || ctx.values.visualBurnRate === "emoji-text";
6178
- const renderTextStatus = ctx.values.visualBurnRate === "text" || ctx.values.visualBurnRate === "emoji-text";
6179
- const costPerHour = burnRate.costPerHour;
6180
- const costPerHourStr = `${formatCurrency(costPerHour)}/hr`;
6181
- const burnStatus = burnRate.tokensPerMinuteForIndicator < 2e3 ? "normal" : burnRate.tokensPerMinuteForIndicator < 5e3 ? "moderate" : "high";
6182
- const { emoji, textValue, coloredString } = {
6183
- normal: {
6184
- emoji: "🟢",
6185
- textValue: "Normal",
6186
- coloredString: import_picocolors.default.green
6187
- },
6188
- moderate: {
6189
- emoji: "⚠️",
6190
- textValue: "Moderate",
6191
- coloredString: import_picocolors.default.yellow
6192
- },
6193
- high: {
6194
- emoji: "🚨",
6195
- textValue: "High",
6196
- coloredString: import_picocolors.default.red
6197
- }
6198
- }[burnStatus];
6199
- const burnRateOutputSegments = [coloredString(costPerHourStr)];
6200
- if (renderEmojiStatus) burnRateOutputSegments.push(emoji);
6201
- if (renderTextStatus) burnRateOutputSegments.push(coloredString(`(${textValue})`));
6202
- return ` | 🔥 ${burnRateOutputSegments.join(" ")}`;
6203
- })() : "";
6204
6144
  return {
6205
6145
  blockInfo: blockInfo$1,
6206
- burnRateInfo: burnRateInfo$1
6146
+ burnRateInfo: burnRate != null ? (() => {
6147
+ const renderEmojiStatus = ctx.values.visualBurnRate === "emoji" || ctx.values.visualBurnRate === "emoji-text";
6148
+ const renderTextStatus = ctx.values.visualBurnRate === "text" || ctx.values.visualBurnRate === "emoji-text";
6149
+ const costPerHour = burnRate.costPerHour;
6150
+ const costPerHourStr = `${formatCurrency(costPerHour)}/hr`;
6151
+ const burnStatus = burnRate.tokensPerMinuteForIndicator < 2e3 ? "normal" : burnRate.tokensPerMinuteForIndicator < 5e3 ? "moderate" : "high";
6152
+ const { emoji, textValue, coloredString } = {
6153
+ normal: {
6154
+ emoji: "🟢",
6155
+ textValue: "Normal",
6156
+ coloredString: import_picocolors.default.green
6157
+ },
6158
+ moderate: {
6159
+ emoji: "⚠️",
6160
+ textValue: "Moderate",
6161
+ coloredString: import_picocolors.default.yellow
6162
+ },
6163
+ high: {
6164
+ emoji: "🚨",
6165
+ textValue: "High",
6166
+ coloredString: import_picocolors.default.red
6167
+ }
6168
+ }[burnStatus];
6169
+ const burnRateOutputSegments = [coloredString(costPerHourStr)];
6170
+ if (renderEmojiStatus) burnRateOutputSegments.push(emoji);
6171
+ if (renderTextStatus) burnRateOutputSegments.push(coloredString(`(${textValue})`));
6172
+ return ` | 🔥 ${burnRateOutputSegments.join(" ")}`;
6173
+ })() : ""
6207
6174
  };
6208
6175
  }
6209
6176
  return {
@@ -6222,16 +6189,10 @@ const statuslineCommand = define({
6222
6189
  const coloredPercentage = (contextResult.percentage < ctx.values.contextLowThreshold ? import_picocolors.default.green : contextResult.percentage < ctx.values.contextMediumThreshold ? import_picocolors.default.yellow : import_picocolors.default.red)(`${contextResult.percentage}%`);
6223
6190
  return `${contextResult.inputTokens.toLocaleString()} (${coloredPercentage})`;
6224
6191
  }), unwrap(void 0));
6225
- const modelName = hookData.model.display_name;
6226
- const sessionDisplay = (() => {
6227
- if (ccCost != null || ccusageCost != null) {
6228
- const ccDisplay = ccCost != null ? formatCurrency(ccCost) : "N/A";
6229
- const ccusageDisplay = ccusageCost != null ? formatCurrency(ccusageCost) : "N/A";
6230
- return `(${ccDisplay} cc / ${ccusageDisplay} ccusage)`;
6231
- }
6192
+ return `🤖 ${hookData.model.display_name} | 💰 ${(() => {
6193
+ if (ccCost != null || ccusageCost != null) return `(${ccCost != null ? formatCurrency(ccCost) : "N/A"} cc / ${ccusageCost != null ? formatCurrency(ccusageCost) : "N/A"} ccusage)`;
6232
6194
  return sessionCost != null ? formatCurrency(sessionCost) : "N/A";
6233
- })();
6234
- return `🤖 ${modelName} | 💰 ${sessionDisplay} session / ${formatCurrency(todayCost)} today / ${blockInfo}${burnRateInfo} | 🧠 ${contextInfo ?? "N/A"}`;
6195
+ })()} session / ${formatCurrency(todayCost)} today / ${blockInfo}${burnRateInfo} | 🧠 ${contextInfo ?? "N/A"}`;
6235
6196
  },
6236
6197
  catch: (error) => error
6237
6198
  })());
@@ -6289,8 +6250,7 @@ const weeklyCommand = define({
6289
6250
  },
6290
6251
  toKebab: true,
6291
6252
  async run(ctx) {
6292
- const config = loadConfig(ctx.values.config, ctx.values.debug);
6293
- const mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug);
6253
+ const mergedOptions = mergeConfigWithArgs(ctx, loadConfig(ctx.values.config, ctx.values.debug), ctx.values.debug);
6294
6254
  const useJson = Boolean(mergedOptions.json) || mergedOptions.jq != null;
6295
6255
  if (useJson) logger.level = 0;
6296
6256
  const weeklyData = await loadWeeklyUsageData(mergedOptions);
@@ -6310,10 +6270,7 @@ const weeklyCommand = define({
6310
6270
  process$1.exit(0);
6311
6271
  }
6312
6272
  const totals = calculateTotals(weeklyData);
6313
- if (mergedOptions.debug && !useJson) {
6314
- const mismatchStats = await detectMismatches(void 0);
6315
- printMismatchReport(mismatchStats, mergedOptions.debugSamples);
6316
- }
6273
+ if (mergedOptions.debug && !useJson) printMismatchReport(await detectMismatches(void 0), mergedOptions.debugSamples);
6317
6274
  if (useJson) {
6318
6275
  const jsonOutput = {
6319
6276
  weekly: weeklyData.map((data) => ({
@@ -6339,12 +6296,11 @@ const weeklyCommand = define({
6339
6296
  } else log(JSON.stringify(jsonOutput, null, 2));
6340
6297
  } else {
6341
6298
  logger.box("Claude Code Token Usage Report - Weekly");
6342
- const tableConfig = {
6299
+ const table = createUsageReportTable({
6343
6300
  firstColumnName: "Week",
6344
6301
  dateFormatter: (dateStr) => formatDateCompact(dateStr, mergedOptions.timezone, mergedOptions.locale ?? void 0),
6345
6302
  forceCompact: ctx.values.compact
6346
- };
6347
- const table = createUsageReportTable(tableConfig);
6303
+ });
6348
6304
  for (const data of weeklyData) {
6349
6305
  const row = formatUsageDataRow(data.week, {
6350
6306
  inputTokens: data.inputTokens,
@@ -326,11 +326,10 @@ ${indent}`);
326
326
  return causedPrefix + message + "\n" + stack + causedError;
327
327
  }
328
328
  formatArgs(args, opts) {
329
- const _args = args.map((arg) => {
329
+ return formatWithOptions(opts, ...args.map((arg) => {
330
330
  if (arg && typeof arg.stack === "string") return this.formatError(arg, opts);
331
331
  return arg;
332
- });
333
- return formatWithOptions(opts, ..._args);
332
+ }));
334
333
  }
335
334
  formatDate(date, opts) {
336
335
  return opts.date ? date.toLocaleTimeString() : "";
@@ -352,11 +351,10 @@ ${indent}`);
352
351
  ]);
353
352
  }
354
353
  log(logObj, ctx) {
355
- const line = this.formatLogObj(logObj, {
354
+ return writeStream(this.formatLogObj(logObj, {
356
355
  columns: ctx.options.stdout.columns || 0,
357
356
  ...ctx.options.formatOptions
358
- });
359
- return writeStream(line + "\n", logObj.level < 2 ? ctx.options.stderr || process.stderr : ctx.options.stdout || process.stdout);
357
+ }) + "\n", logObj.level < 2 ? ctx.options.stderr || process.stderr : ctx.options.stdout || process.stdout);
360
358
  }
361
359
  };
362
360
  const { env = {}, argv = [], platform = "" } = typeof process === "undefined" ? {} : process;
@@ -550,8 +548,7 @@ const r = Object.create(null), i = (e) => globalThis.process?.env || import.meta
550
548
  return i()[s$1] ?? r[s$1];
551
549
  },
552
550
  has(e, s$1) {
553
- const E = i();
554
- return s$1 in E || s$1 in r;
551
+ return s$1 in i() || s$1 in r;
555
552
  },
556
553
  set(e, s$1, E) {
557
554
  const B = i(true);
@@ -848,7 +845,7 @@ function createConsola$1(options = {}) {
848
845
  defaults: { level },
849
846
  stdout: process.stdout,
850
847
  stderr: process.stderr,
851
- prompt: (...args) => import("./prompt-BCI--RF-.js").then((m) => m.prompt(...args)),
848
+ prompt: (...args) => import("./prompt-HWGZJndy.js").then((m) => m.prompt(...args)),
852
849
  reporters: options.reporters || [options.fancy ?? !(T || R) ? new FancyReporter() : new BasicReporter()],
853
850
  ...options
854
851
  });
@@ -869,8 +866,8 @@ function createLogger(name$1) {
869
866
  }
870
867
  const log = console.log;
871
868
  var name = "ccusage";
872
- var version = "17.1.3";
869
+ var version = "17.1.4";
873
870
  var description = "Usage analysis tool for Claude Code";
874
871
  const logger = createLogger(name);
875
872
  const log$1 = log;
876
- export { description, log$1 as log, logger, name, version };
873
+ export { version as a, name as i, logger as n, description as r, log$1 as t };
package/dist/logger.js CHANGED
@@ -1,2 +1,2 @@
1
- import { log, logger } from "./logger-Dti-igUw.js";
1
+ import { n as logger, t as log } from "./logger-_iZ9qzce.js";
2
2
  export { log, logger };
@@ -1,6 +1,6 @@
1
1
  import process$1, { stdin, stdout } from "node:process";
2
- import { WriteStream } from "node:tty";
3
2
  import f from "node:readline";
3
+ import { WriteStream } from "node:tty";
4
4
  function getDefaultExportFromCjs(x$1) {
5
5
  return x$1 && x$1.__esModule && Object.prototype.hasOwnProperty.call(x$1, "default") ? x$1["default"] : x$1;
6
6
  }
@@ -37,28 +37,26 @@ function requireSrc() {
37
37
  save: `${ESC}7`,
38
38
  restore: `${ESC}8`
39
39
  };
40
- const scroll = {
41
- up: (count = 1) => `${CSI}S`.repeat(count),
42
- down: (count = 1) => `${CSI}T`.repeat(count)
43
- };
44
- const erase = {
45
- screen: `${CSI}2J`,
46
- up: (count = 1) => `${CSI}1J`.repeat(count),
47
- down: (count = 1) => `${CSI}J`.repeat(count),
48
- line: `${CSI}2K`,
49
- lineEnd: `${CSI}K`,
50
- lineStart: `${CSI}1K`,
51
- lines(count) {
52
- let clear = "";
53
- for (let i = 0; i < count; i++) clear += this.line + (i < count - 1 ? cursor.up() : "");
54
- if (count) clear += cursor.left;
55
- return clear;
56
- }
57
- };
58
40
  src = {
59
41
  cursor,
60
- scroll,
61
- erase,
42
+ scroll: {
43
+ up: (count = 1) => `${CSI}S`.repeat(count),
44
+ down: (count = 1) => `${CSI}T`.repeat(count)
45
+ },
46
+ erase: {
47
+ screen: `${CSI}2J`,
48
+ up: (count = 1) => `${CSI}1J`.repeat(count),
49
+ down: (count = 1) => `${CSI}J`.repeat(count),
50
+ line: `${CSI}2K`,
51
+ lineEnd: `${CSI}K`,
52
+ lineStart: `${CSI}1K`,
53
+ lines(count) {
54
+ let clear = "";
55
+ for (let i = 0; i < count; i++) clear += this.line + (i < count - 1 ? cursor.up() : "");
56
+ if (count) clear += cursor.left;
57
+ return clear;
58
+ }
59
+ },
62
60
  beep
63
61
  };
64
62
  return src;
@@ -842,4 +840,4 @@ async function prompt(message, opts = {}) {
842
840
  }).then(handleCancel);
843
841
  throw new Error(`Unknown prompt type: ${opts.type}`);
844
842
  }
845
- export { prompt };
843
+ export { kCancel, prompt };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccusage",
3
- "version": "17.1.3",
3
+ "version": "17.1.4",
4
4
  "description": "Usage analysis tool for Claude Code",
5
5
  "homepage": "https://github.com/ryoppippi/ccusage#readme",
6
6
  "bugs": {