ccusage 0.5.0 → 0.6.1
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 +65 -20
- package/dist/calculate-cost.d.ts +11 -8
- package/dist/{core-BgFXUe_h.js → core-B0ovMhJe.js} +4 -4
- package/dist/{data-loader-r5ZcMQy7.js → data-loader-DP5qBPn6.js} +153 -96
- package/dist/{data-loader-LMCrJ-lW.d.ts → data-loader-VdEcqJHc.d.ts} +28 -13
- package/dist/data-loader.d.ts +3 -5
- package/dist/data-loader.js +5 -5
- package/dist/{debug-BVxGf4UL.js → debug-C_5Qx11m.js} +13 -13
- package/dist/debug.d.ts +4 -4
- package/dist/debug.js +5 -5
- package/dist/{dist-FwNhpFrW.js → dist-C0-Tf5eD.js} +1 -92
- package/dist/{dist-C_i5I27w.js → dist-LwbOR2Yw.js} +5 -5
- package/dist/{effect-WSjEuzC9-BsxP11fz.js → effect-WSjEuzC9-CJfWUy0j.js} +1 -1
- package/dist/{esm-vjyZjnpZ.js → esm-Dqsc1zmX.js} +1 -1
- package/dist/{index-CISmcbXk-BotItq1T.js → index-CISmcbXk-DCA05NUL.js} +5 -5
- package/dist/index.js +246 -62
- package/dist/{logger-Cu4Ir1a5.js → logger-DsQC4OvA.js} +17 -17
- package/dist/logger.js +1 -1
- package/dist/{mcp-DAzj5Pua.js → mcp-BQdv12mr.js} +83 -74
- package/dist/mcp.d.ts +2 -4
- package/dist/mcp.js +7 -8
- package/dist/{pricing-fetcher-B5yPtoTB.js → pricing-fetcher-BPUgMrB_.js} +9 -9
- package/dist/{index-BurjgCfW.d.ts → pricing-fetcher-CfEgfzSr.d.ts} +19 -249
- package/dist/pricing-fetcher.d.ts +1 -2
- package/dist/pricing-fetcher.js +3 -3
- package/dist/{prompt-IToGuko2.js → prompt-DljZqwMa.js} +4 -4
- package/dist/{sury-DmrZ3_Oj-DhGOjCNc.js → sury-DmrZ3_Oj-CCL_DlTt.js} +1 -1
- package/dist/{types-CFnCBr2I.js → types-DS8M8QF_.js} +4 -4
- package/dist/{valibot-CQk-M5rL-Cq5E7F3g.js → valibot-CQk-M5rL-CkjrLVu1.js} +2 -2
- package/dist/{zod-Db63SLXj-BWdcigdx.js → zod-Db63SLXj-Dyc_OWjq.js} +3 -3
- package/package.json +8 -11
- package/dist/pricing-fetcher-DygIroMj.d.ts +0 -21
- package/dist/shared-args-DN3jRldX.js +0 -61
- package/dist/shared-args.d.ts +0 -94
- package/dist/shared-args.js +0 -8
- package/dist/types-B3ib19os.d.ts +0 -79
- package/dist/types-DFrbJmnT.js +0 -41
- package/dist/types.d.ts +0 -3
- package/dist/types.js +0 -4
- package/dist/utils-C7kg8MXN.js +0 -10
- package/dist/utils.d.ts +0 -5
- package/dist/utils.js +0 -3
- /package/dist/{arktype-C-GObzDh-Dj1DVoqC.js → arktype-C-GObzDh-Bx7Fdrqj.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { __commonJS, __require, __toESM,
|
|
2
|
+
import { __commonJS, __require, __toESM, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData } from "./data-loader-DP5qBPn6.js";
|
|
3
3
|
import { calculateTotals, createTotalsObject, getTotalTokens } from "./calculate-cost-2IwHSzmi.js";
|
|
4
|
-
import "./dist-
|
|
5
|
-
import { description, log, logger, name, version } from "./logger-
|
|
6
|
-
import "./pricing-fetcher-
|
|
7
|
-
import { detectMismatches, printMismatchReport } from "./debug-
|
|
8
|
-
import "./
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import "
|
|
12
|
-
import { createMcpServer } from "./mcp-DAzj5Pua.js";
|
|
13
|
-
import "./index-CISmcbXk-BotItq1T.js";
|
|
14
|
-
import process$1 from "node:process";
|
|
4
|
+
import { safeParse } from "./dist-C0-Tf5eD.js";
|
|
5
|
+
import { description, log, logger, name, version } from "./logger-DsQC4OvA.js";
|
|
6
|
+
import "./pricing-fetcher-BPUgMrB_.js";
|
|
7
|
+
import { detectMismatches, printMismatchReport } from "./debug-C_5Qx11m.js";
|
|
8
|
+
import { CostModes, SortOrders, createMcpServer, dateSchema } from "./mcp-BQdv12mr.js";
|
|
9
|
+
import "./types-DS8M8QF_.js";
|
|
10
|
+
import "./index-CISmcbXk-DCA05NUL.js";
|
|
11
|
+
import g$1 from "node:process";
|
|
15
12
|
|
|
16
|
-
//#region node_modules/gunshi/lib/utils-
|
|
13
|
+
//#region node_modules/gunshi/lib/utils-D41C8Abf.js
|
|
17
14
|
/**
|
|
18
15
|
* The default locale string, which format is BCP 47 language tag.
|
|
19
16
|
*/
|
|
@@ -84,14 +81,6 @@ async function resolveLazyCommand(cmd, name$1, needRunResolving = false) {
|
|
|
84
81
|
function resolveBuiltInKey(key) {
|
|
85
82
|
return `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
|
|
86
83
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Convert a camelCase string to kebab-case
|
|
89
|
-
* @param str The string to convert
|
|
90
|
-
* @returns The kebab-case version of the string
|
|
91
|
-
*/
|
|
92
|
-
function kebabnize$1(str) {
|
|
93
|
-
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
94
|
-
}
|
|
95
84
|
function resolveArgKey(key) {
|
|
96
85
|
return `${ARG_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
|
|
97
86
|
}
|
|
@@ -120,7 +109,7 @@ function deepFreeze(obj) {
|
|
|
120
109
|
}
|
|
121
110
|
|
|
122
111
|
//#endregion
|
|
123
|
-
//#region node_modules/gunshi/lib/context-
|
|
112
|
+
//#region node_modules/gunshi/lib/context-D_EmfRNA.js
|
|
124
113
|
var COMMAND = "COMMAND";
|
|
125
114
|
var COMMANDS = "COMMANDS";
|
|
126
115
|
var SUBCOMMAND = "SUBCOMMAND";
|
|
@@ -153,7 +142,7 @@ function createTranslationAdapter(options) {
|
|
|
153
142
|
return new DefaultTranslation(options);
|
|
154
143
|
}
|
|
155
144
|
var DefaultTranslation = class {
|
|
156
|
-
#resources = new Map();
|
|
145
|
+
#resources = /* @__PURE__ */ new Map();
|
|
157
146
|
#options;
|
|
158
147
|
constructor(options) {
|
|
159
148
|
this.#options = options;
|
|
@@ -205,7 +194,7 @@ async function createCommandContext({ args, values, positionals, rest, argv: arg
|
|
|
205
194
|
locale: localeStr,
|
|
206
195
|
fallbackLocale: DEFAULT_LOCALE
|
|
207
196
|
});
|
|
208
|
-
const localeResources = new Map();
|
|
197
|
+
const localeResources = /* @__PURE__ */ new Map();
|
|
209
198
|
let builtInLoadedResources;
|
|
210
199
|
/**
|
|
211
200
|
* load the built-in locale resources
|
|
@@ -309,7 +298,24 @@ function define(definition) {
|
|
|
309
298
|
}
|
|
310
299
|
|
|
311
300
|
//#endregion
|
|
312
|
-
//#region node_modules/
|
|
301
|
+
//#region node_modules/args-tokens/lib/utils-N7UlhLbz.js
|
|
302
|
+
/**
|
|
303
|
+
* Entry point of utils.
|
|
304
|
+
*
|
|
305
|
+
* Note that this entry point is used by gunshi to import utility functions.
|
|
306
|
+
*
|
|
307
|
+
* @module
|
|
308
|
+
*/
|
|
309
|
+
/**
|
|
310
|
+
* @author kazuya kawaguchi (a.k.a. kazupon)
|
|
311
|
+
* @license MIT
|
|
312
|
+
*/
|
|
313
|
+
function kebabnize(str) {
|
|
314
|
+
return str.replace(/[A-Z]/g, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase());
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region node_modules/gunshi/lib/renderer-BzRfaLdJ.js
|
|
313
319
|
/**
|
|
314
320
|
* Render the header.
|
|
315
321
|
* @param ctx A {@link CommandContext | command context}
|
|
@@ -494,7 +500,7 @@ function generateOptionsSymbols(ctx) {
|
|
|
494
500
|
return hasOptionalArgs(ctx) ? hasAllDefaultOptions(ctx) ? `[${ctx.translate(resolveBuiltInKey("OPTIONS"))}]` : `<${ctx.translate(resolveBuiltInKey("OPTIONS"))}>` : "";
|
|
495
501
|
}
|
|
496
502
|
function makeShortLongOptionPair(schema, name$1, toKebab) {
|
|
497
|
-
const displayName = toKebab || schema.toKebab ? kebabnize
|
|
503
|
+
const displayName = toKebab || schema.toKebab ? kebabnize(name$1) : name$1;
|
|
498
504
|
let key = `--${displayName}`;
|
|
499
505
|
if (schema.short) key = `-${schema.short}, ${key}`;
|
|
500
506
|
return key;
|
|
@@ -509,12 +515,12 @@ function getOptionalArgsPairs(ctx) {
|
|
|
509
515
|
if (schema.type === "positional") return acc;
|
|
510
516
|
let key = makeShortLongOptionPair(schema, name$1, ctx.toKebab);
|
|
511
517
|
if (schema.type !== "boolean") {
|
|
512
|
-
const displayName = ctx.toKebab || schema.toKebab ? kebabnize
|
|
518
|
+
const displayName = ctx.toKebab || schema.toKebab ? kebabnize(name$1) : name$1;
|
|
513
519
|
key = schema.default ? `${key} [${displayName}]` : `${key} <${displayName}>`;
|
|
514
520
|
}
|
|
515
521
|
acc[name$1] = key;
|
|
516
522
|
if (schema.type === "boolean" && schema.negatable && !COMMON_ARGS_KEYS.includes(name$1)) {
|
|
517
|
-
const displayName = ctx.toKebab || schema.toKebab ? kebabnize
|
|
523
|
+
const displayName = ctx.toKebab || schema.toKebab ? kebabnize(name$1) : name$1;
|
|
518
524
|
acc[`no-${name$1}`] = `--no-${displayName}`;
|
|
519
525
|
}
|
|
520
526
|
return acc;
|
|
@@ -782,11 +788,8 @@ function hasOptionValue(value) {
|
|
|
782
788
|
}
|
|
783
789
|
|
|
784
790
|
//#endregion
|
|
785
|
-
//#region node_modules/args-tokens/lib/resolver-
|
|
791
|
+
//#region node_modules/args-tokens/lib/resolver-Q4k2fgTW.js
|
|
786
792
|
const SKIP_POSITIONAL_DEFAULT = -1;
|
|
787
|
-
function kebabnize(str) {
|
|
788
|
-
return str.replace(/[A-Z]/g, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase());
|
|
789
|
-
}
|
|
790
793
|
/**
|
|
791
794
|
* Resolve command line arguments.
|
|
792
795
|
* @param args - An arguments that contains {@link ArgSchema | arguments schema}.
|
|
@@ -998,7 +1001,7 @@ function createTypeError(option, schema) {
|
|
|
998
1001
|
}
|
|
999
1002
|
|
|
1000
1003
|
//#endregion
|
|
1001
|
-
//#region node_modules/gunshi/lib/cli-
|
|
1004
|
+
//#region node_modules/gunshi/lib/cli-DVGNVw3h.js
|
|
1002
1005
|
/**
|
|
1003
1006
|
* Run the command.
|
|
1004
1007
|
* @param args Command line arguments
|
|
@@ -1225,7 +1228,7 @@ var require_string_width = __commonJS({ "node_modules/string-width/index.js"(exp
|
|
|
1225
1228
|
|
|
1226
1229
|
//#endregion
|
|
1227
1230
|
//#region node_modules/cli-table3/src/utils.js
|
|
1228
|
-
var require_utils
|
|
1231
|
+
var require_utils = __commonJS({ "node_modules/cli-table3/src/utils.js"(exports, module) {
|
|
1229
1232
|
const stringWidth = require_string_width();
|
|
1230
1233
|
function codeRegex(capture) {
|
|
1231
1234
|
return capture ? /\u001b\[((?:\d*;){0,5}\d*)m/g : /\u001b\[(?:\d*;){0,5}\d*m/g;
|
|
@@ -2189,7 +2192,7 @@ var require_safe = __commonJS({ "node_modules/@colors/colors/safe.js"(exports, m
|
|
|
2189
2192
|
//#region node_modules/cli-table3/src/cell.js
|
|
2190
2193
|
var require_cell = __commonJS({ "node_modules/cli-table3/src/cell.js"(exports, module) {
|
|
2191
2194
|
const { info, debug: debug$2 } = require_debug$1();
|
|
2192
|
-
const utils$1 = require_utils
|
|
2195
|
+
const utils$1 = require_utils();
|
|
2193
2196
|
var Cell$1 = class Cell$1 {
|
|
2194
2197
|
/**
|
|
2195
2198
|
* A representation of a cell within the table.
|
|
@@ -2727,9 +2730,9 @@ var require_layout_manager = __commonJS({ "node_modules/cli-table3/src/layout-ma
|
|
|
2727
2730
|
//#region node_modules/cli-table3/src/table.js
|
|
2728
2731
|
var require_table = __commonJS({ "node_modules/cli-table3/src/table.js"(exports, module) {
|
|
2729
2732
|
const debug = require_debug$1();
|
|
2730
|
-
const utils = require_utils
|
|
2733
|
+
const utils = require_utils();
|
|
2731
2734
|
const tableLayout = require_layout_manager();
|
|
2732
|
-
var Table$
|
|
2735
|
+
var Table$3 = class extends Array {
|
|
2733
2736
|
constructor(opts) {
|
|
2734
2737
|
super();
|
|
2735
2738
|
const options = utils.mergeOptions(opts);
|
|
@@ -2792,7 +2795,7 @@ var require_table = __commonJS({ "node_modules/cli-table3/src/table.js"(exports,
|
|
|
2792
2795
|
return str[0].length;
|
|
2793
2796
|
}
|
|
2794
2797
|
};
|
|
2795
|
-
Table$
|
|
2798
|
+
Table$3.reset = () => debug.reset();
|
|
2796
2799
|
function doDraw(row, lineNum, result) {
|
|
2797
2800
|
let line = [];
|
|
2798
2801
|
row.forEach(function(cell) {
|
|
@@ -2801,7 +2804,7 @@ var require_table = __commonJS({ "node_modules/cli-table3/src/table.js"(exports,
|
|
|
2801
2804
|
let str = line.join("");
|
|
2802
2805
|
if (str.length) result.push(str);
|
|
2803
2806
|
}
|
|
2804
|
-
module.exports = Table$
|
|
2807
|
+
module.exports = Table$3;
|
|
2805
2808
|
} });
|
|
2806
2809
|
|
|
2807
2810
|
//#endregion
|
|
@@ -2879,27 +2882,99 @@ var require_picocolors = __commonJS({ "node_modules/picocolors/picocolors.js"(ex
|
|
|
2879
2882
|
module.exports.createColors = createColors;
|
|
2880
2883
|
} });
|
|
2881
2884
|
|
|
2885
|
+
//#endregion
|
|
2886
|
+
//#region src/shared-args.internal.ts
|
|
2887
|
+
function parseDateArg(value) {
|
|
2888
|
+
const result = safeParse(dateSchema, value);
|
|
2889
|
+
if (!result.success) throw new TypeError(result.issues[0].message);
|
|
2890
|
+
return result.output;
|
|
2891
|
+
}
|
|
2892
|
+
const sharedArgs = {
|
|
2893
|
+
since: {
|
|
2894
|
+
type: "custom",
|
|
2895
|
+
short: "s",
|
|
2896
|
+
description: "Filter from date (YYYYMMDD format)",
|
|
2897
|
+
parse: parseDateArg
|
|
2898
|
+
},
|
|
2899
|
+
until: {
|
|
2900
|
+
type: "custom",
|
|
2901
|
+
short: "u",
|
|
2902
|
+
description: "Filter until date (YYYYMMDD format)",
|
|
2903
|
+
parse: parseDateArg
|
|
2904
|
+
},
|
|
2905
|
+
path: {
|
|
2906
|
+
type: "string",
|
|
2907
|
+
short: "p",
|
|
2908
|
+
description: "Custom path to Claude data directory",
|
|
2909
|
+
default: getDefaultClaudePath()
|
|
2910
|
+
},
|
|
2911
|
+
json: {
|
|
2912
|
+
type: "boolean",
|
|
2913
|
+
short: "j",
|
|
2914
|
+
description: "Output in JSON format",
|
|
2915
|
+
default: false
|
|
2916
|
+
},
|
|
2917
|
+
mode: {
|
|
2918
|
+
type: "enum",
|
|
2919
|
+
short: "m",
|
|
2920
|
+
description: "Cost calculation mode: auto (use costUSD if exists, otherwise calculate), calculate (always calculate), display (always use costUSD)",
|
|
2921
|
+
default: "auto",
|
|
2922
|
+
choices: CostModes
|
|
2923
|
+
},
|
|
2924
|
+
debug: {
|
|
2925
|
+
type: "boolean",
|
|
2926
|
+
short: "d",
|
|
2927
|
+
description: "Show pricing mismatch information for debugging",
|
|
2928
|
+
default: false
|
|
2929
|
+
},
|
|
2930
|
+
debugSamples: {
|
|
2931
|
+
type: "number",
|
|
2932
|
+
description: "Number of sample discrepancies to show in debug output (default: 5)",
|
|
2933
|
+
default: 5
|
|
2934
|
+
},
|
|
2935
|
+
order: {
|
|
2936
|
+
type: "enum",
|
|
2937
|
+
short: "o",
|
|
2938
|
+
description: "Sort order: desc (newest first) or asc (oldest first)",
|
|
2939
|
+
default: "asc",
|
|
2940
|
+
choices: SortOrders
|
|
2941
|
+
}
|
|
2942
|
+
};
|
|
2943
|
+
const sharedCommandConfig = {
|
|
2944
|
+
args: sharedArgs,
|
|
2945
|
+
toKebab: true
|
|
2946
|
+
};
|
|
2947
|
+
|
|
2948
|
+
//#endregion
|
|
2949
|
+
//#region src/utils.internal.ts
|
|
2950
|
+
function formatNumber(num) {
|
|
2951
|
+
return num.toLocaleString("en-US");
|
|
2952
|
+
}
|
|
2953
|
+
function formatCurrency(amount) {
|
|
2954
|
+
return `$${amount.toFixed(2)}`;
|
|
2955
|
+
}
|
|
2956
|
+
|
|
2882
2957
|
//#endregion
|
|
2883
2958
|
//#region src/commands/daily.ts
|
|
2884
|
-
var import_cli_table3$
|
|
2885
|
-
var import_picocolors$
|
|
2959
|
+
var import_cli_table3$2 = __toESM(require_cli_table3(), 1);
|
|
2960
|
+
var import_picocolors$2 = __toESM(require_picocolors(), 1);
|
|
2886
2961
|
const dailyCommand = define({
|
|
2887
2962
|
name: "daily",
|
|
2888
2963
|
description: "Show usage report grouped by date",
|
|
2889
2964
|
...sharedCommandConfig,
|
|
2890
2965
|
async run(ctx) {
|
|
2891
2966
|
if (ctx.values.json) logger.level = 0;
|
|
2892
|
-
const
|
|
2967
|
+
const dailyData = await loadDailyUsageData({
|
|
2893
2968
|
since: ctx.values.since,
|
|
2894
2969
|
until: ctx.values.until,
|
|
2895
2970
|
claudePath: ctx.values.path,
|
|
2896
|
-
mode: ctx.values.mode
|
|
2897
|
-
|
|
2898
|
-
|
|
2971
|
+
mode: ctx.values.mode,
|
|
2972
|
+
order: ctx.values.order
|
|
2973
|
+
});
|
|
2899
2974
|
if (dailyData.length === 0) {
|
|
2900
2975
|
if (ctx.values.json) log(JSON.stringify([]));
|
|
2901
2976
|
else logger.warn("No Claude usage data found.");
|
|
2902
|
-
|
|
2977
|
+
g$1.exit(0);
|
|
2903
2978
|
}
|
|
2904
2979
|
const totals = calculateTotals(dailyData);
|
|
2905
2980
|
if (ctx.values.debug && !ctx.values.json) {
|
|
@@ -2922,7 +2997,7 @@ const dailyCommand = define({
|
|
|
2922
2997
|
log(JSON.stringify(jsonOutput, null, 2));
|
|
2923
2998
|
} else {
|
|
2924
2999
|
logger.box("Claude Code Token Usage Report - Daily");
|
|
2925
|
-
const table = new import_cli_table3$
|
|
3000
|
+
const table = new import_cli_table3$2.default({
|
|
2926
3001
|
head: [
|
|
2927
3002
|
"Date",
|
|
2928
3003
|
"Input",
|
|
@@ -2962,13 +3037,13 @@ const dailyCommand = define({
|
|
|
2962
3037
|
"─".repeat(10)
|
|
2963
3038
|
]);
|
|
2964
3039
|
table.push([
|
|
2965
|
-
import_picocolors$
|
|
2966
|
-
import_picocolors$
|
|
2967
|
-
import_picocolors$
|
|
2968
|
-
import_picocolors$
|
|
2969
|
-
import_picocolors$
|
|
2970
|
-
import_picocolors$
|
|
2971
|
-
import_picocolors$
|
|
3040
|
+
import_picocolors$2.default.yellow("Total"),
|
|
3041
|
+
import_picocolors$2.default.yellow(formatNumber(totals.inputTokens)),
|
|
3042
|
+
import_picocolors$2.default.yellow(formatNumber(totals.outputTokens)),
|
|
3043
|
+
import_picocolors$2.default.yellow(formatNumber(totals.cacheCreationTokens)),
|
|
3044
|
+
import_picocolors$2.default.yellow(formatNumber(totals.cacheReadTokens)),
|
|
3045
|
+
import_picocolors$2.default.yellow(formatNumber(getTotalTokens(totals))),
|
|
3046
|
+
import_picocolors$2.default.yellow(formatCurrency(totals.totalCost))
|
|
2972
3047
|
]);
|
|
2973
3048
|
log(table.toString());
|
|
2974
3049
|
}
|
|
@@ -3003,13 +3078,121 @@ const mcpCommand = define({
|
|
|
3003
3078
|
claudePath: path,
|
|
3004
3079
|
mode
|
|
3005
3080
|
});
|
|
3006
|
-
server.start(ctx.values.type === "http" ? {
|
|
3081
|
+
await server.start(ctx.values.type === "http" ? {
|
|
3007
3082
|
transportType: "httpStream",
|
|
3008
3083
|
httpStream: { port }
|
|
3009
3084
|
} : { transportType: "stdio" });
|
|
3010
3085
|
}
|
|
3011
3086
|
});
|
|
3012
3087
|
|
|
3088
|
+
//#endregion
|
|
3089
|
+
//#region src/commands/monthly.ts
|
|
3090
|
+
var import_cli_table3$1 = __toESM(require_cli_table3(), 1);
|
|
3091
|
+
var import_picocolors$1 = __toESM(require_picocolors(), 1);
|
|
3092
|
+
const monthlyCommand = define({
|
|
3093
|
+
name: "monthly",
|
|
3094
|
+
description: "Show usage report grouped by month",
|
|
3095
|
+
...sharedCommandConfig,
|
|
3096
|
+
async run(ctx) {
|
|
3097
|
+
if (ctx.values.json) logger.level = 0;
|
|
3098
|
+
const monthlyData = await loadMonthlyUsageData({
|
|
3099
|
+
since: ctx.values.since,
|
|
3100
|
+
until: ctx.values.until,
|
|
3101
|
+
claudePath: ctx.values.path,
|
|
3102
|
+
mode: ctx.values.mode,
|
|
3103
|
+
order: ctx.values.order
|
|
3104
|
+
});
|
|
3105
|
+
if (monthlyData.length === 0) {
|
|
3106
|
+
if (ctx.values.json) {
|
|
3107
|
+
const emptyOutput = {
|
|
3108
|
+
monthly: [],
|
|
3109
|
+
totals: {
|
|
3110
|
+
inputTokens: 0,
|
|
3111
|
+
outputTokens: 0,
|
|
3112
|
+
cacheCreationTokens: 0,
|
|
3113
|
+
cacheReadTokens: 0,
|
|
3114
|
+
totalTokens: 0,
|
|
3115
|
+
totalCost: 0
|
|
3116
|
+
}
|
|
3117
|
+
};
|
|
3118
|
+
log(JSON.stringify(emptyOutput, null, 2));
|
|
3119
|
+
} else logger.warn("No Claude usage data found.");
|
|
3120
|
+
g$1.exit(0);
|
|
3121
|
+
}
|
|
3122
|
+
const totals = calculateTotals(monthlyData);
|
|
3123
|
+
if (ctx.values.debug && !ctx.values.json) {
|
|
3124
|
+
const mismatchStats = await detectMismatches(ctx.values.path);
|
|
3125
|
+
printMismatchReport(mismatchStats, ctx.values.debugSamples);
|
|
3126
|
+
}
|
|
3127
|
+
if (ctx.values.json) {
|
|
3128
|
+
const jsonOutput = {
|
|
3129
|
+
monthly: monthlyData.map((data) => ({
|
|
3130
|
+
month: data.month,
|
|
3131
|
+
inputTokens: data.inputTokens,
|
|
3132
|
+
outputTokens: data.outputTokens,
|
|
3133
|
+
cacheCreationTokens: data.cacheCreationTokens,
|
|
3134
|
+
cacheReadTokens: data.cacheReadTokens,
|
|
3135
|
+
totalTokens: getTotalTokens(data),
|
|
3136
|
+
totalCost: data.totalCost
|
|
3137
|
+
})),
|
|
3138
|
+
totals: createTotalsObject(totals)
|
|
3139
|
+
};
|
|
3140
|
+
log(JSON.stringify(jsonOutput, null, 2));
|
|
3141
|
+
} else {
|
|
3142
|
+
logger.box("Claude Code Token Usage Report - Monthly");
|
|
3143
|
+
const table = new import_cli_table3$1.default({
|
|
3144
|
+
head: [
|
|
3145
|
+
"Month",
|
|
3146
|
+
"Input",
|
|
3147
|
+
"Output",
|
|
3148
|
+
"Cache Create",
|
|
3149
|
+
"Cache Read",
|
|
3150
|
+
"Total Tokens",
|
|
3151
|
+
"Cost (USD)"
|
|
3152
|
+
],
|
|
3153
|
+
style: { head: ["cyan"] },
|
|
3154
|
+
colAligns: [
|
|
3155
|
+
"left",
|
|
3156
|
+
"right",
|
|
3157
|
+
"right",
|
|
3158
|
+
"right",
|
|
3159
|
+
"right",
|
|
3160
|
+
"right",
|
|
3161
|
+
"right"
|
|
3162
|
+
]
|
|
3163
|
+
});
|
|
3164
|
+
for (const data of monthlyData) table.push([
|
|
3165
|
+
data.month,
|
|
3166
|
+
formatNumber(data.inputTokens),
|
|
3167
|
+
formatNumber(data.outputTokens),
|
|
3168
|
+
formatNumber(data.cacheCreationTokens),
|
|
3169
|
+
formatNumber(data.cacheReadTokens),
|
|
3170
|
+
formatNumber(getTotalTokens(data)),
|
|
3171
|
+
formatCurrency(data.totalCost)
|
|
3172
|
+
]);
|
|
3173
|
+
table.push([
|
|
3174
|
+
"─".repeat(12),
|
|
3175
|
+
"─".repeat(12),
|
|
3176
|
+
"─".repeat(12),
|
|
3177
|
+
"─".repeat(12),
|
|
3178
|
+
"─".repeat(12),
|
|
3179
|
+
"─".repeat(12),
|
|
3180
|
+
"─".repeat(10)
|
|
3181
|
+
]);
|
|
3182
|
+
table.push([
|
|
3183
|
+
import_picocolors$1.default.yellow("Total"),
|
|
3184
|
+
import_picocolors$1.default.yellow(formatNumber(totals.inputTokens)),
|
|
3185
|
+
import_picocolors$1.default.yellow(formatNumber(totals.outputTokens)),
|
|
3186
|
+
import_picocolors$1.default.yellow(formatNumber(totals.cacheCreationTokens)),
|
|
3187
|
+
import_picocolors$1.default.yellow(formatNumber(totals.cacheReadTokens)),
|
|
3188
|
+
import_picocolors$1.default.yellow(formatNumber(getTotalTokens(totals))),
|
|
3189
|
+
import_picocolors$1.default.yellow(formatCurrency(totals.totalCost))
|
|
3190
|
+
]);
|
|
3191
|
+
log(table.toString());
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
});
|
|
3195
|
+
|
|
3013
3196
|
//#endregion
|
|
3014
3197
|
//#region src/commands/session.ts
|
|
3015
3198
|
var import_cli_table3 = __toESM(require_cli_table3(), 1);
|
|
@@ -3020,17 +3203,17 @@ const sessionCommand = define({
|
|
|
3020
3203
|
...sharedCommandConfig,
|
|
3021
3204
|
async run(ctx) {
|
|
3022
3205
|
if (ctx.values.json) logger.level = 0;
|
|
3023
|
-
const
|
|
3206
|
+
const sessionData = await loadSessionData({
|
|
3024
3207
|
since: ctx.values.since,
|
|
3025
3208
|
until: ctx.values.until,
|
|
3026
3209
|
claudePath: ctx.values.path,
|
|
3027
|
-
mode: ctx.values.mode
|
|
3028
|
-
|
|
3029
|
-
|
|
3210
|
+
mode: ctx.values.mode,
|
|
3211
|
+
order: ctx.values.order
|
|
3212
|
+
});
|
|
3030
3213
|
if (sessionData.length === 0) {
|
|
3031
3214
|
if (ctx.values.json) log(JSON.stringify([]));
|
|
3032
3215
|
else logger.warn("No Claude usage data found.");
|
|
3033
|
-
|
|
3216
|
+
g$1.exit(0);
|
|
3034
3217
|
}
|
|
3035
3218
|
const totals = calculateTotals(sessionData);
|
|
3036
3219
|
if (ctx.values.debug && !ctx.values.json) {
|
|
@@ -3128,12 +3311,13 @@ const sessionCommand = define({
|
|
|
3128
3311
|
|
|
3129
3312
|
//#endregion
|
|
3130
3313
|
//#region src/commands/index.ts
|
|
3131
|
-
const subCommands = new Map();
|
|
3314
|
+
const subCommands = /* @__PURE__ */ new Map();
|
|
3132
3315
|
subCommands.set("daily", dailyCommand);
|
|
3316
|
+
subCommands.set("monthly", monthlyCommand);
|
|
3133
3317
|
subCommands.set("session", sessionCommand);
|
|
3134
3318
|
subCommands.set("mcp", mcpCommand);
|
|
3135
3319
|
const mainCommand = dailyCommand;
|
|
3136
|
-
await cli(
|
|
3320
|
+
await cli(g$1.argv.slice(2), mainCommand, {
|
|
3137
3321
|
name,
|
|
3138
3322
|
version,
|
|
3139
3323
|
description,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sep } from "node:path";
|
|
2
2
|
import { formatWithOptions } from "node:util";
|
|
3
|
-
import
|
|
3
|
+
import g$1 from "node:process";
|
|
4
4
|
import * as tty from "node:tty";
|
|
5
5
|
|
|
6
6
|
//#region node_modules/consola/dist/core.mjs
|
|
@@ -384,7 +384,7 @@ Consola.prototype.withScope = Consola.prototype.withTag;
|
|
|
384
384
|
Consola.prototype.mock = Consola.prototype.mockTypes;
|
|
385
385
|
Consola.prototype.pause = Consola.prototype.pauseLogs;
|
|
386
386
|
Consola.prototype.resume = Consola.prototype.resumeLogs;
|
|
387
|
-
function createConsola
|
|
387
|
+
function createConsola(options = {}) {
|
|
388
388
|
return new Consola(options);
|
|
389
389
|
}
|
|
390
390
|
|
|
@@ -525,7 +525,7 @@ function getColor$1(color, fallback = "reset") {
|
|
|
525
525
|
return colors[color] || colors[fallback];
|
|
526
526
|
}
|
|
527
527
|
const ansiRegex$1 = [String.raw`[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?\u0007)`, String.raw`(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))`].join("|");
|
|
528
|
-
function stripAnsi
|
|
528
|
+
function stripAnsi(text) {
|
|
529
529
|
return text.replace(new RegExp(ansiRegex$1, "g"), "");
|
|
530
530
|
}
|
|
531
531
|
const boxStylePresets = {
|
|
@@ -618,14 +618,14 @@ function box(text, _opts = {}) {
|
|
|
618
618
|
if (_color) for (const key in borderStyle) borderStyle[key] = _color(borderStyle[key]);
|
|
619
619
|
const paddingOffset = opts.style.padding % 2 === 0 ? opts.style.padding : opts.style.padding + 1;
|
|
620
620
|
const height = textLines.length + paddingOffset;
|
|
621
|
-
const width = Math.max(...textLines.map((line) => stripAnsi
|
|
621
|
+
const width = Math.max(...textLines.map((line) => stripAnsi(line).length), opts.title ? stripAnsi(opts.title).length : 0) + paddingOffset;
|
|
622
622
|
const widthOffset = width + paddingOffset;
|
|
623
623
|
const leftSpace = opts.style.marginLeft > 0 ? " ".repeat(opts.style.marginLeft) : "";
|
|
624
624
|
if (opts.style.marginTop > 0) boxLines.push("".repeat(opts.style.marginTop));
|
|
625
625
|
if (opts.title) {
|
|
626
626
|
const title = _color ? _color(opts.title) : opts.title;
|
|
627
|
-
const left = borderStyle.h.repeat(Math.floor((width - stripAnsi
|
|
628
|
-
const right = borderStyle.h.repeat(width - stripAnsi
|
|
627
|
+
const left = borderStyle.h.repeat(Math.floor((width - stripAnsi(opts.title).length) / 2));
|
|
628
|
+
const right = borderStyle.h.repeat(width - stripAnsi(opts.title).length - stripAnsi(left).length + paddingOffset);
|
|
629
629
|
boxLines.push(`${leftSpace}${borderStyle.tl}${left}${title}${right}${borderStyle.tr}`);
|
|
630
630
|
} else boxLines.push(`${leftSpace}${borderStyle.tl}${borderStyle.h.repeat(widthOffset)}${borderStyle.tr}`);
|
|
631
631
|
const valignOffset = opts.style.valign === "center" ? Math.floor((height - textLines.length) / 2) : opts.style.valign === "top" ? height - textLines.length - paddingOffset : height - textLines.length;
|
|
@@ -633,7 +633,7 @@ function box(text, _opts = {}) {
|
|
|
633
633
|
else {
|
|
634
634
|
const line = textLines[i$1 - valignOffset];
|
|
635
635
|
const left = " ".repeat(paddingOffset);
|
|
636
|
-
const right = " ".repeat(width - stripAnsi
|
|
636
|
+
const right = " ".repeat(width - stripAnsi(line).length);
|
|
637
637
|
boxLines.push(`${leftSpace}${borderStyle.v}${left}${line}${right}${borderStyle.v}`);
|
|
638
638
|
}
|
|
639
639
|
boxLines.push(`${leftSpace}${borderStyle.bl}${borderStyle.h.repeat(widthOffset)}${borderStyle.br}`);
|
|
@@ -809,7 +809,7 @@ function ansiRegex({ onlyFirst = false } = {}) {
|
|
|
809
809
|
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
810
810
|
}
|
|
811
811
|
const regex = ansiRegex();
|
|
812
|
-
function stripAnsi(string) {
|
|
812
|
+
function stripAnsi$1(string) {
|
|
813
813
|
if (typeof string !== "string") throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
814
814
|
return string.replace(regex, "");
|
|
815
815
|
}
|
|
@@ -838,7 +838,7 @@ const defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
|
|
|
838
838
|
function stringWidth$1(string, options = {}) {
|
|
839
839
|
if (typeof string !== "string" || string.length === 0) return 0;
|
|
840
840
|
const { ambiguousIsNarrow = true, countAnsiEscapeCodes = false } = options;
|
|
841
|
-
if (!countAnsiEscapeCodes) string = stripAnsi(string);
|
|
841
|
+
if (!countAnsiEscapeCodes) string = stripAnsi$1(string);
|
|
842
842
|
if (string.length === 0) return 0;
|
|
843
843
|
let width = 0;
|
|
844
844
|
const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
|
|
@@ -859,9 +859,9 @@ function stringWidth$1(string, options = {}) {
|
|
|
859
859
|
return width;
|
|
860
860
|
}
|
|
861
861
|
function isUnicodeSupported() {
|
|
862
|
-
const { env: env$1 } =
|
|
862
|
+
const { env: env$1 } = g$1;
|
|
863
863
|
const { TERM, TERM_PROGRAM } = env$1;
|
|
864
|
-
if (
|
|
864
|
+
if (g$1.platform !== "win32") return TERM !== "linux";
|
|
865
865
|
return Boolean(env$1.WT_SESSION) || Boolean(env$1.TERMINUS_SUBLIME) || env$1.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env$1.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
866
866
|
}
|
|
867
867
|
const TYPE_COLOR_MAP = {
|
|
@@ -892,7 +892,7 @@ const TYPE_ICONS = {
|
|
|
892
892
|
};
|
|
893
893
|
function stringWidth(str) {
|
|
894
894
|
const hasICU = typeof Intl === "object";
|
|
895
|
-
if (!hasICU || !Intl.Segmenter) return stripAnsi
|
|
895
|
+
if (!hasICU || !Intl.Segmenter) return stripAnsi(str).length;
|
|
896
896
|
return stringWidth$1(str);
|
|
897
897
|
}
|
|
898
898
|
var FancyReporter = class extends BasicReporter {
|
|
@@ -941,15 +941,15 @@ function getColor(color = "white") {
|
|
|
941
941
|
function getBgColor(color = "bgWhite") {
|
|
942
942
|
return colors[`bg${color[0].toUpperCase()}${color.slice(1)}`] || colors.bgWhite;
|
|
943
943
|
}
|
|
944
|
-
function createConsola(options = {}) {
|
|
944
|
+
function createConsola$1(options = {}) {
|
|
945
945
|
let level = _getDefaultLogLevel();
|
|
946
946
|
if (process.env.CONSOLA_LEVEL) level = Number.parseInt(process.env.CONSOLA_LEVEL) ?? level;
|
|
947
|
-
const consola2 = createConsola
|
|
947
|
+
const consola2 = createConsola({
|
|
948
948
|
level,
|
|
949
949
|
defaults: { level },
|
|
950
950
|
stdout: process.stdout,
|
|
951
951
|
stderr: process.stderr,
|
|
952
|
-
prompt: (...args) => import("./prompt-
|
|
952
|
+
prompt: (...args) => import("./prompt-DljZqwMa.js").then((m) => m.prompt(...args)),
|
|
953
953
|
reporters: options.reporters || [options.fancy ?? !(T || R) ? new FancyReporter() : new BasicReporter()],
|
|
954
954
|
...options
|
|
955
955
|
});
|
|
@@ -960,12 +960,12 @@ function _getDefaultLogLevel() {
|
|
|
960
960
|
if (R) return LogLevels.warn;
|
|
961
961
|
return LogLevels.info;
|
|
962
962
|
}
|
|
963
|
-
const consola = createConsola();
|
|
963
|
+
const consola = createConsola$1();
|
|
964
964
|
|
|
965
965
|
//#endregion
|
|
966
966
|
//#region package.json
|
|
967
967
|
var name = "ccusage";
|
|
968
|
-
var version = "0.
|
|
968
|
+
var version = "0.6.1";
|
|
969
969
|
var description = "Usage analysis tool for Claude Code";
|
|
970
970
|
|
|
971
971
|
//#endregion
|
package/dist/logger.js
CHANGED