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 +4 -0
- package/dist/calculate-cost.d.ts +1 -1
- package/dist/{data-loader-CwryIrwx.js → data-loader-DCYemUxR.js} +41 -26
- package/dist/{data-loader-DZMUuqrf.d.ts → data-loader-De3CFZ54.d.ts} +8 -2
- package/dist/data-loader.d.ts +1 -1
- package/dist/data-loader.js +3 -3
- package/dist/{debug-C8bVFK5q.js → debug-DlqDA604.js} +3 -3
- package/dist/debug.js +4 -4
- package/dist/index.js +43 -21
- package/dist/{logger-C35JCduT.js → logger-DWlfa60j.js} +1 -1
- package/dist/logger.js +1 -1
- package/dist/{mcp-CqzLeEbX.js → mcp-5usxHtjN.js} +15 -13
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +4 -4
- package/dist/{pricing-fetcher-CNjC0nXU.js → pricing-fetcher-BlH7npmF.js} +1 -1
- package/dist/pricing-fetcher.js +2 -2
- package/package.json +1 -1
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
|
package/dist/calculate-cost.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./pricing-fetcher-AYfCy7g-.js";
|
|
2
|
-
import { DailyUsage, MonthlyUsage, SessionUsage, WeeklyUsage } from "./data-loader-
|
|
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-
|
|
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-
|
|
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
|
-
*
|
|
3579
|
-
*
|
|
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
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
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
|
-
|
|
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
|
|
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
|
package/dist/data-loader.d.ts
CHANGED
|
@@ -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-
|
|
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 };
|
package/dist/data-loader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
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-
|
|
5
|
-
import "./logger-
|
|
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-
|
|
2
|
-
import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-
|
|
3
|
-
import { logger } from "./logger-
|
|
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-
|
|
1
|
+
import "./pricing-fetcher-BlH7npmF.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import "./_types-ed8-0BH6.js";
|
|
4
|
-
import "./data-loader-
|
|
5
|
-
import "./logger-
|
|
6
|
-
import { detectMismatches, printMismatchReport } from "./debug-
|
|
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-
|
|
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-
|
|
7
|
-
import { description, log, logger, name, version } from "./logger-
|
|
8
|
-
import { detectMismatches, printMismatchReport } from "./debug-
|
|
9
|
-
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-
|
|
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(
|
|
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(
|
|
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.
|
|
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-
|
|
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-
|
|
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-
|
|
6
|
-
import { name, version } from "./logger-
|
|
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
|
|
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
|
-
|
|
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:
|
|
1734
|
-
_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
|
|
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
|
|
1753
|
+
var _a$1;
|
|
1754
1754
|
if (abortController.signal.aborted) return;
|
|
1755
|
-
return
|
|
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: (
|
|
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
package/dist/mcp.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
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-
|
|
6
|
-
import "./logger-
|
|
7
|
-
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-
|
|
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-
|
|
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";
|
package/dist/pricing-fetcher.js
CHANGED