ccusage 15.9.3 → 15.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/{data-loader-B_nfl1Pr.js → data-loader-CY2f8ZBq.js} +3 -3
- package/dist/data-loader.js +3 -3
- package/dist/{debug-BoSgT8lp.js → debug-mIvd8kZa.js} +3 -3
- package/dist/debug.js +4 -4
- package/dist/index.js +96 -5
- package/dist/{logger-L_zzb0iT.js → logger-QcakA1fc.js} +1 -1
- package/dist/logger.js +1 -1
- package/dist/{mcp-Bqi6ayed.js → mcp-COJ_l32e.js} +3 -3
- package/dist/mcp.js +4 -4
- package/dist/{pricing-fetcher-ZrH9X6Xp.js → pricing-fetcher-DzkXdtDF.js} +1 -1
- package/dist/pricing-fetcher.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,11 +106,11 @@ Full documentation is available at **[ccusage.com](https://ccusage.com/)**
|
|
|
106
106
|
|
|
107
107
|
### Featured Sponsor
|
|
108
108
|
|
|
109
|
-
Check out
|
|
109
|
+
Check out [ccusage: The Claude Code cost scorecard that went viral](https://www.youtube.com/watch?v=Ak6qpQ5qdgk)
|
|
110
110
|
|
|
111
111
|
<p align="center">
|
|
112
|
-
<a href="https://www.youtube.com/watch?v=
|
|
113
|
-
<img src="https://cdn.jsdelivr.net/gh/ryoppippi/ccusage@main/docs/public/
|
|
112
|
+
<a href="https://www.youtube.com/watch?v=Ak6qpQ5qdgk">
|
|
113
|
+
<img src="https://cdn.jsdelivr.net/gh/ryoppippi/ccusage@main/docs/public/ccusage_thumbnail.png" alt="ccusage: The Claude Code cost scorecard that went viral" width="600">
|
|
114
114
|
</a>
|
|
115
115
|
</p>
|
|
116
116
|
|
|
@@ -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-DzkXdtDF.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-C0oFKDO-.js";
|
|
4
|
-
import { logger } from "./logger-
|
|
4
|
+
import { logger } from "./logger-QcakA1fc.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";
|
|
@@ -2397,7 +2397,7 @@ function formatDate(dateStr, timezone, locale) {
|
|
|
2397
2397
|
return formatter.format(date);
|
|
2398
2398
|
}
|
|
2399
2399
|
function formatDateCompact(dateStr, timezone, locale) {
|
|
2400
|
-
const date = new Date(dateStr), formatter = createDatePartsFormatter(timezone, locale), parts = formatter.formatToParts(date), year = parts.find((p) => p.type === "year")?.value ?? "", month = parts.find((p) => p.type === "month")?.value ?? "", day = parts.find((p) => p.type === "day")?.value ?? "";
|
|
2400
|
+
const parseResult = dailyDateSchema.safeParse(dateStr), date = parseResult.success ? timezone != null ? /* @__PURE__ */ new Date(`${dateStr}T00:00:00Z`) : /* @__PURE__ */ new Date(`${dateStr}T00:00:00`) : new Date(dateStr), formatter = createDatePartsFormatter(timezone, locale), parts = formatter.formatToParts(date), year = parts.find((p) => p.type === "year")?.value ?? "", month = parts.find((p) => p.type === "month")?.value ?? "", day = parts.find((p) => p.type === "day")?.value ?? "";
|
|
2401
2401
|
return `${year}\n${month}-${day}`;
|
|
2402
2402
|
}
|
|
2403
2403
|
function sortByDate(items, getDate, order = "desc") {
|
package/dist/data-loader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-DzkXdtDF.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import "./_types-C0oFKDO-.js";
|
|
4
|
-
import { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, 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, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema } from "./data-loader-CY2f8ZBq.js";
|
|
5
|
+
import "./logger-QcakA1fc.js";
|
|
6
6
|
export { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, 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-DzkXdtDF.js";
|
|
2
|
+
import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-CY2f8ZBq.js";
|
|
3
|
+
import { logger } from "./logger-QcakA1fc.js";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
var import_usingCtx = /* @__PURE__ */ __toESM(require_usingCtx(), 1);
|
package/dist/debug.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-DzkXdtDF.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import "./_types-C0oFKDO-.js";
|
|
4
|
-
import "./data-loader-
|
|
5
|
-
import "./logger-
|
|
6
|
-
import { detectMismatches, printMismatchReport } from "./debug-
|
|
4
|
+
import "./data-loader-CY2f8ZBq.js";
|
|
5
|
+
import "./logger-QcakA1fc.js";
|
|
6
|
+
import { detectMismatches, printMismatchReport } from "./debug-mIvd8kZa.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-DzkXdtDF.js";
|
|
3
3
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
4
4
|
import { CostModes, SortOrders, filterDateSchema, statuslineHookJsonSchema } from "./_types-C0oFKDO-.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, loadSessionUsageById, 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, loadSessionUsageById, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, uniq, usageDataSchema } from "./data-loader-CY2f8ZBq.js";
|
|
7
|
+
import { description, log, logger, name, version } from "./logger-QcakA1fc.js";
|
|
8
|
+
import { detectMismatches, printMismatchReport } from "./debug-mIvd8kZa.js";
|
|
9
|
+
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-COJ_l32e.js";
|
|
10
10
|
import a, { readFile } from "node:fs/promises";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import process$1 from "node:process";
|
|
@@ -3963,14 +3963,105 @@ const monthlyCommand = define({
|
|
|
3963
3963
|
}
|
|
3964
3964
|
}
|
|
3965
3965
|
});
|
|
3966
|
+
async function handleSessionIdLookup(ctx, useJson) {
|
|
3967
|
+
const sessionUsage = await loadSessionUsageById(ctx.values.id, {
|
|
3968
|
+
mode: ctx.values.mode,
|
|
3969
|
+
offline: ctx.values.offline
|
|
3970
|
+
});
|
|
3971
|
+
if (sessionUsage == null) {
|
|
3972
|
+
if (useJson) log(JSON.stringify(null));
|
|
3973
|
+
else logger.warn(`No session found with ID: ${ctx.values.id}`);
|
|
3974
|
+
process$1.exit(0);
|
|
3975
|
+
}
|
|
3976
|
+
if (useJson) {
|
|
3977
|
+
const jsonOutput = {
|
|
3978
|
+
sessionId: ctx.values.id,
|
|
3979
|
+
totalCost: sessionUsage.totalCost,
|
|
3980
|
+
totalTokens: calculateSessionTotalTokens(sessionUsage.entries),
|
|
3981
|
+
entries: sessionUsage.entries.map((entry) => ({
|
|
3982
|
+
timestamp: entry.timestamp,
|
|
3983
|
+
inputTokens: entry.message.usage.input_tokens,
|
|
3984
|
+
outputTokens: entry.message.usage.output_tokens,
|
|
3985
|
+
cacheCreationTokens: entry.message.usage.cache_creation_input_tokens ?? 0,
|
|
3986
|
+
cacheReadTokens: entry.message.usage.cache_read_input_tokens ?? 0,
|
|
3987
|
+
model: entry.message.model ?? "unknown",
|
|
3988
|
+
costUSD: entry.costUSD ?? 0
|
|
3989
|
+
}))
|
|
3990
|
+
};
|
|
3991
|
+
if (ctx.values.jq != null) {
|
|
3992
|
+
const jqResult = await processWithJq(jsonOutput, ctx.values.jq);
|
|
3993
|
+
if (isFailure(jqResult)) logger.error(jqResult.error.message), process$1.exit(1);
|
|
3994
|
+
log(jqResult.value);
|
|
3995
|
+
} else log(JSON.stringify(jsonOutput, null, 2));
|
|
3996
|
+
} else {
|
|
3997
|
+
logger.box(`Claude Code Session Usage - ${ctx.values.id}`);
|
|
3998
|
+
const totalTokens = calculateSessionTotalTokens(sessionUsage.entries);
|
|
3999
|
+
if (log(`Total Cost: ${formatCurrency(sessionUsage.totalCost)}`), log(`Total Tokens: ${formatNumber(totalTokens)}`), log(`Total Entries: ${sessionUsage.entries.length}`), log(""), sessionUsage.entries.length > 0) {
|
|
4000
|
+
const table = new ResponsiveTable({
|
|
4001
|
+
head: [
|
|
4002
|
+
"Timestamp",
|
|
4003
|
+
"Model",
|
|
4004
|
+
"Input",
|
|
4005
|
+
"Output",
|
|
4006
|
+
"Cache Create",
|
|
4007
|
+
"Cache Read",
|
|
4008
|
+
"Cost (USD)"
|
|
4009
|
+
],
|
|
4010
|
+
style: { head: ["cyan"] },
|
|
4011
|
+
colAligns: [
|
|
4012
|
+
"left",
|
|
4013
|
+
"left",
|
|
4014
|
+
"right",
|
|
4015
|
+
"right",
|
|
4016
|
+
"right",
|
|
4017
|
+
"right",
|
|
4018
|
+
"right"
|
|
4019
|
+
]
|
|
4020
|
+
});
|
|
4021
|
+
for (const entry of sessionUsage.entries) table.push([
|
|
4022
|
+
formatDateCompact(entry.timestamp, ctx.values.timezone, ctx.values.locale),
|
|
4023
|
+
entry.message.model ?? "unknown",
|
|
4024
|
+
formatNumber(entry.message.usage.input_tokens),
|
|
4025
|
+
formatNumber(entry.message.usage.output_tokens),
|
|
4026
|
+
formatNumber(entry.message.usage.cache_creation_input_tokens ?? 0),
|
|
4027
|
+
formatNumber(entry.message.usage.cache_read_input_tokens ?? 0),
|
|
4028
|
+
formatCurrency(entry.costUSD ?? 0)
|
|
4029
|
+
]);
|
|
4030
|
+
log(table.toString());
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
function calculateSessionTotalTokens(entries) {
|
|
4035
|
+
return entries.reduce((sum, entry) => {
|
|
4036
|
+
const usage = entry.message.usage;
|
|
4037
|
+
return sum + usage.input_tokens + usage.output_tokens + (usage.cache_creation_input_tokens ?? 0) + (usage.cache_read_input_tokens ?? 0);
|
|
4038
|
+
}, 0);
|
|
4039
|
+
}
|
|
3966
4040
|
var import_picocolors$2 = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
3967
4041
|
const sessionCommand = define({
|
|
3968
4042
|
name: "session",
|
|
3969
4043
|
description: "Show usage report grouped by conversation session",
|
|
3970
4044
|
...sharedCommandConfig,
|
|
4045
|
+
args: {
|
|
4046
|
+
...sharedCommandConfig.args,
|
|
4047
|
+
id: {
|
|
4048
|
+
type: "string",
|
|
4049
|
+
short: "i",
|
|
4050
|
+
description: "Load usage data for a specific session ID"
|
|
4051
|
+
}
|
|
4052
|
+
},
|
|
4053
|
+
toKebab: true,
|
|
3971
4054
|
async run(ctx) {
|
|
3972
4055
|
const useJson = ctx.values.json || ctx.values.jq != null;
|
|
3973
4056
|
if (useJson) logger.level = 0;
|
|
4057
|
+
if (ctx.values.id != null) return handleSessionIdLookup({ values: {
|
|
4058
|
+
id: ctx.values.id,
|
|
4059
|
+
mode: ctx.values.mode,
|
|
4060
|
+
offline: ctx.values.offline,
|
|
4061
|
+
jq: ctx.values.jq,
|
|
4062
|
+
timezone: ctx.values.timezone,
|
|
4063
|
+
locale: ctx.values.locale ?? "en-CA"
|
|
4064
|
+
} }, useJson);
|
|
3974
4065
|
const sessionData = await loadSessionData({
|
|
3975
4066
|
since: ctx.values.since,
|
|
3976
4067
|
until: ctx.values.until,
|
|
@@ -761,7 +761,7 @@ function _getDefaultLogLevel() {
|
|
|
761
761
|
return g ? LogLevels.debug : R ? LogLevels.warn : LogLevels.info;
|
|
762
762
|
}
|
|
763
763
|
const consola = createConsola$1();
|
|
764
|
-
var name = "ccusage", version = "15.9.
|
|
764
|
+
var name = "ccusage", version = "15.9.4", description = "Usage analysis tool for Claude Code";
|
|
765
765
|
const logger = consola.withTag(name);
|
|
766
766
|
if (process$1.env.LOG_LEVEL != null) {
|
|
767
767
|
const level = Number.parseInt(process$1.env.LOG_LEVEL, 10);
|
package/dist/logger.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { log, logger } from "./logger-
|
|
1
|
+
import { log, logger } from "./logger-QcakA1fc.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-DzkXdtDF.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-C0oFKDO-.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-CY2f8ZBq.js";
|
|
6
|
+
import { name, version } from "./logger-QcakA1fc.js";
|
|
7
7
|
import process from "node:process";
|
|
8
8
|
const LATEST_PROTOCOL_VERSION = "2025-06-18", SUPPORTED_PROTOCOL_VERSIONS = [
|
|
9
9
|
LATEST_PROTOCOL_VERSION,
|
package/dist/mcp.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-DzkXdtDF.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
3
|
import "./_types-C0oFKDO-.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-CY2f8ZBq.js";
|
|
6
|
+
import "./logger-QcakA1fc.js";
|
|
7
|
+
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-COJ_l32e.js";
|
|
8
8
|
export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { modelPricingSchema } from "./_types-C0oFKDO-.js";
|
|
2
|
-
import { logger } from "./logger-
|
|
2
|
+
import { logger } from "./logger-QcakA1fc.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