ccusage 15.3.1 → 15.4.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/dist/calculate-cost.d.ts +1 -1
- package/dist/{data-loader-a9CiVyT5.d.ts → data-loader-7c4yXbqG.d.ts} +14 -1
- package/dist/{data-loader-DqK3z1AK.js → data-loader-BNrxyvc9.js} +45 -38
- package/dist/data-loader.d.ts +2 -2
- package/dist/data-loader.js +4 -4
- package/dist/{debug-Cby_QhQQ.js → debug-Brn3ODNf.js} +3 -3
- package/dist/debug.js +4 -4
- package/dist/index.js +60 -26
- package/dist/{logger-D7tlrIfv.js → logger-mXUMXvyg.js} +1 -1
- package/dist/logger.js +1 -1
- package/dist/{mcp-CFT0dcvs.js → mcp-CQw7snVU.js} +9 -10
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +4 -4
- package/dist/{pricing-fetcher-DpoTR8Md.js → pricing-fetcher-KIIpXo8L.js} +2 -10
- package/dist/pricing-fetcher.js +2 -2
- package/package.json +9 -9
package/dist/calculate-cost.d.ts
CHANGED
|
@@ -446,6 +446,19 @@ declare function calculateCostForEntry(data: UsageData, mode: CostMode, fetcher:
|
|
|
446
446
|
* @returns Usage limit expiration date
|
|
447
447
|
*/
|
|
448
448
|
declare function getUsageLimitResetTime(data: UsageData): Date | null;
|
|
449
|
+
/**
|
|
450
|
+
* Result of glob operation with base directory information
|
|
451
|
+
*/
|
|
452
|
+
type GlobResult = {
|
|
453
|
+
file: string;
|
|
454
|
+
baseDir: string;
|
|
455
|
+
};
|
|
456
|
+
/**
|
|
457
|
+
* Glob files from multiple Claude paths in parallel
|
|
458
|
+
* @param claudePaths - Array of Claude base paths
|
|
459
|
+
* @returns Array of file paths with their base directories
|
|
460
|
+
*/
|
|
461
|
+
declare function globUsageFiles(claudePaths: string[]): Promise<GlobResult[]>;
|
|
449
462
|
/**
|
|
450
463
|
* Date range filter for limiting usage data by date
|
|
451
464
|
*/
|
|
@@ -492,4 +505,4 @@ declare function loadMonthlyUsageData(options?: LoadOptions): Promise<MonthlyUsa
|
|
|
492
505
|
*/
|
|
493
506
|
declare function loadSessionBlockData(options?: LoadOptions): Promise<SessionBlock[]>;
|
|
494
507
|
//#endregion
|
|
495
|
-
export { DailyUsage, DateFilter, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema };
|
|
508
|
+
export { DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema };
|
|
@@ -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-KIIpXo8L.js";
|
|
2
2
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import { activityDateSchema, arrayType, booleanType, createDailyDate, createMonthlyDate, createProjectPath, createSessionId, dailyDateSchema, isoTimestampSchema, messageIdSchema, modelNameSchema, monthlyDateSchema, numberType, objectType, projectPathSchema, requestIdSchema, sessionIdSchema, stringType, versionSchema } from "./_types-BHFM59hI.js";
|
|
4
|
-
import { logger } from "./logger-
|
|
4
|
+
import { logger } from "./logger-mXUMXvyg.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";
|
|
@@ -251,7 +251,7 @@ const unwrap = (...args) => {
|
|
|
251
251
|
const apply = (r) => {
|
|
252
252
|
if (isFailure(r)) {
|
|
253
253
|
if (hasDefault$1) return defaultValue$1;
|
|
254
|
-
throw
|
|
254
|
+
throw r.error;
|
|
255
255
|
}
|
|
256
256
|
return r.value;
|
|
257
257
|
};
|
|
@@ -263,7 +263,7 @@ const unwrap = (...args) => {
|
|
|
263
263
|
const apply = (r) => {
|
|
264
264
|
if (isFailure(r)) {
|
|
265
265
|
if (hasDefault) return defaultValue;
|
|
266
|
-
throw
|
|
266
|
+
throw r.error;
|
|
267
267
|
}
|
|
268
268
|
return r.value;
|
|
269
269
|
};
|
|
@@ -3518,16 +3518,26 @@ function extractUniqueModels(entries, getModel) {
|
|
|
3518
3518
|
return uniq(entries.map(getModel).filter((m$1) => m$1 != null && m$1 !== "<synthetic>"));
|
|
3519
3519
|
}
|
|
3520
3520
|
/**
|
|
3521
|
+
* Shared method for formatting dates with proper timezone handling
|
|
3522
|
+
* @param dateStr - Input date string
|
|
3523
|
+
* @param twoLine - Whether to format as two lines (true) or single line (false)
|
|
3524
|
+
* @returns Formatted date string
|
|
3525
|
+
*/
|
|
3526
|
+
function formatDateInternal(dateStr, twoLine) {
|
|
3527
|
+
const date = new Date(dateStr);
|
|
3528
|
+
const hasTimezone = /Z|[+-]\d{2}:\d{2}/.test(dateStr);
|
|
3529
|
+
const year = hasTimezone ? date.getUTCFullYear() : date.getFullYear();
|
|
3530
|
+
const month = String(hasTimezone ? date.getUTCMonth() + 1 : date.getMonth() + 1).padStart(2, "0");
|
|
3531
|
+
const day = String(hasTimezone ? date.getUTCDate() : date.getDate()).padStart(2, "0");
|
|
3532
|
+
return twoLine ? `${year}\n${month}-${day}` : `${year}-${month}-${day}`;
|
|
3533
|
+
}
|
|
3534
|
+
/**
|
|
3521
3535
|
* Formats a date string to YYYY-MM-DD format
|
|
3522
3536
|
* @param dateStr - Input date string
|
|
3523
3537
|
* @returns Formatted date string in YYYY-MM-DD format
|
|
3524
3538
|
*/
|
|
3525
3539
|
function formatDate(dateStr) {
|
|
3526
|
-
|
|
3527
|
-
const year = date.getFullYear();
|
|
3528
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
3529
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
3530
|
-
return `${year}-${month}-${day}`;
|
|
3540
|
+
return formatDateInternal(dateStr, false);
|
|
3531
3541
|
}
|
|
3532
3542
|
/**
|
|
3533
3543
|
* Formats a date string to compact format with year on first line and month-day on second
|
|
@@ -3535,11 +3545,7 @@ function formatDate(dateStr) {
|
|
|
3535
3545
|
* @returns Formatted date string with newline separator (YYYY\nMM-DD)
|
|
3536
3546
|
*/
|
|
3537
3547
|
function formatDateCompact(dateStr) {
|
|
3538
|
-
|
|
3539
|
-
const year = date.getFullYear();
|
|
3540
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
3541
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
3542
|
-
return `${year}\n${month}-${day}`;
|
|
3548
|
+
return formatDateInternal(dateStr, true);
|
|
3543
3549
|
}
|
|
3544
3550
|
/**
|
|
3545
3551
|
* Generic function to sort items by date based on sort order
|
|
@@ -3647,6 +3653,25 @@ function getUsageLimitResetTime(data) {
|
|
|
3647
3653
|
return resetTime;
|
|
3648
3654
|
}
|
|
3649
3655
|
/**
|
|
3656
|
+
* Glob files from multiple Claude paths in parallel
|
|
3657
|
+
* @param claudePaths - Array of Claude base paths
|
|
3658
|
+
* @returns Array of file paths with their base directories
|
|
3659
|
+
*/
|
|
3660
|
+
async function globUsageFiles(claudePaths) {
|
|
3661
|
+
const filePromises = claudePaths.map(async (claudePath) => {
|
|
3662
|
+
const claudeDir = path.join(claudePath, CLAUDE_PROJECTS_DIR_NAME);
|
|
3663
|
+
const files = await glob([USAGE_DATA_GLOB_PATTERN], {
|
|
3664
|
+
cwd: claudeDir,
|
|
3665
|
+
absolute: true
|
|
3666
|
+
}).catch(() => []);
|
|
3667
|
+
return files.map((file) => ({
|
|
3668
|
+
file,
|
|
3669
|
+
baseDir: claudeDir
|
|
3670
|
+
}));
|
|
3671
|
+
});
|
|
3672
|
+
return (await Promise.all(filePromises)).flat();
|
|
3673
|
+
}
|
|
3674
|
+
/**
|
|
3650
3675
|
* Loads and aggregates Claude usage data by day
|
|
3651
3676
|
* Processes all JSONL files in the Claude projects directory and groups usage by date
|
|
3652
3677
|
* @param options - Optional configuration for loading and filtering data
|
|
@@ -3656,17 +3681,10 @@ async function loadDailyUsageData(options) {
|
|
|
3656
3681
|
try {
|
|
3657
3682
|
var _usingCtx = (0, import_usingCtx.default)();
|
|
3658
3683
|
const claudePaths = toArray(options?.claudePath ?? getClaudePaths());
|
|
3659
|
-
const allFiles =
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
cwd: claudeDir,
|
|
3664
|
-
absolute: true
|
|
3665
|
-
});
|
|
3666
|
-
allFiles.push(...files);
|
|
3667
|
-
}
|
|
3668
|
-
if (allFiles.length === 0) return [];
|
|
3669
|
-
const sortedFiles = await sortFilesByTimestamp(allFiles);
|
|
3684
|
+
const allFiles = await globUsageFiles(claudePaths);
|
|
3685
|
+
const fileList = allFiles.map((f$1) => f$1.file);
|
|
3686
|
+
if (fileList.length === 0) return [];
|
|
3687
|
+
const sortedFiles = await sortFilesByTimestamp(fileList);
|
|
3670
3688
|
const mode = options?.mode ?? "auto";
|
|
3671
3689
|
const fetcher = _usingCtx.u(mode === "display" ? null : new PricingFetcher(options?.offline));
|
|
3672
3690
|
const processedHashes = /* @__PURE__ */ new Set();
|
|
@@ -3724,18 +3742,7 @@ async function loadSessionData(options) {
|
|
|
3724
3742
|
try {
|
|
3725
3743
|
var _usingCtx3 = (0, import_usingCtx.default)();
|
|
3726
3744
|
const claudePaths = toArray(options?.claudePath ?? getClaudePaths());
|
|
3727
|
-
const filesWithBase =
|
|
3728
|
-
for (const claudePath of claudePaths) {
|
|
3729
|
-
const claudeDir = path.join(claudePath, CLAUDE_PROJECTS_DIR_NAME);
|
|
3730
|
-
const files = await glob([USAGE_DATA_GLOB_PATTERN], {
|
|
3731
|
-
cwd: claudeDir,
|
|
3732
|
-
absolute: true
|
|
3733
|
-
});
|
|
3734
|
-
for (const file of files) filesWithBase.push({
|
|
3735
|
-
file,
|
|
3736
|
-
baseDir: claudeDir
|
|
3737
|
-
});
|
|
3738
|
-
}
|
|
3745
|
+
const filesWithBase = await globUsageFiles(claudePaths);
|
|
3739
3746
|
if (filesWithBase.length === 0) return [];
|
|
3740
3747
|
const fileToBaseMap = new Map(filesWithBase.map((f$1) => [f$1.file, f$1.baseDir]));
|
|
3741
3748
|
const sortedFilesWithBase = await sortFilesByTimestamp(filesWithBase.map((f$1) => f$1.file)).then((sortedFiles) => sortedFiles.map((file) => ({
|
|
@@ -3915,4 +3922,4 @@ async function loadSessionBlockData(options) {
|
|
|
3915
3922
|
_usingCtx4.d();
|
|
3916
3923
|
}
|
|
3917
3924
|
}
|
|
3918
|
-
export { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateCostForEntry, createUniqueHash, dailyUsageSchema, filterRecentBlocks, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, glob, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, projectBlockUsage, sessionUsageSchema, sortFilesByTimestamp, uniq, unwrap, usageDataSchema };
|
|
3925
|
+
export { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateCostForEntry, createUniqueHash, dailyUsageSchema, filterRecentBlocks, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, glob, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, projectBlockUsage, sessionUsageSchema, sortFilesByTimestamp, uniq, unwrap, usageDataSchema };
|
package/dist/data-loader.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { DailyUsage, DateFilter, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema } from "./data-loader-
|
|
1
|
+
import { DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema } from "./data-loader-7c4yXbqG.js";
|
|
2
2
|
import "./pricing-fetcher-B3SvKOod.js";
|
|
3
|
-
export { DailyUsage, DateFilter, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema };
|
|
3
|
+
export { DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema };
|
package/dist/data-loader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-KIIpXo8L.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import "./_types-BHFM59hI.js";
|
|
4
|
-
import { calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema } from "./data-loader-
|
|
5
|
-
import "./logger-
|
|
6
|
-
export { calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema };
|
|
4
|
+
import { calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema } from "./data-loader-BNrxyvc9.js";
|
|
5
|
+
import "./logger-mXUMXvyg.js";
|
|
6
|
+
export { calculateCostForEntry, createUniqueHash, dailyUsageSchema, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema };
|
|
@@ -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-KIIpXo8L.js";
|
|
2
|
+
import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-BNrxyvc9.js";
|
|
3
|
+
import { logger } from "./logger-mXUMXvyg.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-KIIpXo8L.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import "./_types-BHFM59hI.js";
|
|
4
|
-
import "./data-loader-
|
|
5
|
-
import "./logger-
|
|
6
|
-
import { detectMismatches, printMismatchReport } from "./debug-
|
|
4
|
+
import "./data-loader-BNrxyvc9.js";
|
|
5
|
+
import "./logger-mXUMXvyg.js";
|
|
6
|
+
import { detectMismatches, printMismatchReport } from "./debug-Brn3ODNf.js";
|
|
7
7
|
export { detectMismatches, printMismatchReport };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS,
|
|
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, PricingFetcher, __commonJSMin, __require, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-KIIpXo8L.js";
|
|
3
3
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
4
4
|
import { CostModes, SortOrders, filterDateSchema } from "./_types-BHFM59hI.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,
|
|
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, projectBlockUsage, sortFilesByTimestamp, uniq, usageDataSchema } from "./data-loader-BNrxyvc9.js";
|
|
7
|
+
import { description, log, logger, name, version } from "./logger-mXUMXvyg.js";
|
|
8
|
+
import { detectMismatches, printMismatchReport } from "./debug-Brn3ODNf.js";
|
|
9
|
+
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-CQw7snVU.js";
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
11
|
-
import path from "node:path";
|
|
12
11
|
import process$1 from "node:process";
|
|
13
12
|
import { createServer } from "node:http";
|
|
14
13
|
import { Http2ServerRequest } from "node:http2";
|
|
@@ -3205,14 +3204,11 @@ var LiveMonitor = class {
|
|
|
3205
3204
|
* Only reads new or modified files since last check
|
|
3206
3205
|
*/
|
|
3207
3206
|
async getActiveBlock() {
|
|
3208
|
-
const
|
|
3209
|
-
const
|
|
3210
|
-
|
|
3211
|
-
absolute: true
|
|
3212
|
-
});
|
|
3213
|
-
if (files.length === 0) return null;
|
|
3207
|
+
const results = await globUsageFiles(this.config.claudePaths);
|
|
3208
|
+
const allFiles = results.map((r) => r.file);
|
|
3209
|
+
if (allFiles.length === 0) return null;
|
|
3214
3210
|
const filesToRead = [];
|
|
3215
|
-
for (const file of
|
|
3211
|
+
for (const file of allFiles) {
|
|
3216
3212
|
const timestamp = await getEarliestTimestamp(file);
|
|
3217
3213
|
const lastTimestamp = this.lastFileTimestamps.get(file);
|
|
3218
3214
|
if (timestamp != null && (lastTimestamp == null || timestamp.getTime() > lastTimestamp)) {
|
|
@@ -3745,7 +3741,7 @@ const DETAIL_COLUMN_WIDTHS = {
|
|
|
3745
3741
|
function renderLiveDisplay(terminal, block, config) {
|
|
3746
3742
|
const width = terminal.width;
|
|
3747
3743
|
const now = /* @__PURE__ */ new Date();
|
|
3748
|
-
const totalTokens = block.tokenCounts
|
|
3744
|
+
const totalTokens = getTotalTokens(block.tokenCounts);
|
|
3749
3745
|
const elapsed = (now.getTime() - block.startTime.getTime()) / (1e3 * 60);
|
|
3750
3746
|
const remaining = (block.endTime.getTime() - now.getTime()) / (1e3 * 60);
|
|
3751
3747
|
if (width < 60) {
|
|
@@ -3952,7 +3948,7 @@ async function startLiveMonitoring(config) {
|
|
|
3952
3948
|
terminal.clearScreen();
|
|
3953
3949
|
terminal.hideCursor();
|
|
3954
3950
|
const monitor = _usingCtx.u(new LiveMonitor({
|
|
3955
|
-
|
|
3951
|
+
claudePaths: config.claudePaths,
|
|
3956
3952
|
sessionDurationHours: config.sessionDurationHours,
|
|
3957
3953
|
mode: config.mode,
|
|
3958
3954
|
order: config.order
|
|
@@ -4052,8 +4048,7 @@ function formatModels(models) {
|
|
|
4052
4048
|
* @returns Parsed token limit or undefined if invalid
|
|
4053
4049
|
*/
|
|
4054
4050
|
function parseTokenLimit(value, maxFromAll) {
|
|
4055
|
-
if (value == null || value === "") return void 0;
|
|
4056
|
-
if (value === "max") return maxFromAll > 0 ? maxFromAll : void 0;
|
|
4051
|
+
if (value == null || value === "" || value === "max") return maxFromAll > 0 ? maxFromAll : void 0;
|
|
4057
4052
|
const limit = Number.parseInt(value, 10);
|
|
4058
4053
|
return Number.isNaN(limit) ? void 0 : limit;
|
|
4059
4054
|
}
|
|
@@ -4117,7 +4112,7 @@ const blocksCommand = define({
|
|
|
4117
4112
|
process$1.exit(0);
|
|
4118
4113
|
}
|
|
4119
4114
|
let maxTokensFromAll = 0;
|
|
4120
|
-
if (ctx.values.tokenLimit === "max") {
|
|
4115
|
+
if (ctx.values.tokenLimit === "max" || ctx.values.tokenLimit == null || ctx.values.tokenLimit === "") {
|
|
4121
4116
|
for (const block of blocks) if (!(block.isGap ?? false) && !block.isActive) {
|
|
4122
4117
|
const blockTokens = getTotalTokens(block.tokenCounts);
|
|
4123
4118
|
if (blockTokens > maxTokensFromAll) maxTokensFromAll = blockTokens;
|
|
@@ -4151,7 +4146,7 @@ const blocksCommand = define({
|
|
|
4151
4146
|
throw new Error("No valid Claude data directory found");
|
|
4152
4147
|
}
|
|
4153
4148
|
await startLiveMonitoring({
|
|
4154
|
-
|
|
4149
|
+
claudePaths: paths,
|
|
4155
4150
|
tokenLimit: parseTokenLimit(tokenLimitValue, maxTokensFromAll),
|
|
4156
4151
|
refreshInterval: refreshInterval * 1e3,
|
|
4157
4152
|
sessionDurationHours: ctx.values.sessionLength,
|
|
@@ -4173,7 +4168,7 @@ const blocksCommand = define({
|
|
|
4173
4168
|
isGap: block.isGap ?? false,
|
|
4174
4169
|
entries: block.entries.length,
|
|
4175
4170
|
tokenCounts: block.tokenCounts,
|
|
4176
|
-
totalTokens: block.tokenCounts
|
|
4171
|
+
totalTokens: getTotalTokens(block.tokenCounts),
|
|
4177
4172
|
costUSD: block.costUSD,
|
|
4178
4173
|
models: block.models,
|
|
4179
4174
|
burnRate,
|
|
@@ -4474,6 +4469,7 @@ var Request = class extends GlobalRequest {
|
|
|
4474
4469
|
super(input, options);
|
|
4475
4470
|
}
|
|
4476
4471
|
};
|
|
4472
|
+
var wrapBodyStream = Symbol("wrapBodyStream");
|
|
4477
4473
|
var newRequestFromIncoming = (method, url, incoming, abortController) => {
|
|
4478
4474
|
const headerRecord = [];
|
|
4479
4475
|
const rawHeaders = incoming.rawHeaders;
|
|
@@ -4498,7 +4494,19 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
|
|
|
4498
4494
|
controller.enqueue(incoming.rawBody);
|
|
4499
4495
|
controller.close();
|
|
4500
4496
|
} });
|
|
4501
|
-
else
|
|
4497
|
+
else if (incoming[wrapBodyStream]) {
|
|
4498
|
+
let reader;
|
|
4499
|
+
init$1.body = new ReadableStream({ async pull(controller) {
|
|
4500
|
+
try {
|
|
4501
|
+
reader ||= Readable.toWeb(incoming).getReader();
|
|
4502
|
+
const { done, value } = await reader.read();
|
|
4503
|
+
if (done) controller.close();
|
|
4504
|
+
else controller.enqueue(value);
|
|
4505
|
+
} catch (error) {
|
|
4506
|
+
controller.error(error);
|
|
4507
|
+
}
|
|
4508
|
+
} });
|
|
4509
|
+
} else init$1.body = Readable.toWeb(incoming);
|
|
4502
4510
|
return new Request(url, init$1);
|
|
4503
4511
|
};
|
|
4504
4512
|
var getRequestCache = Symbol("getRequestCache");
|
|
@@ -4709,6 +4717,7 @@ global.fetch = (info$1, init$1) => {
|
|
|
4709
4717
|
};
|
|
4710
4718
|
return webFetch(info$1, init$1);
|
|
4711
4719
|
};
|
|
4720
|
+
var outgoingEnded = Symbol("outgoingEnded");
|
|
4712
4721
|
var regBuffer = /^no$/i;
|
|
4713
4722
|
var regContentType = /^(application\/json\b|text\/(?!event-stream\b))/i;
|
|
4714
4723
|
var handleRequestError = () => new Response(null, { status: 400 });
|
|
@@ -4737,8 +4746,9 @@ var responseViaCache = async (res, outgoing) => {
|
|
|
4737
4746
|
else if (body instanceof Blob) outgoing.end(new Uint8Array(await body.arrayBuffer()));
|
|
4738
4747
|
else {
|
|
4739
4748
|
flushHeaders(outgoing);
|
|
4740
|
-
|
|
4749
|
+
await writeFromReadableStream(body, outgoing)?.catch((e) => handleResponseError(e, outgoing));
|
|
4741
4750
|
}
|
|
4751
|
+
outgoing[outgoingEnded]?.();
|
|
4742
4752
|
};
|
|
4743
4753
|
var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
4744
4754
|
if (res instanceof Promise) if (options.errorHandler) try {
|
|
@@ -4767,8 +4777,10 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
4767
4777
|
outgoing.writeHead(res.status, resHeaderRecord);
|
|
4768
4778
|
outgoing.end();
|
|
4769
4779
|
}
|
|
4780
|
+
outgoing[outgoingEnded]?.();
|
|
4770
4781
|
};
|
|
4771
4782
|
var getRequestListener = (fetchCallback, options = {}) => {
|
|
4783
|
+
const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
|
|
4772
4784
|
if (options.overrideGlobalObjects !== false && global.Request !== Request) {
|
|
4773
4785
|
Object.defineProperty(global, "Request", { value: Request });
|
|
4774
4786
|
Object.defineProperty(global, "Response", { value: Response2 });
|
|
@@ -4777,11 +4789,32 @@ var getRequestListener = (fetchCallback, options = {}) => {
|
|
|
4777
4789
|
let res, req;
|
|
4778
4790
|
try {
|
|
4779
4791
|
req = newRequest(incoming, options.hostname);
|
|
4792
|
+
let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD";
|
|
4793
|
+
if (!incomingEnded) {
|
|
4794
|
+
incoming[wrapBodyStream] = true;
|
|
4795
|
+
incoming.on("end", () => {
|
|
4796
|
+
incomingEnded = true;
|
|
4797
|
+
});
|
|
4798
|
+
if (incoming instanceof Http2ServerRequest) outgoing[outgoingEnded] = () => {
|
|
4799
|
+
if (!incomingEnded) setTimeout(() => {
|
|
4800
|
+
if (!incomingEnded) setTimeout(() => {
|
|
4801
|
+
incoming.destroy();
|
|
4802
|
+
outgoing.destroy();
|
|
4803
|
+
});
|
|
4804
|
+
});
|
|
4805
|
+
};
|
|
4806
|
+
}
|
|
4780
4807
|
outgoing.on("close", () => {
|
|
4781
4808
|
const abortController = req[abortControllerKey];
|
|
4782
|
-
if (
|
|
4783
|
-
|
|
4784
|
-
|
|
4809
|
+
if (abortController) {
|
|
4810
|
+
if (incoming.errored) req[abortControllerKey].abort(incoming.errored.toString());
|
|
4811
|
+
else if (!outgoing.writableFinished) req[abortControllerKey].abort("Client connection prematurely closed.");
|
|
4812
|
+
}
|
|
4813
|
+
if (!incomingEnded) setTimeout(() => {
|
|
4814
|
+
if (!incomingEnded) setTimeout(() => {
|
|
4815
|
+
incoming.destroy();
|
|
4816
|
+
});
|
|
4817
|
+
});
|
|
4785
4818
|
});
|
|
4786
4819
|
res = fetchCallback(req, {
|
|
4787
4820
|
incoming,
|
|
@@ -4807,7 +4840,8 @@ var createAdaptorServer = (options) => {
|
|
|
4807
4840
|
const fetchCallback = options.fetch;
|
|
4808
4841
|
const requestListener = getRequestListener(fetchCallback, {
|
|
4809
4842
|
hostname: options.hostname,
|
|
4810
|
-
overrideGlobalObjects: options.overrideGlobalObjects
|
|
4843
|
+
overrideGlobalObjects: options.overrideGlobalObjects,
|
|
4844
|
+
autoCleanupIncoming: options.autoCleanupIncoming
|
|
4811
4845
|
});
|
|
4812
4846
|
const createServer$1 = options.createServer || createServer;
|
|
4813
4847
|
const server = createServer$1(options.serverOptions || {}, requestListener);
|
|
@@ -951,7 +951,7 @@ function _getDefaultLogLevel() {
|
|
|
951
951
|
}
|
|
952
952
|
const consola = createConsola$1();
|
|
953
953
|
var name = "ccusage";
|
|
954
|
-
var version = "15.
|
|
954
|
+
var version = "15.4.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-mXUMXvyg.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-KIIpXo8L.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-BHFM59hI.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-BNrxyvc9.js";
|
|
6
|
+
import { name, version } from "./logger-mXUMXvyg.js";
|
|
7
7
|
import process from "node:process";
|
|
8
8
|
const LATEST_PROTOCOL_VERSION = "2025-06-18";
|
|
9
9
|
const SUPPORTED_PROTOCOL_VERSIONS = [
|
|
@@ -606,7 +606,7 @@ const ElicitRequestSchema = RequestSchema.extend({
|
|
|
606
606
|
const ElicitResultSchema = ResultSchema.extend({
|
|
607
607
|
action: enumType([
|
|
608
608
|
"accept",
|
|
609
|
-
"
|
|
609
|
+
"decline",
|
|
610
610
|
"cancel"
|
|
611
611
|
]),
|
|
612
612
|
content: optionalType(recordType(stringType(), unknownType()))
|
|
@@ -1054,7 +1054,7 @@ var HonoRequest = class {
|
|
|
1054
1054
|
return bodyCache[key] = raw$1[key]();
|
|
1055
1055
|
};
|
|
1056
1056
|
json() {
|
|
1057
|
-
return this.#cachedBody("
|
|
1057
|
+
return this.#cachedBody("text").then((text) => JSON.parse(text));
|
|
1058
1058
|
}
|
|
1059
1059
|
text() {
|
|
1060
1060
|
return this.#cachedBody("text");
|
|
@@ -8561,10 +8561,6 @@ var McpServer = class {
|
|
|
8561
8561
|
return registeredResourceTemplate;
|
|
8562
8562
|
}
|
|
8563
8563
|
}
|
|
8564
|
-
/**
|
|
8565
|
-
* Registers a resource with a config object and callback.
|
|
8566
|
-
* For static resources, use a URI string. For dynamic resources, use a ResourceTemplate.
|
|
8567
|
-
*/
|
|
8568
8564
|
registerResource(name$1, uriOrTemplate, config, readCallback) {
|
|
8569
8565
|
if (typeof uriOrTemplate === "string") {
|
|
8570
8566
|
if (this._registeredResources[uriOrTemplate]) throw new Error(`Resource ${uriOrTemplate} is already registered`);
|
|
@@ -8766,7 +8762,10 @@ var McpServer = class {
|
|
|
8766
8762
|
if (this.isConnected()) this.server.sendPromptListChanged();
|
|
8767
8763
|
}
|
|
8768
8764
|
};
|
|
8769
|
-
const EMPTY_OBJECT_JSON_SCHEMA = {
|
|
8765
|
+
const EMPTY_OBJECT_JSON_SCHEMA = {
|
|
8766
|
+
type: "object",
|
|
8767
|
+
properties: {}
|
|
8768
|
+
};
|
|
8770
8769
|
function isZodRawShape(obj) {
|
|
8771
8770
|
if (typeof obj !== "object" || obj === null) return false;
|
|
8772
8771
|
const isEmptyObject = Object.keys(obj).length === 0;
|
package/dist/mcp.d.ts
CHANGED
package/dist/mcp.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-KIIpXo8L.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import "./_types-BHFM59hI.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-BNrxyvc9.js";
|
|
6
|
+
import "./logger-mXUMXvyg.js";
|
|
7
|
+
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-CQw7snVU.js";
|
|
8
8
|
export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { modelPricingSchema } from "./_types-BHFM59hI.js";
|
|
2
|
-
import { logger } from "./logger-
|
|
2
|
+
import { logger } from "./logger-mXUMXvyg.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import F, { homedir } from "node:os";
|
|
@@ -47,6 +47,7 @@ const andThrough = (fn) => (result) => {
|
|
|
47
47
|
};
|
|
48
48
|
return isPromise(result) ? result.then(apply) : apply(result);
|
|
49
49
|
};
|
|
50
|
+
const isSuccess = (result) => "Success" === result.type;
|
|
50
51
|
const succeed = (...args) => {
|
|
51
52
|
const value = args[0];
|
|
52
53
|
if (void 0 === value) return { type: "Success" };
|
|
@@ -71,7 +72,6 @@ const fail = (...args) => {
|
|
|
71
72
|
error
|
|
72
73
|
};
|
|
73
74
|
};
|
|
74
|
-
const isSuccess = (result) => "Success" === result.type;
|
|
75
75
|
const inspect = (fn) => (result) => {
|
|
76
76
|
const apply = (r) => {
|
|
77
77
|
if (isSuccess(r)) fn(r.value);
|
|
@@ -324,14 +324,6 @@ var PricingFetcher = class {
|
|
|
324
324
|
loadOfflinePricing = try_({
|
|
325
325
|
try: async () => {
|
|
326
326
|
const pricing = new Map(Object.entries({
|
|
327
|
-
"claude-instant-1": {
|
|
328
|
-
"input_cost_per_token": 163e-8,
|
|
329
|
-
"output_cost_per_token": 551e-8
|
|
330
|
-
},
|
|
331
|
-
"claude-instant-1.2": {
|
|
332
|
-
"input_cost_per_token": 163e-9,
|
|
333
|
-
"output_cost_per_token": 551e-9
|
|
334
|
-
},
|
|
335
327
|
"claude-2": {
|
|
336
328
|
"input_cost_per_token": 8e-6,
|
|
337
329
|
"output_cost_per_token": 24e-6
|
package/dist/pricing-fetcher.js
CHANGED
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccusage",
|
|
3
|
-
"
|
|
4
|
-
"version": "15.3.1",
|
|
3
|
+
"version": "15.4.0",
|
|
5
4
|
"description": "Usage analysis tool for Claude Code",
|
|
6
|
-
"author": "ryoppippi",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"funding": "https://github.com/ryoppippi/ccusage?sponsor=1",
|
|
9
5
|
"homepage": "https://github.com/ryoppippi/ccusage#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/ryoppippi/ccusage/issues"
|
|
8
|
+
},
|
|
10
9
|
"repository": {
|
|
11
10
|
"type": "git",
|
|
12
11
|
"url": "git+https://github.com/ryoppippi/ccusage.git"
|
|
13
12
|
},
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
"funding": "https://github.com/ryoppippi/ccusage?sponsor=1",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": "ryoppippi",
|
|
16
|
+
"type": "module",
|
|
17
17
|
"exports": {
|
|
18
18
|
".": "./dist/index.js",
|
|
19
19
|
"./calculate-cost": "./dist/calculate-cost.js",
|
|
@@ -32,6 +32,6 @@
|
|
|
32
32
|
"dist"
|
|
33
33
|
],
|
|
34
34
|
"engines": {
|
|
35
|
-
"node": ">=20.19.
|
|
35
|
+
"node": ">=20.19.4"
|
|
36
36
|
}
|
|
37
37
|
}
|