ccusage 15.9.9 → 16.0.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 +6 -0
- package/config-schema.json +783 -0
- package/dist/calculate-cost.d.ts +1 -1
- package/dist/{data-loader-BJnD_oR3.d.ts → data-loader--Ga8BPdt.d.ts} +4 -0
- package/dist/{data-loader-CM8RKePp.js → data-loader-Bf4qMLf2.js} +3 -3
- package/dist/data-loader.d.ts +1 -1
- package/dist/data-loader.js +3 -3
- package/dist/{debug-D5u7ZVKi.js → debug-Oi3WqR-w.js} +3 -3
- package/dist/debug.js +4 -4
- package/dist/index.js +217 -95
- package/dist/{logger-m79TqYfY.js → logger-ClcgjXEW.js} +1 -1
- package/dist/logger.js +1 -1
- package/dist/{mcp-r529IhIF.js → mcp-DW2TXqtN.js} +10 -10
- package/dist/mcp.d.ts +2 -4
- package/dist/mcp.js +4 -4
- package/dist/{pricing-fetcher-CbLCyFQr.js → pricing-fetcher-CUQk_dDN.js} +3 -3
- package/dist/pricing-fetcher.js +2 -2
- package/package.json +2 -1
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, inspectError, isFailure, isSuccess, map, pipe, require_usingCtx, succeed, try_ } from "./pricing-fetcher-
|
|
2
|
+
import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CONFIG_FILE_NAME, 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, inspect, inspectError, isFailure, isSuccess, map, pipe, require_usingCtx, succeed, try_ } from "./pricing-fetcher-CUQk_dDN.js";
|
|
3
3
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
4
4
|
import { CostModes, SortOrders, filterDateSchema, statuslineHookJsonSchema } from "./_types-BbEk8t2a.js";
|
|
5
5
|
import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
|
|
6
|
-
import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateContextTokens, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths, getContextUsageThresholds, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, uniq, unwrap, 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, calculateContextTokens, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths, getContextUsageThresholds, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, toArray, uniq, unwrap, usageDataSchema } from "./data-loader-Bf4qMLf2.js";
|
|
7
|
+
import { description, log, logger, name, version } from "./logger-ClcgjXEW.js";
|
|
8
|
+
import { detectMismatches, printMismatchReport } from "./debug-Oi3WqR-w.js";
|
|
9
|
+
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-DW2TXqtN.js";
|
|
10
10
|
import a, { readFile, stat } from "node:fs/promises";
|
|
11
11
|
import path, { join } from "node:path";
|
|
12
12
|
import process$1 from "node:process";
|
|
@@ -817,7 +817,94 @@ var require_picocolors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
817
817
|
};
|
|
818
818
|
};
|
|
819
819
|
module.exports = createColors(), module.exports.createColors = createColors;
|
|
820
|
-
})), import_picocolors$8 = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
820
|
+
})), import_picocolors$8 = /* @__PURE__ */ __toESM(require_picocolors(), 1), import_usingCtx$3 = /* @__PURE__ */ __toESM(require_usingCtx(), 1);
|
|
821
|
+
function extractExplicitArgs(tokens) {
|
|
822
|
+
const explicit = {};
|
|
823
|
+
for (const token of tokens) if (typeof token === "object" && token !== null) {
|
|
824
|
+
const t = token;
|
|
825
|
+
if (t.kind === "option" && typeof t.name === "string") explicit[t.name] = true;
|
|
826
|
+
}
|
|
827
|
+
return explicit;
|
|
828
|
+
}
|
|
829
|
+
function getConfigSearchPaths() {
|
|
830
|
+
const claudeConfigDirs = [join(process$1.cwd(), ".ccusage"), ...toArray(getClaudePaths())];
|
|
831
|
+
return claudeConfigDirs.map((dir) => join(dir, CONFIG_FILE_NAME));
|
|
832
|
+
}
|
|
833
|
+
function validateConfigJson(data) {
|
|
834
|
+
if (typeof data !== "object" || data === null) return false;
|
|
835
|
+
const config = data;
|
|
836
|
+
return !(config.$schema != null && typeof config.$schema !== "string" || config.defaults != null && (typeof config.defaults !== "object" || config.defaults === null) || config.commands != null && (typeof config.commands !== "object" || config.commands === null));
|
|
837
|
+
}
|
|
838
|
+
function loadConfigFile(filePath, debug$4 = false) {
|
|
839
|
+
if (!existsSync(filePath)) {
|
|
840
|
+
if (debug$4) logger.info(` • Checking: ${filePath} (not found)`);
|
|
841
|
+
return void 0;
|
|
842
|
+
}
|
|
843
|
+
const parseConfigFileResult = pipe(try_({
|
|
844
|
+
try: () => {
|
|
845
|
+
const content = readFileSync(filePath, "utf-8"), data = JSON.parse(content);
|
|
846
|
+
if (!validateConfigJson(data)) throw new Error("Invalid configuration structure");
|
|
847
|
+
return data.source = filePath, data;
|
|
848
|
+
},
|
|
849
|
+
catch: (error) => error
|
|
850
|
+
})(), inspect(() => {
|
|
851
|
+
if (logger.debug(`Parsed configuration file: ${filePath}`), debug$4) logger.info(` • Checking: ${filePath} (found ✓)`);
|
|
852
|
+
}), inspectError((error) => {
|
|
853
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
854
|
+
if (logger.warn(`Error parsing configuration file at ${filePath}: ${errorMessage}`), debug$4) logger.info(` • Checking: ${filePath} (error: ${errorMessage})`);
|
|
855
|
+
}), unwrap(void 0));
|
|
856
|
+
return parseConfigFileResult;
|
|
857
|
+
}
|
|
858
|
+
function loadConfig(configPath, debug$4 = false) {
|
|
859
|
+
if (debug$4) logger.info("Debug mode enabled - showing config loading details\n");
|
|
860
|
+
if (configPath != null) {
|
|
861
|
+
if (debug$4) logger.info("Using specified config file:"), logger.info(` • Path: ${configPath}`);
|
|
862
|
+
const config = loadConfigFile(configPath, debug$4);
|
|
863
|
+
if (config == null) logger.warn(`Configuration file not found or invalid: ${configPath}`);
|
|
864
|
+
else if (debug$4) logger.info(""), logger.info(`Loaded config from: ${configPath}`), logger.info(` • Schema: ${config.$schema ?? "none"}`), logger.info(` • Has defaults: ${config.defaults != null ? "yes" : "no"}${config.defaults != null ? ` (${Object.keys(config.defaults).length} options)` : ""}`), logger.info(` • Has command configs: ${config.commands != null ? "yes" : "no"}${config.commands != null ? ` (${Object.keys(config.commands).join(", ")})` : ""}`);
|
|
865
|
+
return config;
|
|
866
|
+
}
|
|
867
|
+
if (debug$4) logger.info("Searching for config files:");
|
|
868
|
+
for (const searchPath of getConfigSearchPaths()) {
|
|
869
|
+
const config = loadConfigFile(searchPath, debug$4);
|
|
870
|
+
if (config != null) {
|
|
871
|
+
if (debug$4) logger.info(""), logger.info(`Loaded config from: ${searchPath}`), logger.info(` • Schema: ${config.$schema ?? "none"}`), logger.info(` • Has defaults: ${config.defaults != null ? "yes" : "no"}${config.defaults != null ? ` (${Object.keys(config.defaults).length} options)` : ""}`), logger.info(` • Has command configs: ${config.commands != null ? "yes" : "no"}${config.commands != null ? ` (${Object.keys(config.commands).join(", ")})` : ""}`);
|
|
872
|
+
return config;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
if (logger.debug("No valid configuration file found"), debug$4) logger.info(""), logger.info("No valid configuration file found");
|
|
876
|
+
return void 0;
|
|
877
|
+
}
|
|
878
|
+
function mergeConfigWithArgs(ctx, config, debug$4 = false) {
|
|
879
|
+
if (config == null) {
|
|
880
|
+
if (debug$4) logger.info(""), logger.info(`No config file loaded, using CLI args only for '${ctx.name ?? "unknown"}' command`);
|
|
881
|
+
return ctx.values;
|
|
882
|
+
}
|
|
883
|
+
const merged = {}, commandName = ctx.name, sources = {};
|
|
884
|
+
if (config.defaults != null) for (const [key, value$1] of Object.entries(config.defaults)) merged[key] = value$1, sources[key] = "defaults";
|
|
885
|
+
if (commandName != null && config.commands?.[commandName] != null) for (const [key, value$1] of Object.entries(config.commands[commandName])) merged[key] = value$1, sources[key] = "command config";
|
|
886
|
+
const explicit = extractExplicitArgs(ctx.tokens);
|
|
887
|
+
for (const [key, value$1] of Object.entries(ctx.values)) if (value$1 != null && explicit[key] === true) merged[key] = value$1, sources[key] = "CLI";
|
|
888
|
+
if (logger.debug(`Merged config for ${commandName ?? "unknown"}:`, merged), debug$4) {
|
|
889
|
+
logger.info(""), logger.info(`Merging options for '${commandName ?? "unknown"}' command:`);
|
|
890
|
+
const bySource = {
|
|
891
|
+
"defaults": [],
|
|
892
|
+
"command config": [],
|
|
893
|
+
"CLI": []
|
|
894
|
+
};
|
|
895
|
+
for (const [key, source] of Object.entries(sources)) if (bySource[source] != null) bySource[source].push(`${key}=${JSON.stringify(merged[key])}`);
|
|
896
|
+
if (bySource.defaults.length > 0) logger.info(` • From defaults: ${bySource.defaults.join(", ")}`);
|
|
897
|
+
if (bySource["command config"].length > 0) logger.info(` • From command config: ${bySource["command config"].join(", ")}`);
|
|
898
|
+
if (bySource.CLI.length > 0) logger.info(` • From CLI args: ${bySource.CLI.join(", ")}`);
|
|
899
|
+
logger.info(" • Final merged options: {");
|
|
900
|
+
for (const [key, value$1] of Object.entries(merged)) {
|
|
901
|
+
const source = sources[key] ?? "unknown";
|
|
902
|
+
logger.info(` ${key}: ${JSON.stringify(value$1)} (from ${source}),`);
|
|
903
|
+
}
|
|
904
|
+
logger.info(" }");
|
|
905
|
+
}
|
|
906
|
+
return merged;
|
|
907
|
+
}
|
|
821
908
|
const getContext = (raw) => ({
|
|
822
909
|
start: process$1.hrtime.bigint(),
|
|
823
910
|
command: raw.map((part) => getCommandPart(stripVTControlCharacters(part))).join(" "),
|
|
@@ -1076,6 +1163,15 @@ const sharedArgs = {
|
|
|
1076
1163
|
type: "string",
|
|
1077
1164
|
short: "q",
|
|
1078
1165
|
description: "Process JSON output with jq command (requires jq binary, implies --json)"
|
|
1166
|
+
},
|
|
1167
|
+
config: {
|
|
1168
|
+
type: "string",
|
|
1169
|
+
description: "Path to configuration file (default: auto-discovery)"
|
|
1170
|
+
},
|
|
1171
|
+
compact: {
|
|
1172
|
+
type: "boolean",
|
|
1173
|
+
description: "Force compact mode for narrow displays (better for screenshots)",
|
|
1174
|
+
default: false
|
|
1079
1175
|
}
|
|
1080
1176
|
}, sharedCommandConfig = {
|
|
1081
1177
|
args: sharedArgs,
|
|
@@ -2381,8 +2477,9 @@ var import_usingCtx$2 = /* @__PURE__ */ __toESM(require_usingCtx(), 1), Responsi
|
|
|
2381
2477
|
compactColAligns;
|
|
2382
2478
|
compactThreshold;
|
|
2383
2479
|
compactMode = false;
|
|
2480
|
+
forceCompact;
|
|
2384
2481
|
constructor(options) {
|
|
2385
|
-
this.head = options.head, this.colAligns = options.colAligns ?? Array.from({ length: this.head.length }, () => "left"), this.style = options.style, this.dateFormatter = options.dateFormatter, this.compactHead = options.compactHead, this.compactColAligns = options.compactColAligns, this.compactThreshold = options.compactThreshold ?? 100;
|
|
2482
|
+
this.head = options.head, this.colAligns = options.colAligns ?? Array.from({ length: this.head.length }, () => "left"), this.style = options.style, this.dateFormatter = options.dateFormatter, this.compactHead = options.compactHead, this.compactColAligns = options.compactColAligns, this.compactThreshold = options.compactThreshold ?? 100, this.forceCompact = options.forceCompact ?? false;
|
|
2386
2483
|
}
|
|
2387
2484
|
push(row) {
|
|
2388
2485
|
this.rows.push(row);
|
|
@@ -2410,7 +2507,7 @@ var import_usingCtx$2 = /* @__PURE__ */ __toESM(require_usingCtx(), 1), Responsi
|
|
|
2410
2507
|
}
|
|
2411
2508
|
toString() {
|
|
2412
2509
|
const terminalWidth = Number.parseInt(process$1.env.COLUMNS ?? "", 10) || process$1.stdout.columns || 120;
|
|
2413
|
-
this.compactMode = terminalWidth < this.compactThreshold && this.compactHead != null;
|
|
2510
|
+
this.compactMode = this.forceCompact || terminalWidth < this.compactThreshold && this.compactHead != null;
|
|
2414
2511
|
const { head, colAligns } = this.getCurrentTableConfig(), compactIndices = this.getCompactIndices(), dataRows = this.rows.filter((row) => !this.isSeparatorRow(row)), processedDataRows = this.compactMode ? dataRows.map((row) => this.filterRowToCompact(row, compactIndices)) : dataRows, allRows = [head.map(String), ...processedDataRows.map((row) => row.map((cell) => {
|
|
2415
2512
|
return typeof cell === "object" && cell != null && "content" in cell ? String(cell.content) : String(cell ?? "");
|
|
2416
2513
|
}))], contentWidths = head.map((_, colIndex) => {
|
|
@@ -3066,7 +3163,7 @@ const blocksCommand = define({
|
|
|
3066
3163
|
},
|
|
3067
3164
|
toKebab: true,
|
|
3068
3165
|
async run(ctx) {
|
|
3069
|
-
const
|
|
3166
|
+
const config = loadConfig(ctx.values.config, ctx.values.debug), mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug), useJson = mergedOptions.json || mergedOptions.jq != null;
|
|
3070
3167
|
if (useJson) logger.level = 0;
|
|
3071
3168
|
if (ctx.values.sessionLength <= 0) logger.error("Session length must be a positive number"), process$1.exit(1);
|
|
3072
3169
|
let blocks = await loadSessionBlockData({
|
|
@@ -3192,7 +3289,7 @@ const blocksCommand = define({
|
|
|
3192
3289
|
head: tableHeaders,
|
|
3193
3290
|
style: { head: ["cyan"] },
|
|
3194
3291
|
colAligns: tableAligns
|
|
3195
|
-
}), terminalWidth = process$1.stdout.columns || BLOCKS_DEFAULT_TERMINAL_WIDTH,
|
|
3292
|
+
}), terminalWidth = process$1.stdout.columns || BLOCKS_DEFAULT_TERMINAL_WIDTH, isNarrowTerminal = terminalWidth < BLOCKS_COMPACT_WIDTH_THRESHOLD, useCompactFormat = ctx.values.compact || isNarrowTerminal;
|
|
3196
3293
|
for (const block of blocks) if (block.isGap ?? false) {
|
|
3197
3294
|
const gapRow = [
|
|
3198
3295
|
import_picocolors$5.default.gray(formatBlockTime(block, useCompactFormat, ctx.values.locale)),
|
|
@@ -3348,18 +3445,11 @@ const dailyCommand = define({
|
|
|
3348
3445
|
}
|
|
3349
3446
|
},
|
|
3350
3447
|
async run(ctx) {
|
|
3351
|
-
const
|
|
3448
|
+
const config = loadConfig(ctx.values.config, ctx.values.debug), mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug), useJson = Boolean(mergedOptions.json) || mergedOptions.jq != null;
|
|
3352
3449
|
if (useJson) logger.level = 0;
|
|
3353
3450
|
const dailyData = await loadDailyUsageData({
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
mode: ctx.values.mode,
|
|
3357
|
-
order: ctx.values.order,
|
|
3358
|
-
offline: ctx.values.offline,
|
|
3359
|
-
groupByProject: ctx.values.instances,
|
|
3360
|
-
project: ctx.values.project,
|
|
3361
|
-
timezone: ctx.values.timezone,
|
|
3362
|
-
locale: ctx.values.locale
|
|
3451
|
+
...mergedOptions,
|
|
3452
|
+
groupByProject: mergedOptions.instances
|
|
3363
3453
|
});
|
|
3364
3454
|
if (dailyData.length === 0) {
|
|
3365
3455
|
if (useJson) log(JSON.stringify([]));
|
|
@@ -3367,12 +3457,12 @@ const dailyCommand = define({
|
|
|
3367
3457
|
process$1.exit(0);
|
|
3368
3458
|
}
|
|
3369
3459
|
const totals = calculateTotals(dailyData);
|
|
3370
|
-
if (
|
|
3460
|
+
if (mergedOptions.debug && !useJson) {
|
|
3371
3461
|
const mismatchStats = await detectMismatches(void 0);
|
|
3372
|
-
printMismatchReport(mismatchStats,
|
|
3462
|
+
printMismatchReport(mismatchStats, mergedOptions.debugSamples);
|
|
3373
3463
|
}
|
|
3374
3464
|
if (useJson) {
|
|
3375
|
-
const jsonOutput =
|
|
3465
|
+
const jsonOutput = Boolean(mergedOptions.instances) && dailyData.some((d) => d.project != null) ? {
|
|
3376
3466
|
projects: groupByProject(dailyData),
|
|
3377
3467
|
totals: createTotalsObject(totals)
|
|
3378
3468
|
} : {
|
|
@@ -3390,8 +3480,8 @@ const dailyCommand = define({
|
|
|
3390
3480
|
})),
|
|
3391
3481
|
totals: createTotalsObject(totals)
|
|
3392
3482
|
};
|
|
3393
|
-
if (
|
|
3394
|
-
const jqResult = await processWithJq(jsonOutput,
|
|
3483
|
+
if (mergedOptions.jq != null) {
|
|
3484
|
+
const jqResult = await processWithJq(jsonOutput, mergedOptions.jq);
|
|
3395
3485
|
if (isFailure(jqResult)) logger.error(jqResult.error.message), process$1.exit(1);
|
|
3396
3486
|
log(jqResult.value);
|
|
3397
3487
|
} else log(JSON.stringify(jsonOutput, null, 2));
|
|
@@ -3419,7 +3509,7 @@ const dailyCommand = define({
|
|
|
3419
3509
|
"right",
|
|
3420
3510
|
"right"
|
|
3421
3511
|
],
|
|
3422
|
-
dateFormatter: (dateStr) => formatDateCompact(dateStr,
|
|
3512
|
+
dateFormatter: (dateStr) => formatDateCompact(dateStr, mergedOptions.timezone, mergedOptions.locale ?? void 0),
|
|
3423
3513
|
compactHead: [
|
|
3424
3514
|
"Date",
|
|
3425
3515
|
"Models",
|
|
@@ -3434,9 +3524,10 @@ const dailyCommand = define({
|
|
|
3434
3524
|
"right",
|
|
3435
3525
|
"right"
|
|
3436
3526
|
],
|
|
3437
|
-
compactThreshold: 100
|
|
3527
|
+
compactThreshold: 100,
|
|
3528
|
+
forceCompact: ctx.values.compact
|
|
3438
3529
|
});
|
|
3439
|
-
if (
|
|
3530
|
+
if (Boolean(mergedOptions.instances) && dailyData.some((d) => d.project != null)) {
|
|
3440
3531
|
const projectGroups = groupDataByProject(dailyData);
|
|
3441
3532
|
let isFirstProject = true;
|
|
3442
3533
|
for (const [projectName, projectData] of Object.entries(projectGroups)) {
|
|
@@ -3469,7 +3560,7 @@ const dailyCommand = define({
|
|
|
3469
3560
|
formatNumber(data.cacheReadTokens),
|
|
3470
3561
|
formatNumber(getTotalTokens(data)),
|
|
3471
3562
|
formatCurrency(data.totalCost)
|
|
3472
|
-
]),
|
|
3563
|
+
]), mergedOptions.breakdown) pushBreakdownRows(table, data.modelBreakdowns);
|
|
3473
3564
|
isFirstProject = false;
|
|
3474
3565
|
}
|
|
3475
3566
|
} else for (const data of dailyData) if (table.push([
|
|
@@ -3481,7 +3572,7 @@ const dailyCommand = define({
|
|
|
3481
3572
|
formatNumber(data.cacheReadTokens),
|
|
3482
3573
|
formatNumber(getTotalTokens(data)),
|
|
3483
3574
|
formatCurrency(data.totalCost)
|
|
3484
|
-
]),
|
|
3575
|
+
]), mergedOptions.breakdown) pushBreakdownRows(table, data.modelBreakdowns);
|
|
3485
3576
|
if (table.push([
|
|
3486
3577
|
"",
|
|
3487
3578
|
"",
|
|
@@ -3893,17 +3984,9 @@ const monthlyCommand = define({
|
|
|
3893
3984
|
description: "Show usage report grouped by month",
|
|
3894
3985
|
...sharedCommandConfig,
|
|
3895
3986
|
async run(ctx) {
|
|
3896
|
-
const
|
|
3987
|
+
const config = loadConfig(ctx.values.config, ctx.values.debug), mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug), useJson = Boolean(mergedOptions.json) || mergedOptions.jq != null;
|
|
3897
3988
|
if (useJson) logger.level = 0;
|
|
3898
|
-
const monthlyData = await loadMonthlyUsageData(
|
|
3899
|
-
since: ctx.values.since,
|
|
3900
|
-
until: ctx.values.until,
|
|
3901
|
-
mode: ctx.values.mode,
|
|
3902
|
-
order: ctx.values.order,
|
|
3903
|
-
offline: ctx.values.offline,
|
|
3904
|
-
timezone: ctx.values.timezone,
|
|
3905
|
-
locale: ctx.values.locale
|
|
3906
|
-
});
|
|
3989
|
+
const monthlyData = await loadMonthlyUsageData(mergedOptions);
|
|
3907
3990
|
if (monthlyData.length === 0) {
|
|
3908
3991
|
if (useJson) {
|
|
3909
3992
|
const emptyOutput = {
|
|
@@ -3922,9 +4005,9 @@ const monthlyCommand = define({
|
|
|
3922
4005
|
process$1.exit(0);
|
|
3923
4006
|
}
|
|
3924
4007
|
const totals = calculateTotals(monthlyData);
|
|
3925
|
-
if (
|
|
4008
|
+
if (mergedOptions.debug && !useJson) {
|
|
3926
4009
|
const mismatchStats = await detectMismatches(void 0);
|
|
3927
|
-
printMismatchReport(mismatchStats,
|
|
4010
|
+
printMismatchReport(mismatchStats, mergedOptions.debugSamples);
|
|
3928
4011
|
}
|
|
3929
4012
|
if (useJson) {
|
|
3930
4013
|
const jsonOutput = {
|
|
@@ -3941,8 +4024,8 @@ const monthlyCommand = define({
|
|
|
3941
4024
|
})),
|
|
3942
4025
|
totals: createTotalsObject(totals)
|
|
3943
4026
|
};
|
|
3944
|
-
if (
|
|
3945
|
-
const jqResult = await processWithJq(jsonOutput,
|
|
4027
|
+
if (mergedOptions.jq != null) {
|
|
4028
|
+
const jqResult = await processWithJq(jsonOutput, mergedOptions.jq);
|
|
3946
4029
|
if (isFailure(jqResult)) logger.error(jqResult.error.message), process$1.exit(1);
|
|
3947
4030
|
log(jqResult.value);
|
|
3948
4031
|
} else log(JSON.stringify(jsonOutput, null, 2));
|
|
@@ -3970,7 +4053,7 @@ const monthlyCommand = define({
|
|
|
3970
4053
|
"right",
|
|
3971
4054
|
"right"
|
|
3972
4055
|
],
|
|
3973
|
-
dateFormatter: (dateStr) => formatDateCompact(dateStr,
|
|
4056
|
+
dateFormatter: (dateStr) => formatDateCompact(dateStr, mergedOptions.timezone, mergedOptions.locale ?? "en-CA"),
|
|
3974
4057
|
compactHead: [
|
|
3975
4058
|
"Month",
|
|
3976
4059
|
"Models",
|
|
@@ -3985,7 +4068,8 @@ const monthlyCommand = define({
|
|
|
3985
4068
|
"right",
|
|
3986
4069
|
"right"
|
|
3987
4070
|
],
|
|
3988
|
-
compactThreshold: 100
|
|
4071
|
+
compactThreshold: 100,
|
|
4072
|
+
forceCompact: ctx.values.compact
|
|
3989
4073
|
});
|
|
3990
4074
|
for (const data of monthlyData) if (table.push([
|
|
3991
4075
|
data.month,
|
|
@@ -3996,7 +4080,7 @@ const monthlyCommand = define({
|
|
|
3996
4080
|
formatNumber(data.cacheReadTokens),
|
|
3997
4081
|
formatNumber(getTotalTokens(data)),
|
|
3998
4082
|
formatCurrency(data.totalCost)
|
|
3999
|
-
]),
|
|
4083
|
+
]), mergedOptions.breakdown) pushBreakdownRows(table, data.modelBreakdowns);
|
|
4000
4084
|
if (table.push([
|
|
4001
4085
|
"",
|
|
4002
4086
|
"",
|
|
@@ -4108,15 +4192,15 @@ const sessionCommand = define({
|
|
|
4108
4192
|
},
|
|
4109
4193
|
toKebab: true,
|
|
4110
4194
|
async run(ctx) {
|
|
4111
|
-
const
|
|
4195
|
+
const config = loadConfig(ctx.values.config, ctx.values.debug), mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug), useJson = mergedOptions.json || mergedOptions.jq != null;
|
|
4112
4196
|
if (useJson) logger.level = 0;
|
|
4113
|
-
if (
|
|
4114
|
-
id:
|
|
4115
|
-
mode:
|
|
4116
|
-
offline:
|
|
4117
|
-
jq:
|
|
4118
|
-
timezone:
|
|
4119
|
-
locale:
|
|
4197
|
+
if (mergedOptions.id != null) return handleSessionIdLookup({ values: {
|
|
4198
|
+
id: mergedOptions.id,
|
|
4199
|
+
mode: mergedOptions.mode,
|
|
4200
|
+
offline: mergedOptions.offline,
|
|
4201
|
+
jq: mergedOptions.jq,
|
|
4202
|
+
timezone: mergedOptions.timezone,
|
|
4203
|
+
locale: mergedOptions.locale ?? "en-CA"
|
|
4120
4204
|
} }, useJson);
|
|
4121
4205
|
const sessionData = await loadSessionData({
|
|
4122
4206
|
since: ctx.values.since,
|
|
@@ -4202,7 +4286,8 @@ const sessionCommand = define({
|
|
|
4202
4286
|
"right",
|
|
4203
4287
|
"left"
|
|
4204
4288
|
],
|
|
4205
|
-
compactThreshold: 100
|
|
4289
|
+
compactThreshold: 100,
|
|
4290
|
+
forceCompact: ctx.values.compact
|
|
4206
4291
|
});
|
|
4207
4292
|
let maxSessionLength = 0;
|
|
4208
4293
|
for (const data of sessionData) {
|
|
@@ -5123,7 +5208,12 @@ function getSemaphore(sessionId) {
|
|
|
5123
5208
|
const semaphore = createLimoJson(semaphorePath);
|
|
5124
5209
|
return semaphore;
|
|
5125
5210
|
}
|
|
5126
|
-
const
|
|
5211
|
+
const visualBurnRateChoices = [
|
|
5212
|
+
"off",
|
|
5213
|
+
"emoji",
|
|
5214
|
+
"text",
|
|
5215
|
+
"emoji-text"
|
|
5216
|
+
], statuslineCommand = define({
|
|
5127
5217
|
name: "statusline",
|
|
5128
5218
|
description: "Display compact status line for Claude Code hooks with hybrid time+file caching (Beta)",
|
|
5129
5219
|
toKebab: true,
|
|
@@ -5132,6 +5222,15 @@ const statuslineCommand = define({
|
|
|
5132
5222
|
...sharedArgs.offline,
|
|
5133
5223
|
default: true
|
|
5134
5224
|
},
|
|
5225
|
+
visualBurnRate: {
|
|
5226
|
+
type: "enum",
|
|
5227
|
+
choices: visualBurnRateChoices,
|
|
5228
|
+
description: "Controls the visualization of the burn rate status",
|
|
5229
|
+
default: "off",
|
|
5230
|
+
short: "vb",
|
|
5231
|
+
negatable: false,
|
|
5232
|
+
toKebab: true
|
|
5233
|
+
},
|
|
5135
5234
|
cache: {
|
|
5136
5235
|
type: "boolean",
|
|
5137
5236
|
description: "Enable cache for status line output (default: true)",
|
|
@@ -5141,16 +5240,18 @@ const statuslineCommand = define({
|
|
|
5141
5240
|
type: "number",
|
|
5142
5241
|
description: `Refresh interval in seconds for cache expiry (default: ${DEFAULT_REFRESH_INTERVAL_SECONDS})`,
|
|
5143
5242
|
default: DEFAULT_REFRESH_INTERVAL_SECONDS
|
|
5144
|
-
}
|
|
5243
|
+
},
|
|
5244
|
+
config: sharedArgs.config,
|
|
5245
|
+
debug: sharedArgs.debug
|
|
5145
5246
|
},
|
|
5146
5247
|
async run(ctx) {
|
|
5147
5248
|
logger.level = 0;
|
|
5148
|
-
const
|
|
5249
|
+
const config = loadConfig(ctx.values.config, ctx.values.debug), mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug), refreshInterval = mergedOptions.refreshInterval, stdin$2 = await getStdin();
|
|
5149
5250
|
if (stdin$2.length === 0) log("❌ No input provided"), process$1.exit(1);
|
|
5150
5251
|
const hookDataJson = JSON.parse(stdin$2.trim()), hookDataParseResult = statuslineHookJsonSchema.safeParse(hookDataJson);
|
|
5151
5252
|
if (!hookDataParseResult.success) log("❌ Invalid input format:", hookDataParseResult.error.message), process$1.exit(1);
|
|
5152
5253
|
const hookData = hookDataParseResult.data, sessionId = hookData.session_id, initialSemaphoreState = pipe(succeed(getSemaphore(sessionId)), map((semaphore) => semaphore.data), unwrap(void 0)), currentMtime = await getFileModifiedTime(hookData.transcript_path);
|
|
5153
|
-
if (
|
|
5254
|
+
if (mergedOptions.cache && initialSemaphoreState != null) {
|
|
5154
5255
|
const now = Date.now(), timeElapsed = now - (initialSemaphoreState.lastUpdateTime ?? 0), isExpired = timeElapsed >= refreshInterval * 1e3, isFileModified = initialSemaphoreState.transcriptMtime !== currentMtime;
|
|
5155
5256
|
if (!isExpired && !isFileModified) {
|
|
5156
5257
|
log(initialSemaphoreState.lastOutput);
|
|
@@ -5200,7 +5301,7 @@ const statuslineCommand = define({
|
|
|
5200
5301
|
const sessionCost = await pipe(try_({
|
|
5201
5302
|
try: loadSessionUsageById(sessionId, {
|
|
5202
5303
|
mode: "auto",
|
|
5203
|
-
offline:
|
|
5304
|
+
offline: mergedOptions.offline
|
|
5204
5305
|
}),
|
|
5205
5306
|
catch: (error) => error
|
|
5206
5307
|
}), map((sessionCost$1) => sessionCost$1?.totalCost), inspectError((error) => logger.error("Failed to load session data:", error)), unwrap(void 0)), today = /* @__PURE__ */ new Date(), todayStr = today.toISOString().split("T")[0]?.replace(/-/g, "") ?? "", todayCost = await pipe(try_({
|
|
@@ -5208,7 +5309,7 @@ const statuslineCommand = define({
|
|
|
5208
5309
|
since: todayStr,
|
|
5209
5310
|
until: todayStr,
|
|
5210
5311
|
mode: "auto",
|
|
5211
|
-
offline:
|
|
5312
|
+
offline: mergedOptions.offline
|
|
5212
5313
|
}),
|
|
5213
5314
|
catch: (error) => error
|
|
5214
5315
|
}), map((dailyData) => {
|
|
@@ -5220,7 +5321,7 @@ const statuslineCommand = define({
|
|
|
5220
5321
|
}), inspectError((error) => logger.error("Failed to load daily data:", error)), unwrap(0)), { blockInfo, burnRateInfo } = await pipe(try_({
|
|
5221
5322
|
try: loadSessionBlockData({
|
|
5222
5323
|
mode: "auto",
|
|
5223
|
-
offline:
|
|
5324
|
+
offline: mergedOptions.offline
|
|
5224
5325
|
}),
|
|
5225
5326
|
catch: (error) => error
|
|
5226
5327
|
}), map((blocks) => {
|
|
@@ -5233,8 +5334,26 @@ const statuslineCommand = define({
|
|
|
5233
5334
|
});
|
|
5234
5335
|
if (activeBlock != null) {
|
|
5235
5336
|
const now = /* @__PURE__ */ new Date(), remaining = Math.round((activeBlock.endTime.getTime() - now.getTime()) / (1e3 * 60)), blockCost = activeBlock.costUSD, blockInfo$1 = `${formatCurrency(blockCost)} block (${formatRemainingTime(remaining)})`, burnRate = calculateBurnRate(activeBlock), burnRateInfo$1 = burnRate != null ? (() => {
|
|
5236
|
-
const costPerHour = burnRate.costPerHour, costPerHourStr = `${formatCurrency(costPerHour)}/hr`,
|
|
5237
|
-
|
|
5337
|
+
const renderEmojiStatus = ctx.values.visualBurnRate === "emoji" || ctx.values.visualBurnRate === "emoji-text", renderTextStatus = ctx.values.visualBurnRate === "text" || ctx.values.visualBurnRate === "emoji-text", costPerHour = burnRate.costPerHour, costPerHourStr = `${formatCurrency(costPerHour)}/hr`, burnStatus = burnRate.tokensPerMinuteForIndicator < 2e3 ? "normal" : burnRate.tokensPerMinuteForIndicator < 5e3 ? "moderate" : "high", burnStatusMappings = {
|
|
5338
|
+
normal: {
|
|
5339
|
+
emoji: "🟢",
|
|
5340
|
+
textValue: "Normal",
|
|
5341
|
+
coloredString: import_picocolors$1.default.green
|
|
5342
|
+
},
|
|
5343
|
+
moderate: {
|
|
5344
|
+
emoji: "⚠️",
|
|
5345
|
+
textValue: "Moderate",
|
|
5346
|
+
coloredString: import_picocolors$1.default.yellow
|
|
5347
|
+
},
|
|
5348
|
+
high: {
|
|
5349
|
+
emoji: "🚨",
|
|
5350
|
+
textValue: "High",
|
|
5351
|
+
coloredString: import_picocolors$1.default.red
|
|
5352
|
+
}
|
|
5353
|
+
}, { emoji, textValue, coloredString } = burnStatusMappings[burnStatus], burnRateOutputSegments = [coloredString(costPerHourStr)];
|
|
5354
|
+
if (renderEmojiStatus) burnRateOutputSegments.push(emoji);
|
|
5355
|
+
if (renderTextStatus) burnRateOutputSegments.push(coloredString(`(${textValue})`));
|
|
5356
|
+
return ` | 🔥 ${burnRateOutputSegments.join(" ")}`;
|
|
5238
5357
|
})() : "";
|
|
5239
5358
|
return {
|
|
5240
5359
|
blockInfo: blockInfo$1,
|
|
@@ -5249,7 +5368,7 @@ const statuslineCommand = define({
|
|
|
5249
5368
|
blockInfo: "No active block",
|
|
5250
5369
|
burnRateInfo: ""
|
|
5251
5370
|
})), contextInfo = await pipe(try_({
|
|
5252
|
-
try: calculateContextTokens(hookData.transcript_path, hookData.model.id,
|
|
5371
|
+
try: calculateContextTokens(hookData.transcript_path, hookData.model.id, mergedOptions.offline),
|
|
5253
5372
|
catch: (error) => error
|
|
5254
5373
|
}), inspectError((error) => logger.debug(`Failed to calculate context tokens: ${error instanceof Error ? error.message : String(error)}`)), map((ctx$1) => {
|
|
5255
5374
|
if (ctx$1 == null) return void 0;
|
|
@@ -5263,7 +5382,7 @@ const statuslineCommand = define({
|
|
|
5263
5382
|
if (isSuccess(mainProcessingResult)) try {
|
|
5264
5383
|
var _usingCtx3 = (0, import_usingCtx.default)();
|
|
5265
5384
|
const statusLine = mainProcessingResult.value;
|
|
5266
|
-
if (log(statusLine), !
|
|
5385
|
+
if (log(statusLine), !mergedOptions.cache) return;
|
|
5267
5386
|
const semaphore = _usingCtx3.u(getSemaphore(sessionId));
|
|
5268
5387
|
semaphore.data = {
|
|
5269
5388
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -5284,7 +5403,7 @@ const statuslineCommand = define({
|
|
|
5284
5403
|
var _usingCtx4 = (0, import_usingCtx.default)();
|
|
5285
5404
|
if (initialSemaphoreState?.lastOutput != null && initialSemaphoreState.lastOutput !== "") log(initialSemaphoreState.lastOutput);
|
|
5286
5405
|
else log("❌ Error generating status");
|
|
5287
|
-
if (logger.error("Error in statusline command:", mainProcessingResult.error), !
|
|
5406
|
+
if (logger.error("Error in statusline command:", mainProcessingResult.error), !mergedOptions.cache) return;
|
|
5288
5407
|
const semaphore = _usingCtx4.u(getSemaphore(sessionId));
|
|
5289
5408
|
if (semaphore.data != null) semaphore.data.isUpdating = false, semaphore.data.pid = void 0;
|
|
5290
5409
|
} catch (_) {
|
|
@@ -5310,18 +5429,9 @@ const weeklyCommand = define({
|
|
|
5310
5429
|
},
|
|
5311
5430
|
toKebab: true,
|
|
5312
5431
|
async run(ctx) {
|
|
5313
|
-
const
|
|
5432
|
+
const config = loadConfig(ctx.values.config, ctx.values.debug), mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug), useJson = Boolean(mergedOptions.json) || mergedOptions.jq != null;
|
|
5314
5433
|
if (useJson) logger.level = 0;
|
|
5315
|
-
const weeklyData = await loadWeeklyUsageData(
|
|
5316
|
-
since: ctx.values.since,
|
|
5317
|
-
until: ctx.values.until,
|
|
5318
|
-
timezone: ctx.values.timezone,
|
|
5319
|
-
mode: ctx.values.mode,
|
|
5320
|
-
order: ctx.values.order,
|
|
5321
|
-
offline: ctx.values.offline,
|
|
5322
|
-
startOfWeek: ctx.values.startOfWeek,
|
|
5323
|
-
locale: ctx.values.locale
|
|
5324
|
-
});
|
|
5434
|
+
const weeklyData = await loadWeeklyUsageData(mergedOptions);
|
|
5325
5435
|
if (weeklyData.length === 0) {
|
|
5326
5436
|
if (useJson) {
|
|
5327
5437
|
const emptyOutput = {
|
|
@@ -5340,9 +5450,9 @@ const weeklyCommand = define({
|
|
|
5340
5450
|
process$1.exit(0);
|
|
5341
5451
|
}
|
|
5342
5452
|
const totals = calculateTotals(weeklyData);
|
|
5343
|
-
if (
|
|
5453
|
+
if (mergedOptions.debug && !useJson) {
|
|
5344
5454
|
const mismatchStats = await detectMismatches(void 0);
|
|
5345
|
-
printMismatchReport(mismatchStats,
|
|
5455
|
+
printMismatchReport(mismatchStats, mergedOptions.debugSamples);
|
|
5346
5456
|
}
|
|
5347
5457
|
if (useJson) {
|
|
5348
5458
|
const jsonOutput = {
|
|
@@ -5359,8 +5469,8 @@ const weeklyCommand = define({
|
|
|
5359
5469
|
})),
|
|
5360
5470
|
totals: createTotalsObject(totals)
|
|
5361
5471
|
};
|
|
5362
|
-
if (
|
|
5363
|
-
const jqResult = await processWithJq(jsonOutput,
|
|
5472
|
+
if (mergedOptions.jq != null) {
|
|
5473
|
+
const jqResult = await processWithJq(jsonOutput, mergedOptions.jq);
|
|
5364
5474
|
if (isFailure(jqResult)) logger.error(jqResult.error.message), process$1.exit(1);
|
|
5365
5475
|
log(jqResult.value);
|
|
5366
5476
|
} else log(JSON.stringify(jsonOutput, null, 2));
|
|
@@ -5388,7 +5498,7 @@ const weeklyCommand = define({
|
|
|
5388
5498
|
"right",
|
|
5389
5499
|
"right"
|
|
5390
5500
|
],
|
|
5391
|
-
dateFormatter: (dateStr) => formatDateCompact(dateStr,
|
|
5501
|
+
dateFormatter: (dateStr) => formatDateCompact(dateStr, mergedOptions.timezone, mergedOptions.locale ?? void 0),
|
|
5392
5502
|
compactHead: [
|
|
5393
5503
|
"Week",
|
|
5394
5504
|
"Models",
|
|
@@ -5403,7 +5513,8 @@ const weeklyCommand = define({
|
|
|
5403
5513
|
"right",
|
|
5404
5514
|
"right"
|
|
5405
5515
|
],
|
|
5406
|
-
compactThreshold: 100
|
|
5516
|
+
compactThreshold: 100,
|
|
5517
|
+
forceCompact: ctx.values.compact
|
|
5407
5518
|
});
|
|
5408
5519
|
for (const data of weeklyData) if (table.push([
|
|
5409
5520
|
data.week,
|
|
@@ -5414,7 +5525,7 @@ const weeklyCommand = define({
|
|
|
5414
5525
|
formatNumber(data.cacheReadTokens),
|
|
5415
5526
|
formatNumber(getTotalTokens(data)),
|
|
5416
5527
|
formatCurrency(data.totalCost)
|
|
5417
|
-
]),
|
|
5528
|
+
]), mergedOptions.breakdown) pushBreakdownRows(table, data.modelBreakdowns);
|
|
5418
5529
|
if (table.push([
|
|
5419
5530
|
"",
|
|
5420
5531
|
"",
|
|
@@ -5436,14 +5547,25 @@ const weeklyCommand = define({
|
|
|
5436
5547
|
]), log(table.toString()), table.isCompactMode()) logger.info("\nRunning in Compact Mode"), logger.info("Expand terminal width to see cache metrics and total tokens");
|
|
5437
5548
|
}
|
|
5438
5549
|
}
|
|
5439
|
-
}),
|
|
5440
|
-
|
|
5550
|
+
}), subCommandUnion = [
|
|
5551
|
+
["daily", dailyCommand],
|
|
5552
|
+
["monthly", monthlyCommand],
|
|
5553
|
+
["weekly", weeklyCommand],
|
|
5554
|
+
["session", sessionCommand],
|
|
5555
|
+
["blocks", blocksCommand],
|
|
5556
|
+
["mcp", mcpCommand],
|
|
5557
|
+
["statusline", statuslineCommand]
|
|
5558
|
+
], subCommands = /* @__PURE__ */ new Map();
|
|
5559
|
+
for (const [name$1, command] of subCommandUnion) subCommands.set(name$1, command);
|
|
5441
5560
|
const mainCommand = dailyCommand;
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5561
|
+
async function run() {
|
|
5562
|
+
await cli(process$1.argv.slice(2), mainCommand, {
|
|
5563
|
+
name,
|
|
5564
|
+
version,
|
|
5565
|
+
description,
|
|
5566
|
+
subCommands,
|
|
5567
|
+
renderHeader: null
|
|
5568
|
+
});
|
|
5569
|
+
}
|
|
5570
|
+
await run();
|
|
5449
5571
|
export {};
|
|
@@ -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 = "
|
|
764
|
+
var name = "ccusage", version = "16.0.0", 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-ClcgjXEW.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-CUQk_dDN.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-BbEk8t2a.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-Bf4qMLf2.js";
|
|
6
|
+
import { name, version } from "./logger-ClcgjXEW.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,
|
|
@@ -6670,12 +6670,12 @@ function transformUsageDataWithTotals(data, totals, mapper, key) {
|
|
|
6670
6670
|
totals: createTotalsObject(totals)
|
|
6671
6671
|
};
|
|
6672
6672
|
}
|
|
6673
|
-
|
|
6673
|
+
function defaultOptions() {
|
|
6674
6674
|
const paths = getClaudePaths();
|
|
6675
6675
|
if (paths.length === 0) throw new Error("No valid Claude path found. Ensure getClaudePaths() returns at least one valid path.");
|
|
6676
|
-
return paths[0];
|
|
6677
|
-
}
|
|
6678
|
-
function createMcpServer(
|
|
6676
|
+
return { claudePath: paths[0] };
|
|
6677
|
+
}
|
|
6678
|
+
function createMcpServer(options) {
|
|
6679
6679
|
const server = new McpServer({
|
|
6680
6680
|
name,
|
|
6681
6681
|
version
|
|
@@ -6689,7 +6689,7 @@ function createMcpServer({ claudePath } = defaultOptions) {
|
|
|
6689
6689
|
]).default("auto").optional(),
|
|
6690
6690
|
timezone: stringType().optional(),
|
|
6691
6691
|
locale: stringType().default("en-CA").optional()
|
|
6692
|
-
};
|
|
6692
|
+
}, { claudePath } = options ?? defaultOptions();
|
|
6693
6693
|
return server.registerTool("daily", {
|
|
6694
6694
|
description: "Show usage report grouped by date",
|
|
6695
6695
|
inputSchema: parametersZodSchema,
|
|
@@ -6807,8 +6807,8 @@ async function startMcpServerStdio(server) {
|
|
|
6807
6807
|
const transport = new StdioServerTransport();
|
|
6808
6808
|
await server.connect(transport);
|
|
6809
6809
|
}
|
|
6810
|
-
function createMcpHttpApp(options
|
|
6811
|
-
const app = new Hono(), mcpServer = createMcpServer(options);
|
|
6810
|
+
function createMcpHttpApp(options) {
|
|
6811
|
+
const app = new Hono(), mcpServer = createMcpServer(options ?? defaultOptions());
|
|
6812
6812
|
return app.all("/", async (c) => {
|
|
6813
6813
|
const transport = new StreamableHTTPTransport();
|
|
6814
6814
|
return await mcpServer.connect(transport), transport.handleRequest(c);
|