ccusage 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,180 @@
1
+ import { ArraySchema, InferOutput, NumberSchema, ObjectSchema, OptionalSchema, PricingFetcher, RegexAction, SchemaWithPipe, StringSchema } from "./pricing-fetcher-Dq-OLBp4.js";
2
+
3
+ //#region node_modules/type-fest/source/observable-like.d.ts
4
+ declare global {
5
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
6
+ interface SymbolConstructor {
7
+ readonly observable: symbol;
8
+ }
9
+ }
10
+
11
+ /**
12
+ @remarks
13
+ The TC39 observable proposal defines a `closed` property, but some implementations (such as xstream) do not as of 10/08/2021.
14
+ As well, some guidance on making an `Observable` to not include `closed` property.
15
+ @see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130
16
+ @see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85
17
+ @see https://github.com/benlesh/symbol-observable#making-an-object-observable
18
+
19
+ @category Observable
20
+ */
21
+
22
+ //#endregion
23
+ //#region node_modules/type-fest/source/tuple-to-union.d.ts
24
+ /**
25
+ Convert a tuple/array into a union type of its elements.
26
+
27
+ This can be useful when you have a fixed set of allowed values and want a type defining only the allowed values, but do not want to repeat yourself.
28
+
29
+ @example
30
+ ```
31
+ import type {TupleToUnion} from 'type-fest';
32
+
33
+ const destinations = ['a', 'b', 'c'] as const;
34
+
35
+ type Destination = TupleToUnion<typeof destinations>;
36
+ //=> 'a' | 'b' | 'c'
37
+
38
+ function verifyDestination(destination: unknown): destination is Destination {
39
+ return destinations.includes(destination as any);
40
+ }
41
+
42
+ type RequestBody = {
43
+ deliverTo: Destination;
44
+ };
45
+
46
+ function verifyRequestBody(body: unknown): body is RequestBody {
47
+ const deliverTo = (body as any).deliverTo;
48
+ return typeof body === 'object' && body !== null && verifyDestination(deliverTo);
49
+ }
50
+ ```
51
+
52
+ Alternatively, you may use `typeof destinations[number]`. If `destinations` is a tuple, there is no difference. However if `destinations` is a string, the resulting type will the union of the characters in the string. Other types of `destinations` may result in a compile error. In comparison, TupleToUnion will return `never` if a tuple is not provided.
53
+
54
+ @example
55
+ ```
56
+ const destinations = ['a', 'b', 'c'] as const;
57
+
58
+ type Destination = typeof destinations[number];
59
+ //=> 'a' | 'b' | 'c'
60
+
61
+ const erroringType = new Set(['a', 'b', 'c']);
62
+
63
+ type ErroringType = typeof erroringType[number];
64
+ //=> Type 'Set<string>' has no matching index signature for type 'number'. ts(2537)
65
+
66
+ const numberBool: { [n: number]: boolean } = { 1: true };
67
+
68
+ type NumberBool = typeof numberBool[number];
69
+ //=> boolean
70
+ ```
71
+
72
+ @category Array
73
+ */
74
+ type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never;
75
+ //#endregion
76
+ //#region src/types.internal.d.ts
77
+ declare const CostModes: readonly ["auto", "calculate", "display"];
78
+ type CostMode = TupleToUnion<typeof CostModes>;
79
+ declare const SortOrders: readonly ["desc", "asc"];
80
+ type SortOrder = TupleToUnion<typeof SortOrders>;
81
+ //#endregion
82
+ //#region src/data-loader.d.ts
83
+ declare function getDefaultClaudePath(): string;
84
+ declare const UsageDataSchema: ObjectSchema<{
85
+ readonly timestamp: StringSchema<undefined>;
86
+ readonly version: OptionalSchema<StringSchema<undefined>, undefined>;
87
+ readonly message: ObjectSchema<{
88
+ readonly usage: ObjectSchema<{
89
+ readonly input_tokens: NumberSchema<undefined>;
90
+ readonly output_tokens: NumberSchema<undefined>;
91
+ readonly cache_creation_input_tokens: OptionalSchema<NumberSchema<undefined>, undefined>;
92
+ readonly cache_read_input_tokens: OptionalSchema<NumberSchema<undefined>, undefined>;
93
+ }, undefined>;
94
+ readonly model: OptionalSchema<StringSchema<undefined>, undefined>;
95
+ }, undefined>;
96
+ readonly costUSD: OptionalSchema<NumberSchema<undefined>, undefined>;
97
+ }, undefined>;
98
+ type UsageData = InferOutput<typeof UsageDataSchema>;
99
+ declare const ModelBreakdownSchema: ObjectSchema<{
100
+ readonly modelName: StringSchema<undefined>;
101
+ readonly inputTokens: NumberSchema<undefined>;
102
+ readonly outputTokens: NumberSchema<undefined>;
103
+ readonly cacheCreationTokens: NumberSchema<undefined>;
104
+ readonly cacheReadTokens: NumberSchema<undefined>;
105
+ readonly cost: NumberSchema<undefined>;
106
+ }, undefined>;
107
+ type ModelBreakdown = InferOutput<typeof ModelBreakdownSchema>;
108
+ declare const DailyUsageSchema: ObjectSchema<{
109
+ readonly date: SchemaWithPipe<readonly [StringSchema<undefined>, RegexAction<string, undefined>]>;
110
+ readonly inputTokens: NumberSchema<undefined>;
111
+ readonly outputTokens: NumberSchema<undefined>;
112
+ readonly cacheCreationTokens: NumberSchema<undefined>;
113
+ readonly cacheReadTokens: NumberSchema<undefined>;
114
+ readonly totalCost: NumberSchema<undefined>;
115
+ readonly modelsUsed: ArraySchema<StringSchema<undefined>, undefined>;
116
+ readonly modelBreakdowns: ArraySchema<ObjectSchema<{
117
+ readonly modelName: StringSchema<undefined>;
118
+ readonly inputTokens: NumberSchema<undefined>;
119
+ readonly outputTokens: NumberSchema<undefined>;
120
+ readonly cacheCreationTokens: NumberSchema<undefined>;
121
+ readonly cacheReadTokens: NumberSchema<undefined>;
122
+ readonly cost: NumberSchema<undefined>;
123
+ }, undefined>, undefined>;
124
+ }, undefined>;
125
+ type DailyUsage = InferOutput<typeof DailyUsageSchema>;
126
+ declare const SessionUsageSchema: ObjectSchema<{
127
+ readonly sessionId: StringSchema<undefined>;
128
+ readonly projectPath: StringSchema<undefined>;
129
+ readonly inputTokens: NumberSchema<undefined>;
130
+ readonly outputTokens: NumberSchema<undefined>;
131
+ readonly cacheCreationTokens: NumberSchema<undefined>;
132
+ readonly cacheReadTokens: NumberSchema<undefined>;
133
+ readonly totalCost: NumberSchema<undefined>;
134
+ readonly lastActivity: StringSchema<undefined>;
135
+ readonly versions: ArraySchema<StringSchema<undefined>, undefined>;
136
+ readonly modelsUsed: ArraySchema<StringSchema<undefined>, undefined>;
137
+ readonly modelBreakdowns: ArraySchema<ObjectSchema<{
138
+ readonly modelName: StringSchema<undefined>;
139
+ readonly inputTokens: NumberSchema<undefined>;
140
+ readonly outputTokens: NumberSchema<undefined>;
141
+ readonly cacheCreationTokens: NumberSchema<undefined>;
142
+ readonly cacheReadTokens: NumberSchema<undefined>;
143
+ readonly cost: NumberSchema<undefined>;
144
+ }, undefined>, undefined>;
145
+ }, undefined>;
146
+ type SessionUsage = InferOutput<typeof SessionUsageSchema>;
147
+ declare const MonthlyUsageSchema: ObjectSchema<{
148
+ readonly month: SchemaWithPipe<readonly [StringSchema<undefined>, RegexAction<string, undefined>]>;
149
+ readonly inputTokens: NumberSchema<undefined>;
150
+ readonly outputTokens: NumberSchema<undefined>;
151
+ readonly cacheCreationTokens: NumberSchema<undefined>;
152
+ readonly cacheReadTokens: NumberSchema<undefined>;
153
+ readonly totalCost: NumberSchema<undefined>;
154
+ readonly modelsUsed: ArraySchema<StringSchema<undefined>, undefined>;
155
+ readonly modelBreakdowns: ArraySchema<ObjectSchema<{
156
+ readonly modelName: StringSchema<undefined>;
157
+ readonly inputTokens: NumberSchema<undefined>;
158
+ readonly outputTokens: NumberSchema<undefined>;
159
+ readonly cacheCreationTokens: NumberSchema<undefined>;
160
+ readonly cacheReadTokens: NumberSchema<undefined>;
161
+ readonly cost: NumberSchema<undefined>;
162
+ }, undefined>, undefined>;
163
+ }, undefined>;
164
+ type MonthlyUsage = InferOutput<typeof MonthlyUsageSchema>;
165
+ declare function formatDate(dateStr: string): string;
166
+ declare function calculateCostForEntry(data: UsageData, mode: CostMode, fetcher: PricingFetcher): Promise<number>;
167
+ type DateFilter = {
168
+ since?: string;
169
+ until?: string;
170
+ };
171
+ type LoadOptions = {
172
+ claudePath?: string;
173
+ mode?: CostMode;
174
+ order?: SortOrder;
175
+ } & DateFilter;
176
+ declare function loadDailyUsageData(options?: LoadOptions): Promise<DailyUsage[]>;
177
+ declare function loadSessionData(options?: LoadOptions): Promise<SessionUsage[]>;
178
+ declare function loadMonthlyUsageData(options?: LoadOptions): Promise<MonthlyUsage[]>;
179
+ //#endregion
180
+ export { DailyUsage, DailyUsageSchema, DateFilter, LoadOptions, ModelBreakdown, ModelBreakdownSchema, MonthlyUsage, MonthlyUsageSchema, SessionUsage, SessionUsageSchema, UsageData, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData };
@@ -1,3 +1,3 @@
1
- import "./pricing-fetcher-CfEgfzSr.js";
2
- import { DailyUsage, DailyUsageSchema, DateFilter, LoadOptions, MonthlyUsage, MonthlyUsageSchema, SessionUsage, SessionUsageSchema, UsageData, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData } from "./data-loader-VdEcqJHc.js";
3
- export { DailyUsage, DailyUsageSchema, DateFilter, LoadOptions, MonthlyUsage, MonthlyUsageSchema, SessionUsage, SessionUsageSchema, UsageData, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData };
1
+ import { DailyUsage, DailyUsageSchema, DateFilter, LoadOptions, ModelBreakdown, ModelBreakdownSchema, MonthlyUsage, MonthlyUsageSchema, SessionUsage, SessionUsageSchema, UsageData, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData } from "./data-loader-pCzn-ryX.js";
2
+ import "./pricing-fetcher-Dq-OLBp4.js";
3
+ export { DailyUsage, DailyUsageSchema, DateFilter, LoadOptions, ModelBreakdown, ModelBreakdownSchema, MonthlyUsage, MonthlyUsageSchema, SessionUsage, SessionUsageSchema, UsageData, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData };
@@ -1,6 +1,6 @@
1
- import { DailyUsageSchema, MonthlyUsageSchema, SessionUsageSchema, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData } from "./data-loader-DP5qBPn6.js";
2
- import "./dist-C0-Tf5eD.js";
3
- import "./logger-DsQC4OvA.js";
4
- import "./pricing-fetcher-BPUgMrB_.js";
1
+ import { DailyUsageSchema, ModelBreakdownSchema, MonthlyUsageSchema, SessionUsageSchema, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData } from "./data-loader-nOFcMg_V.js";
2
+ import "./dist-BEQ1tJCL.js";
3
+ import "./logger-BPjA3VFO.js";
4
+ import "./pricing-fetcher-CAeJvZnF.js";
5
5
 
6
- export { DailyUsageSchema, MonthlyUsageSchema, SessionUsageSchema, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData };
6
+ export { DailyUsageSchema, ModelBreakdownSchema, MonthlyUsageSchema, SessionUsageSchema, UsageDataSchema, calculateCostForEntry, formatDate, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionData };
@@ -1,44 +1,45 @@
1
- import { UsageDataSchema, glob } from "./data-loader-DP5qBPn6.js";
2
- import { safeParse } from "./dist-C0-Tf5eD.js";
3
- import { logger } from "./logger-DsQC4OvA.js";
4
- import { calculateCostFromTokens, fetchModelPricing, getModelPricing } from "./pricing-fetcher-BPUgMrB_.js";
1
+ import { UsageDataSchema, __toESM, glob, require_usingCtx } from "./data-loader-nOFcMg_V.js";
2
+ import { safeParse } from "./dist-BEQ1tJCL.js";
3
+ import { logger } from "./logger-BPjA3VFO.js";
4
+ import { PricingFetcher } from "./pricing-fetcher-CAeJvZnF.js";
5
5
  import { readFile } from "node:fs/promises";
6
6
  import { homedir } from "node:os";
7
7
  import path from "node:path";
8
8
 
9
9
  //#region src/debug.ts
10
+ var import_usingCtx = __toESM(require_usingCtx(), 1);
10
11
  const MATCH_THRESHOLD_PERCENT = .1;
11
12
  async function detectMismatches(claudePath) {
12
- const claudeDir = claudePath ?? path.join(homedir(), ".claude", "projects");
13
- const files = await glob(["**/*.jsonl"], {
14
- cwd: claudeDir,
15
- absolute: true
16
- });
17
- const modelPricing = await fetchModelPricing();
18
- const stats = {
19
- totalEntries: 0,
20
- entriesWithBoth: 0,
21
- matches: 0,
22
- mismatches: 0,
23
- discrepancies: [],
24
- modelStats: /* @__PURE__ */ new Map(),
25
- versionStats: /* @__PURE__ */ new Map()
26
- };
27
- for (const file of files) {
28
- const content = await readFile(file, "utf-8");
29
- const lines = content.trim().split("\n").filter((line) => line.length > 0);
30
- for (const line of lines) try {
31
- const parsed = JSON.parse(line);
32
- const result = safeParse(UsageDataSchema, parsed);
33
- if (!result.success) continue;
34
- const data = result.output;
35
- stats.totalEntries++;
36
- if (data.costUSD !== void 0 && data.message.model != null && data.message.model !== "<synthetic>") {
37
- stats.entriesWithBoth++;
38
- const model = data.message.model;
39
- const pricing = getModelPricing(model, modelPricing);
40
- if (pricing != null) {
41
- const calculatedCost = calculateCostFromTokens(data.message.usage, pricing);
13
+ try {
14
+ var _usingCtx = (0, import_usingCtx.default)();
15
+ const claudeDir = claudePath ?? path.join(homedir(), ".claude", "projects");
16
+ const files = await glob(["**/*.jsonl"], {
17
+ cwd: claudeDir,
18
+ absolute: true
19
+ });
20
+ const fetcher = _usingCtx.u(new PricingFetcher());
21
+ const stats = {
22
+ totalEntries: 0,
23
+ entriesWithBoth: 0,
24
+ matches: 0,
25
+ mismatches: 0,
26
+ discrepancies: [],
27
+ modelStats: /* @__PURE__ */ new Map(),
28
+ versionStats: /* @__PURE__ */ new Map()
29
+ };
30
+ for (const file of files) {
31
+ const content = await readFile(file, "utf-8");
32
+ const lines = content.trim().split("\n").filter((line) => line.length > 0);
33
+ for (const line of lines) try {
34
+ const parsed = JSON.parse(line);
35
+ const result = safeParse(UsageDataSchema, parsed);
36
+ if (!result.success) continue;
37
+ const data = result.output;
38
+ stats.totalEntries++;
39
+ if (data.costUSD !== void 0 && data.message.model != null && data.message.model !== "<synthetic>") {
40
+ stats.entriesWithBoth++;
41
+ const model = data.message.model;
42
+ const calculatedCost = await fetcher.calculateCostFromTokens(data.message.usage, model);
42
43
  const difference = Math.abs(data.costUSD - calculatedCost);
43
44
  const percentDiff = data.costUSD > 0 ? difference / data.costUSD * 100 : 0;
44
45
  const modelStat = stats.modelStats.get(model) ?? {
@@ -81,10 +82,14 @@ async function detectMismatches(claudePath) {
81
82
  modelStat.avgPercentDiff = (modelStat.avgPercentDiff * (modelStat.total - 1) + percentDiff) / modelStat.total;
82
83
  stats.modelStats.set(model, modelStat);
83
84
  }
84
- }
85
- } catch {}
85
+ } catch {}
86
+ }
87
+ return stats;
88
+ } catch (_) {
89
+ _usingCtx.e = _;
90
+ } finally {
91
+ _usingCtx.d();
86
92
  }
87
- return stats;
88
93
  }
89
94
  function printMismatchReport(stats, sampleCount = 5) {
90
95
  if (stats.entriesWithBoth === 0) {
package/dist/debug.js CHANGED
@@ -1,7 +1,7 @@
1
- import "./data-loader-DP5qBPn6.js";
2
- import "./dist-C0-Tf5eD.js";
3
- import "./logger-DsQC4OvA.js";
4
- import "./pricing-fetcher-BPUgMrB_.js";
5
- import { detectMismatches, printMismatchReport } from "./debug-C_5Qx11m.js";
1
+ import "./data-loader-nOFcMg_V.js";
2
+ import "./dist-BEQ1tJCL.js";
3
+ import "./logger-BPjA3VFO.js";
4
+ import "./pricing-fetcher-CAeJvZnF.js";
5
+ import { detectMismatches, printMismatchReport } from "./debug-Bttss7TN.js";
6
6
 
7
7
  export { detectMismatches, printMismatchReport };
@@ -73,18 +73,6 @@ function _joinExpects(values2, separator) {
73
73
  if (list.length > 1) return `(${list.join(` ${separator} `)})`;
74
74
  return list[0] ?? "never";
75
75
  }
76
- var ValiError = class extends Error {
77
- /**
78
- * Creates a Valibot error with useful information.
79
- *
80
- * @param issues The error issues.
81
- */
82
- constructor(issues) {
83
- super(issues[0].message);
84
- this.name = "ValiError";
85
- this.issues = issues;
86
- }
87
- };
88
76
  /* @__NO_SIDE_EFFECTS__ */
89
77
  function description(description_) {
90
78
  return {
@@ -360,11 +348,6 @@ function union(options, message2) {
360
348
  }
361
349
  };
362
350
  }
363
- function parse(schema, input, config2) {
364
- const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config2));
365
- if (dataset.issues) throw new ValiError(dataset.issues);
366
- return dataset.value;
367
- }
368
351
  /* @__NO_SIDE_EFFECTS__ */
369
352
  function pipe(...pipe2) {
370
353
  return {
@@ -397,4 +380,4 @@ function safeParse(schema, input, config2) {
397
380
  }
398
381
 
399
382
  //#endregion
400
- export { array, description, getDefault, literal, number, object, optional, parse, pipe, regex, safeParse, string, union };
383
+ export { array, description, getDefault, literal, number, object, optional, pipe, regex, safeParse, string, union };
@@ -1,4 +1,4 @@
1
- import { getDefault } from "./dist-C0-Tf5eD.js";
1
+ import { getDefault } from "./dist-BEQ1tJCL.js";
2
2
 
3
3
  //#region node_modules/@valibot/to-json-schema/dist/index.js
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { tryImport } from "./index-CISmcbXk-DCA05NUL.js";
1
+ import { tryImport } from "./index-CISmcbXk-x9eVmhGM.js";
2
2
 
3
3
  //#region node_modules/xsschema/dist/effect-WSjEuzC9.js
4
4
  const getToJsonSchemaFn = async () => {
@@ -10,10 +10,10 @@ const tryImport = async (result, name) => {
10
10
  const getToJsonSchemaFn = async (vendor) => {
11
11
  switch (vendor) {
12
12
  case "arktype": return import("./arktype-C-GObzDh-Bx7Fdrqj.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
13
- case "effect": return import("./effect-WSjEuzC9-CJfWUy0j.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
14
- case "sury": return import("./sury-DmrZ3_Oj-CCL_DlTt.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
15
- case "valibot": return import("./valibot-CQk-M5rL-CkjrLVu1.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
16
- case "zod": return import("./zod-Db63SLXj-Dyc_OWjq.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
13
+ case "effect": return import("./effect-WSjEuzC9-ChJ5OQQf.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
14
+ case "sury": return import("./sury-DmrZ3_Oj-l0qqtY-f.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
15
+ case "valibot": return import("./valibot-CQk-M5rL-BNHzwpA0.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
16
+ case "zod": return import("./zod-Db63SLXj-N1oN-yiY.js").then(async ({ getToJsonSchemaFn: getToJsonSchemaFn2 }) => getToJsonSchemaFn2());
17
17
  default: throw new Error(`xsschema: Unsupported schema vendor "${vendor}". see https://xsai.js.org/docs/packages-top/xsschema#unsupported-schema-vendor`);
18
18
  }
19
19
  };