ccusage 15.6.0 → 15.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,6 +63,8 @@ ccusage blocks --live # Real-time usage dashboard
63
63
  ccusage daily --since 20250525 --until 20250530
64
64
  ccusage daily --json # JSON output
65
65
  ccusage daily --breakdown # Per-model cost breakdown
66
+ ccusage daily --timezone UTC # Use UTC timezone
67
+ ccusage daily --locale ja-JP # Use Japanese locale for date/time formatting
66
68
 
67
69
  # Project analysis
68
70
  ccusage daily --instances # Group by project/instance
@@ -90,6 +92,8 @@ ccusage daily --instances --project myproject --json # Combined usage
90
92
  - 🌐 **Offline Mode**: Use pre-cached pricing data without network connectivity with `--offline` (Claude models only)
91
93
  - 🔌 **MCP Integration**: Built-in Model Context Protocol server for integration with other tools
92
94
  - 🏗️ **Multi-Instance Support**: Group usage by project with `--instances` flag and filter by specific projects
95
+ - 🌍 **Timezone Support**: Configure timezone for date grouping with `--timezone` option
96
+ - 🌐 **Locale Support**: Customize date/time formatting with `--locale` option (e.g., en-US, ja-JP, de-DE)
93
97
  - 🚀 **Ultra-Small Bundle**: Unlike other CLI tools, we pay extreme attention to bundle size - incredibly small even without minification!
94
98
 
95
99
  ## Documentation
@@ -1,5 +1,5 @@
1
1
  import "./pricing-fetcher-AYfCy7g-.js";
2
- import { DailyUsage, MonthlyUsage, SessionUsage, WeeklyUsage } from "./data-loader-DZMUuqrf.js";
2
+ import { DailyUsage, MonthlyUsage, SessionUsage, WeeklyUsage } from "./data-loader-De3CFZ54.js";
3
3
 
4
4
  //#region src/_token-utils.d.ts
5
5
 
@@ -1,7 +1,7 @@
1
- import { CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_RECENT_DAYS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx } from "./pricing-fetcher-CNjC0nXU.js";
1
+ import { CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_RECENT_DAYS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx } from "./pricing-fetcher-BlH7npmF.js";
2
2
  import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
3
3
  import { activityDateSchema, arrayType, booleanType, createBucket, createDailyDate, createMonthlyDate, createProjectPath, createSessionId, createWeeklyDate, dailyDateSchema, isoTimestampSchema, messageIdSchema, modelNameSchema, monthlyDateSchema, numberType, objectType, projectPathSchema, requestIdSchema, sessionIdSchema, stringType, unionType, versionSchema, weeklyDateSchema } from "./_types-ed8-0BH6.js";
4
- import { logger } from "./logger-C35JCduT.js";
4
+ import { logger } from "./logger-DWlfa60j.js";
5
5
  import a, { readFile } from "node:fs/promises";
6
6
  import path, { posix } from "node:path";
7
7
  import process$1 from "node:process";
@@ -3575,41 +3575,56 @@ function extractUniqueModels(entries, getModel) {
3575
3575
  return uniq(entries.map(getModel).filter((m$1) => m$1 != null && m$1 !== "<synthetic>"));
3576
3576
  }
3577
3577
  /**
3578
- * Date formatter using Intl.DateTimeFormat for consistent formatting
3579
- * Using UTC to avoid timezone issues
3578
+ * Creates a date formatter with the specified timezone and locale
3579
+ * @param timezone - Timezone to use (e.g., 'UTC', 'America/New_York')
3580
+ * @param locale - Locale to use for formatting (e.g., 'en-US', 'ja-JP')
3581
+ * @returns Intl.DateTimeFormat instance
3580
3582
  */
3581
- const dateFormatter = new Intl.DateTimeFormat("en-CA", {
3582
- timeZone: "UTC",
3583
- year: "numeric",
3584
- month: "2-digit",
3585
- day: "2-digit"
3586
- });
3583
+ function createDateFormatter(timezone, locale) {
3584
+ return new Intl.DateTimeFormat(locale, {
3585
+ year: "numeric",
3586
+ month: "2-digit",
3587
+ day: "2-digit",
3588
+ timeZone: timezone
3589
+ });
3590
+ }
3591
+ /**
3592
+ * Creates a date parts formatter with the specified timezone and locale
3593
+ * @param timezone - Timezone to use
3594
+ * @param locale - Locale to use for formatting
3595
+ * @returns Intl.DateTimeFormat instance
3596
+ */
3597
+ function createDatePartsFormatter(timezone, locale) {
3598
+ return new Intl.DateTimeFormat(locale, {
3599
+ year: "numeric",
3600
+ month: "2-digit",
3601
+ day: "2-digit",
3602
+ timeZone: timezone
3603
+ });
3604
+ }
3587
3605
  /**
3588
3606
  * Formats a date string to YYYY-MM-DD format
3589
3607
  * @param dateStr - Input date string
3608
+ * @param timezone - Optional timezone to use for formatting
3609
+ * @param locale - Optional locale to use for formatting (defaults to 'en-CA' for YYYY-MM-DD format)
3590
3610
  * @returns Formatted date string in YYYY-MM-DD format
3591
3611
  */
3592
- function formatDate(dateStr) {
3612
+ function formatDate(dateStr, timezone, locale) {
3593
3613
  const date = new Date(dateStr);
3594
- return dateFormatter.format(date);
3614
+ const formatter = createDateFormatter(timezone, locale ?? "en-CA");
3615
+ return formatter.format(date);
3595
3616
  }
3596
3617
  /**
3597
- * Date parts formatter for extracting year, month, and day separately
3598
- */
3599
- const datePartsFormatter = new Intl.DateTimeFormat("en", {
3600
- timeZone: "UTC",
3601
- year: "numeric",
3602
- month: "2-digit",
3603
- day: "2-digit"
3604
- });
3605
- /**
3606
3618
  * Formats a date string to compact format with year on first line and month-day on second
3607
3619
  * @param dateStr - Input date string
3620
+ * @param timezone - Timezone to use for formatting (pass undefined to use system timezone)
3621
+ * @param locale - Locale to use for formatting
3608
3622
  * @returns Formatted date string with newline separator (YYYY\nMM-DD)
3609
3623
  */
3610
- function formatDateCompact(dateStr) {
3624
+ function formatDateCompact(dateStr, timezone, locale) {
3611
3625
  const date = new Date(dateStr);
3612
- const parts = datePartsFormatter.formatToParts(date);
3626
+ const formatter = createDatePartsFormatter(timezone, locale);
3627
+ const parts = formatter.formatToParts(date);
3613
3628
  const year = parts.find((p) => p.type === "year")?.value ?? "";
3614
3629
  const month = parts.find((p) => p.type === "month")?.value ?? "";
3615
3630
  const day = parts.find((p) => p.type === "day")?.value ?? "";
@@ -3769,7 +3784,7 @@ async function loadDailyUsageData(options) {
3769
3784
  const uniqueHash = createUniqueHash(data);
3770
3785
  if (isDuplicateEntry(uniqueHash, processedHashes)) continue;
3771
3786
  markAsProcessed(uniqueHash, processedHashes);
3772
- const date = formatDate(data.timestamp);
3787
+ const date = formatDate(data.timestamp, options?.timezone, "en-CA");
3773
3788
  const cost = fetcher != null ? await calculateCostForEntry(data, mode, fetcher) : data.costUSD ?? 0;
3774
3789
  const project = extractProjectFromPath(file);
3775
3790
  allEntries.push({
@@ -3875,7 +3890,7 @@ async function loadSessionData(options) {
3875
3890
  sessionId: createSessionId(latestEntry.sessionId),
3876
3891
  projectPath: createProjectPath(latestEntry.projectPath),
3877
3892
  ...totals,
3878
- lastActivity: formatDate(latestEntry.timestamp),
3893
+ lastActivity: formatDate(latestEntry.timestamp, options?.timezone, "en-CA"),
3879
3894
  versions: uniq(versions).sort(),
3880
3895
  modelsUsed,
3881
3896
  modelBreakdowns
@@ -4037,7 +4052,7 @@ async function loadSessionBlockData(options) {
4037
4052
  }
4038
4053
  const blocks = identifySessionBlocks(allEntries, options?.sessionDurationHours);
4039
4054
  const dateFiltered = options?.since != null && options.since !== "" || options?.until != null && options.until !== "" ? blocks.filter((block) => {
4040
- const blockDateStr = formatDate(block.startTime.toISOString()).replace(/-/g, "");
4055
+ const blockDateStr = formatDate(block.startTime.toISOString(), options?.timezone, "en-CA").replace(/-/g, "");
4041
4056
  if (options.since != null && options.since !== "" && blockDateStr < options.since) return false;
4042
4057
  if (options.until != null && options.until !== "" && blockDateStr > options.until) return false;
4043
4058
  return true;
@@ -574,15 +574,19 @@ type BucketUsage = z.infer<typeof bucketUsageSchema>;
574
574
  /**
575
575
  * Formats a date string to YYYY-MM-DD format
576
576
  * @param dateStr - Input date string
577
+ * @param timezone - Optional timezone to use for formatting
578
+ * @param locale - Optional locale to use for formatting (defaults to 'en-CA' for YYYY-MM-DD format)
577
579
  * @returns Formatted date string in YYYY-MM-DD format
578
580
  */
579
- declare function formatDate(dateStr: string): string;
581
+ declare function formatDate(dateStr: string, timezone?: string, locale?: string): string;
580
582
  /**
581
583
  * Formats a date string to compact format with year on first line and month-day on second
582
584
  * @param dateStr - Input date string
585
+ * @param timezone - Timezone to use for formatting (pass undefined to use system timezone)
586
+ * @param locale - Locale to use for formatting
583
587
  * @returns Formatted date string with newline separator (YYYY\nMM-DD)
584
588
  */
585
- declare function formatDateCompact(dateStr: string): string;
589
+ declare function formatDateCompact(dateStr: string, timezone: string | undefined, locale: string): string;
586
590
  /**
587
591
  * Create a unique identifier for deduplication using message ID and request ID
588
592
  */
@@ -644,6 +648,8 @@ type LoadOptions = {
644
648
  groupByProject?: boolean; // Group data by project instead of aggregating
645
649
  project?: string; // Filter to specific project name
646
650
  startOfWeek?: WeekDay; // Start of week for weekly aggregation
651
+ timezone?: string; // Timezone for date grouping (e.g., 'UTC', 'America/New_York'). Defaults to system timezone
652
+ locale?: string; // Locale for date/time formatting (e.g., 'en-US', 'ja-JP'). Defaults to 'en-US'
647
653
  } & DateFilter;
648
654
  /**
649
655
  * Loads and aggregates Claude usage data by day
@@ -1,3 +1,3 @@
1
1
  import "./pricing-fetcher-AYfCy7g-.js";
2
- import { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema$1 as bucketUsageSchema, calculateCostForEntry$1 as calculateCostForEntry, createUniqueHash$1 as createUniqueHash, dailyUsageSchema$1 as dailyUsageSchema, extractProjectFromPath$1 as extractProjectFromPath, formatDate$1 as formatDate, formatDateCompact$1 as formatDateCompact, getClaudePaths$1 as getClaudePaths, getEarliestTimestamp$1 as getEarliestTimestamp, getUsageLimitResetTime$1 as getUsageLimitResetTime, globUsageFiles$1 as globUsageFiles, loadBucketUsageData$1 as loadBucketUsageData, loadDailyUsageData$1 as loadDailyUsageData, loadMonthlyUsageData$1 as loadMonthlyUsageData, loadSessionBlockData$1 as loadSessionBlockData, loadSessionData$1 as loadSessionData, loadWeeklyUsageData$1 as loadWeeklyUsageData, modelBreakdownSchema$1 as modelBreakdownSchema, monthlyUsageSchema$1 as monthlyUsageSchema, sessionUsageSchema$1 as sessionUsageSchema, sortFilesByTimestamp$1 as sortFilesByTimestamp, usageDataSchema$1 as usageDataSchema, weeklyUsageSchema$1 as weeklyUsageSchema } from "./data-loader-DZMUuqrf.js";
2
+ import { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema$1 as bucketUsageSchema, calculateCostForEntry$1 as calculateCostForEntry, createUniqueHash$1 as createUniqueHash, dailyUsageSchema$1 as dailyUsageSchema, extractProjectFromPath$1 as extractProjectFromPath, formatDate$1 as formatDate, formatDateCompact$1 as formatDateCompact, getClaudePaths$1 as getClaudePaths, getEarliestTimestamp$1 as getEarliestTimestamp, getUsageLimitResetTime$1 as getUsageLimitResetTime, globUsageFiles$1 as globUsageFiles, loadBucketUsageData$1 as loadBucketUsageData, loadDailyUsageData$1 as loadDailyUsageData, loadMonthlyUsageData$1 as loadMonthlyUsageData, loadSessionBlockData$1 as loadSessionBlockData, loadSessionData$1 as loadSessionData, loadWeeklyUsageData$1 as loadWeeklyUsageData, modelBreakdownSchema$1 as modelBreakdownSchema, monthlyUsageSchema$1 as monthlyUsageSchema, sessionUsageSchema$1 as sessionUsageSchema, sortFilesByTimestamp$1 as sortFilesByTimestamp, usageDataSchema$1 as usageDataSchema, weeklyUsageSchema$1 as weeklyUsageSchema } from "./data-loader-De3CFZ54.js";
3
3
  export { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema };
@@ -1,6 +1,6 @@
1
- import "./pricing-fetcher-CNjC0nXU.js";
1
+ import "./pricing-fetcher-BlH7npmF.js";
2
2
  import "./_token-utils-WjkbrjKv.js";
3
3
  import "./_types-ed8-0BH6.js";
4
- import { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema } from "./data-loader-CwryIrwx.js";
5
- import "./logger-C35JCduT.js";
4
+ import { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema } from "./data-loader-DCYemUxR.js";
5
+ import "./logger-DWlfa60j.js";
6
6
  export { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema };
@@ -1,6 +1,6 @@
1
- import { CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, PricingFetcher, USAGE_DATA_GLOB_PATTERN, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-CNjC0nXU.js";
2
- import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-CwryIrwx.js";
3
- import { logger } from "./logger-C35JCduT.js";
1
+ import { CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, PricingFetcher, USAGE_DATA_GLOB_PATTERN, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-BlH7npmF.js";
2
+ import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-DCYemUxR.js";
3
+ import { logger } from "./logger-DWlfa60j.js";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  var import_usingCtx = __toESM(require_usingCtx(), 1);
package/dist/debug.js CHANGED
@@ -1,7 +1,7 @@
1
- import "./pricing-fetcher-CNjC0nXU.js";
1
+ import "./pricing-fetcher-BlH7npmF.js";
2
2
  import "./_token-utils-WjkbrjKv.js";
3
3
  import "./_types-ed8-0BH6.js";
4
- import "./data-loader-CwryIrwx.js";
5
- import "./logger-C35JCduT.js";
6
- import { detectMismatches, printMismatchReport } from "./debug-C8bVFK5q.js";
4
+ import "./data-loader-DCYemUxR.js";
5
+ import "./logger-DWlfa60j.js";
6
+ import { detectMismatches, printMismatchReport } from "./debug-DlqDA604.js";
7
7
  export { detectMismatches, printMismatchReport };
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PROJECT_ALIASES_ENV, PricingFetcher, WEEK_DAYS, __commonJSMin, __require, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-CNjC0nXU.js";
2
+ import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PROJECT_ALIASES_ENV, PricingFetcher, WEEK_DAYS, __commonJSMin, __require, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-BlH7npmF.js";
3
3
  import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
4
4
  import { CostModes, SortOrders, filterDateSchema } from "./_types-ed8-0BH6.js";
5
5
  import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
6
- import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, uniq, usageDataSchema } from "./data-loader-CwryIrwx.js";
7
- import { description, log, logger, name, version } from "./logger-C35JCduT.js";
8
- import { detectMismatches, printMismatchReport } from "./debug-C8bVFK5q.js";
9
- import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-CqzLeEbX.js";
6
+ import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, uniq, usageDataSchema } from "./data-loader-DCYemUxR.js";
7
+ import { description, log, logger, name, version } from "./logger-DWlfa60j.js";
8
+ import { detectMismatches, printMismatchReport } from "./debug-DlqDA604.js";
9
+ import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-5usxHtjN.js";
10
10
  import { readFile } from "node:fs/promises";
11
11
  import process$1 from "node:process";
12
12
  import { createServer } from "node:http";
@@ -1265,6 +1265,17 @@ const sharedArgs = {
1265
1265
  noColor: {
1266
1266
  type: "boolean",
1267
1267
  description: "Disable colored output (default: auto). NO_COLOR=1 has the same effect."
1268
+ },
1269
+ timezone: {
1270
+ type: "string",
1271
+ short: "z",
1272
+ description: "Timezone for date grouping (e.g., UTC, America/New_York, Asia/Tokyo). Default: system timezone"
1273
+ },
1274
+ locale: {
1275
+ type: "string",
1276
+ short: "l",
1277
+ description: "Locale for date/time formatting (e.g., en-US, ja-JP, de-DE)",
1278
+ default: "en-CA"
1268
1279
  }
1269
1280
  };
1270
1281
  /**
@@ -4030,20 +4041,21 @@ var import_picocolors$4 = __toESM(require_picocolors(), 1);
4030
4041
  * Formats the time display for a session block
4031
4042
  * @param block - Session block to format
4032
4043
  * @param compact - Whether to use compact formatting for narrow terminals
4044
+ * @param locale - Locale for date/time formatting
4033
4045
  * @returns Formatted time string with duration and status information
4034
4046
  */
4035
- function formatBlockTime(block, compact = false) {
4036
- const start = compact ? block.startTime.toLocaleString(void 0, {
4047
+ function formatBlockTime(block, compact = false, locale) {
4048
+ const start = compact ? block.startTime.toLocaleString(locale, {
4037
4049
  month: "2-digit",
4038
4050
  day: "2-digit",
4039
4051
  hour: "2-digit",
4040
4052
  minute: "2-digit"
4041
- }) : block.startTime.toLocaleString();
4053
+ }) : block.startTime.toLocaleString(locale);
4042
4054
  if (block.isGap ?? false) {
4043
- const end = compact ? block.endTime.toLocaleString(void 0, {
4055
+ const end = compact ? block.endTime.toLocaleString(locale, {
4044
4056
  hour: "2-digit",
4045
4057
  minute: "2-digit"
4046
- }) : block.endTime.toLocaleString();
4058
+ }) : block.endTime.toLocaleString(locale);
4047
4059
  const duration$1 = Math.round((block.endTime.getTime() - block.startTime.getTime()) / (1e3 * 60 * 60));
4048
4060
  return compact ? `${start}-${end}\n(${duration$1}h gap)` : `${start} - ${end} (${duration$1}h gap)`;
4049
4061
  }
@@ -4137,7 +4149,9 @@ const blocksCommand = define({
4137
4149
  mode: ctx.values.mode,
4138
4150
  order: ctx.values.order,
4139
4151
  offline: ctx.values.offline,
4140
- sessionDurationHours: ctx.values.sessionLength
4152
+ sessionDurationHours: ctx.values.sessionLength,
4153
+ timezone: ctx.values.timezone,
4154
+ locale: ctx.values.locale
4141
4155
  });
4142
4156
  if (blocks.length === 0) {
4143
4157
  if (ctx.values.json) log(JSON.stringify({ blocks: [] }));
@@ -4291,7 +4305,7 @@ const blocksCommand = define({
4291
4305
  const useCompactFormat = terminalWidth < BLOCKS_COMPACT_WIDTH_THRESHOLD;
4292
4306
  for (const block of blocks) if (block.isGap ?? false) {
4293
4307
  const gapRow = [
4294
- import_picocolors$4.default.gray(formatBlockTime(block, useCompactFormat)),
4308
+ import_picocolors$4.default.gray(formatBlockTime(block, useCompactFormat, ctx.values.locale)),
4295
4309
  import_picocolors$4.default.gray("(inactive)"),
4296
4310
  import_picocolors$4.default.gray("-"),
4297
4311
  import_picocolors$4.default.gray("-")
@@ -4303,7 +4317,7 @@ const blocksCommand = define({
4303
4317
  const totalTokens = getTotalTokens(block.tokenCounts);
4304
4318
  const status = block.isActive ? import_picocolors$4.default.green("ACTIVE") : "";
4305
4319
  const row = [
4306
- formatBlockTime(block, useCompactFormat),
4320
+ formatBlockTime(block, useCompactFormat, ctx.values.locale),
4307
4321
  status,
4308
4322
  formatModels(block.models),
4309
4323
  formatNumber(totalTokens)
@@ -4527,7 +4541,9 @@ const dailyCommand = define({
4527
4541
  order: ctx.values.order,
4528
4542
  offline: ctx.values.offline,
4529
4543
  groupByProject: ctx.values.instances,
4530
- project: ctx.values.project
4544
+ project: ctx.values.project,
4545
+ timezone: ctx.values.timezone,
4546
+ locale: ctx.values.locale
4531
4547
  });
4532
4548
  if (dailyData.length === 0) {
4533
4549
  if (ctx.values.json) log(JSON.stringify([]));
@@ -4583,7 +4599,7 @@ const dailyCommand = define({
4583
4599
  "right",
4584
4600
  "right"
4585
4601
  ],
4586
- dateFormatter: formatDateCompact,
4602
+ dateFormatter: (dateStr) => formatDateCompact(dateStr, ctx.values.timezone, ctx.values.locale),
4587
4603
  compactHead: [
4588
4604
  "Date",
4589
4605
  "Models",
@@ -5166,7 +5182,9 @@ const monthlyCommand = define({
5166
5182
  until: ctx.values.until,
5167
5183
  mode: ctx.values.mode,
5168
5184
  order: ctx.values.order,
5169
- offline: ctx.values.offline
5185
+ offline: ctx.values.offline,
5186
+ timezone: ctx.values.timezone,
5187
+ locale: ctx.values.locale
5170
5188
  });
5171
5189
  if (monthlyData.length === 0) {
5172
5190
  if (ctx.values.json) {
@@ -5230,7 +5248,7 @@ const monthlyCommand = define({
5230
5248
  "right",
5231
5249
  "right"
5232
5250
  ],
5233
- dateFormatter: formatDateCompact,
5251
+ dateFormatter: (dateStr) => formatDateCompact(dateStr, ctx.values.timezone, ctx.values.locale),
5234
5252
  compactHead: [
5235
5253
  "Month",
5236
5254
  "Models",
@@ -5300,7 +5318,9 @@ const sessionCommand = define({
5300
5318
  until: ctx.values.until,
5301
5319
  mode: ctx.values.mode,
5302
5320
  order: ctx.values.order,
5303
- offline: ctx.values.offline
5321
+ offline: ctx.values.offline,
5322
+ timezone: ctx.values.timezone,
5323
+ locale: ctx.values.locale
5304
5324
  });
5305
5325
  if (sessionData.length === 0) {
5306
5326
  if (ctx.values.json) log(JSON.stringify([]));
@@ -5356,7 +5376,7 @@ const sessionCommand = define({
5356
5376
  "right",
5357
5377
  "left"
5358
5378
  ],
5359
- dateFormatter: formatDateCompact,
5379
+ dateFormatter: (dateStr) => formatDateCompact(dateStr, ctx.values.timezone, ctx.values.locale),
5360
5380
  compactHead: [
5361
5381
  "Session",
5362
5382
  "Models",
@@ -5442,10 +5462,12 @@ const weeklyCommand = define({
5442
5462
  const weeklyData = await loadWeeklyUsageData({
5443
5463
  since: ctx.values.since,
5444
5464
  until: ctx.values.until,
5465
+ timezone: ctx.values.timezone,
5445
5466
  mode: ctx.values.mode,
5446
5467
  order: ctx.values.order,
5447
5468
  offline: ctx.values.offline,
5448
- startOfWeek: ctx.values.startOfWeek
5469
+ startOfWeek: ctx.values.startOfWeek,
5470
+ locale: ctx.values.locale
5449
5471
  });
5450
5472
  if (weeklyData.length === 0) {
5451
5473
  if (ctx.values.json) {
@@ -5509,7 +5531,7 @@ const weeklyCommand = define({
5509
5531
  "right",
5510
5532
  "right"
5511
5533
  ],
5512
- dateFormatter: formatDateCompact,
5534
+ dateFormatter: (dateStr) => formatDateCompact(dateStr, ctx.values.timezone, ctx.values.locale),
5513
5535
  compactHead: [
5514
5536
  "Week",
5515
5537
  "Models",
@@ -951,7 +951,7 @@ function _getDefaultLogLevel() {
951
951
  }
952
952
  const consola = createConsola();
953
953
  var name = "ccusage";
954
- var version = "15.6.0";
954
+ var version = "15.7.0";
955
955
  var description = "Usage analysis tool for Claude Code";
956
956
  /**
957
957
  * Application logger instance with package name tag
package/dist/logger.js CHANGED
@@ -1,2 +1,2 @@
1
- import { log, logger } from "./logger-C35JCduT.js";
1
+ import { log, logger } from "./logger-DWlfa60j.js";
2
2
  export { log, logger };
@@ -1,9 +1,9 @@
1
- import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-CNjC0nXU.js";
1
+ import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-BlH7npmF.js";
2
2
  import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
3
3
  import { ZodFirstPartyTypeKind, ZodOptional, ZodType, arrayType, booleanType, discriminatedUnionType, enumType, filterDateSchema, literalType, numberType, objectType, optionalType, recordType, stringType, unionType, unknownType } from "./_types-ed8-0BH6.js";
4
4
  import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
5
- import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-CwryIrwx.js";
6
- import { name, version } from "./logger-C35JCduT.js";
5
+ import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-DCYemUxR.js";
6
+ import { name, version } from "./logger-DWlfa60j.js";
7
7
  import process from "node:process";
8
8
  const LATEST_PROTOCOL_VERSION = "2025-06-18";
9
9
  const SUPPORTED_PROTOCOL_VERSIONS = [
@@ -1713,10 +1713,11 @@ var Protocol = class {
1713
1713
  Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(new Error(`Uncaught error in notification handler: ${error}`)));
1714
1714
  }
1715
1715
  _onrequest(request, extra) {
1716
- var _a, _b, _c, _d;
1716
+ var _a, _b;
1717
1717
  const handler = (_a = this._requestHandlers.get(request.method)) !== null && _a !== void 0 ? _a : this.fallbackRequestHandler;
1718
+ const capturedTransport = this._transport;
1718
1719
  if (handler === void 0) {
1719
- (_b = this._transport) === null || _b === void 0 || _b.send({
1720
+ capturedTransport === null || capturedTransport === void 0 || capturedTransport.send({
1720
1721
  jsonrpc: "2.0",
1721
1722
  id: request.id,
1722
1723
  error: {
@@ -1730,8 +1731,8 @@ var Protocol = class {
1730
1731
  this._requestHandlerAbortControllers.set(request.id, abortController);
1731
1732
  const fullExtra = {
1732
1733
  signal: abortController.signal,
1733
- sessionId: (_c = this._transport) === null || _c === void 0 ? void 0 : _c.sessionId,
1734
- _meta: (_d = request.params) === null || _d === void 0 ? void 0 : _d._meta,
1734
+ sessionId: capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.sessionId,
1735
+ _meta: (_b = request.params) === null || _b === void 0 ? void 0 : _b._meta,
1735
1736
  sendNotification: (notification) => this.notification(notification, { relatedRequestId: request.id }),
1736
1737
  sendRequest: (r, resultSchema, options) => this.request(r, resultSchema, {
1737
1738
  ...options,
@@ -1742,22 +1743,21 @@ var Protocol = class {
1742
1743
  requestInfo: extra === null || extra === void 0 ? void 0 : extra.requestInfo
1743
1744
  };
1744
1745
  Promise.resolve().then(() => handler(request, fullExtra)).then((result) => {
1745
- var _a$1;
1746
1746
  if (abortController.signal.aborted) return;
1747
- return (_a$1 = this._transport) === null || _a$1 === void 0 ? void 0 : _a$1.send({
1747
+ return capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
1748
1748
  result,
1749
1749
  jsonrpc: "2.0",
1750
1750
  id: request.id
1751
1751
  });
1752
1752
  }, (error) => {
1753
- var _a$1, _b$1;
1753
+ var _a$1;
1754
1754
  if (abortController.signal.aborted) return;
1755
- return (_a$1 = this._transport) === null || _a$1 === void 0 ? void 0 : _a$1.send({
1755
+ return capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
1756
1756
  jsonrpc: "2.0",
1757
1757
  id: request.id,
1758
1758
  error: {
1759
1759
  code: Number.isSafeInteger(error["code"]) ? error["code"] : ErrorCode.InternalError,
1760
- message: (_b$1 = error.message) !== null && _b$1 !== void 0 ? _b$1 : "Internal error"
1760
+ message: (_a$1 = error.message) !== null && _a$1 !== void 0 ? _a$1 : "Internal error"
1761
1761
  }
1762
1762
  });
1763
1763
  }).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
@@ -9327,7 +9327,9 @@ function createMcpServer({ claudePath } = defaultOptions) {
9327
9327
  "auto",
9328
9328
  "calculate",
9329
9329
  "display"
9330
- ]).default("auto").optional()
9330
+ ]).default("auto").optional(),
9331
+ timezone: stringType().optional(),
9332
+ locale: stringType().default("en-CA").optional()
9331
9333
  };
9332
9334
  server.registerTool("daily", {
9333
9335
  description: "Show usage report grouped by date",
package/dist/mcp.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./pricing-fetcher-AYfCy7g-.js";
2
- import { LoadOptions } from "./data-loader-DZMUuqrf.js";
2
+ import { LoadOptions } from "./data-loader-De3CFZ54.js";
3
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  import { Hono } from "hono/tiny";
5
5
 
package/dist/mcp.js CHANGED
@@ -1,8 +1,8 @@
1
- import "./pricing-fetcher-CNjC0nXU.js";
1
+ import "./pricing-fetcher-BlH7npmF.js";
2
2
  import "./_token-utils-WjkbrjKv.js";
3
3
  import "./_types-ed8-0BH6.js";
4
4
  import "./calculate-cost-BDqO4yWA.js";
5
- import "./data-loader-CwryIrwx.js";
6
- import "./logger-C35JCduT.js";
7
- import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-CqzLeEbX.js";
5
+ import "./data-loader-DCYemUxR.js";
6
+ import "./logger-DWlfa60j.js";
7
+ import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-5usxHtjN.js";
8
8
  export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
@@ -1,5 +1,5 @@
1
1
  import { modelPricingSchema } from "./_types-ed8-0BH6.js";
2
- import { logger } from "./logger-C35JCduT.js";
2
+ import { logger } from "./logger-DWlfa60j.js";
3
3
  import { createRequire } from "node:module";
4
4
  import path from "node:path";
5
5
  import F, { homedir } from "node:os";
@@ -1,4 +1,4 @@
1
- import { PricingFetcher } from "./pricing-fetcher-CNjC0nXU.js";
1
+ import { PricingFetcher } from "./pricing-fetcher-BlH7npmF.js";
2
2
  import "./_types-ed8-0BH6.js";
3
- import "./logger-C35JCduT.js";
3
+ import "./logger-DWlfa60j.js";
4
4
  export { PricingFetcher };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccusage",
3
- "version": "15.6.0",
3
+ "version": "15.7.0",
4
4
  "description": "Usage analysis tool for Claude Code",
5
5
  "homepage": "https://github.com/ryoppippi/ccusage#readme",
6
6
  "bugs": {