ccusage 15.2.0 → 15.3.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.
@@ -1,5 +1,5 @@
1
- import { modelPricingSchema } from "./_types-CmSE0O0q.js";
2
- import { logger } from "./logger-CeR-gFvq.js";
1
+ import { modelPricingSchema } from "./_types-BHFM59hI.js";
2
+ import { logger } from "./logger-DeTONwj8.js";
3
3
  import { createRequire } from "node:module";
4
4
  import path from "node:path";
5
5
  import F, { homedir } from "node:os";
@@ -25,6 +25,107 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  enumerable: true
26
26
  }) : target, mod));
27
27
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
28
+ const isFailure = (result) => "Failure" === result.type;
29
+ const isPromise = (value) => "object" == typeof value && null !== value && "then" in value && "function" == typeof value.then && "catch" in value && "function" == typeof value.catch;
30
+ const andThen = (fn) => (result) => {
31
+ const apply = (r) => {
32
+ if (isFailure(r)) return r;
33
+ return fn(r.value);
34
+ };
35
+ return isPromise(result) ? result.then(apply) : apply(result);
36
+ };
37
+ const andThrough = (fn) => (result) => {
38
+ const apply = (r) => {
39
+ if (isFailure(r)) return r;
40
+ const next = fn(r.value);
41
+ if (isPromise(next)) return next.then((n) => {
42
+ if (isFailure(n)) return n;
43
+ return r;
44
+ });
45
+ if (isFailure(next)) return next;
46
+ return r;
47
+ };
48
+ return isPromise(result) ? result.then(apply) : apply(result);
49
+ };
50
+ const succeed = (...args) => {
51
+ const value = args[0];
52
+ if (void 0 === value) return { type: "Success" };
53
+ if (isPromise(value)) return value.then((value$1) => ({
54
+ type: "Success",
55
+ value: value$1
56
+ }));
57
+ return {
58
+ type: "Success",
59
+ value
60
+ };
61
+ };
62
+ const fail = (...args) => {
63
+ const error = args[0];
64
+ if (void 0 === error) return { type: "Failure" };
65
+ if (isPromise(error)) return error.then((error$1) => ({
66
+ type: "Failure",
67
+ error: error$1
68
+ }));
69
+ return {
70
+ type: "Failure",
71
+ error
72
+ };
73
+ };
74
+ const isSuccess = (result) => "Success" === result.type;
75
+ const inspect = (fn) => (result) => {
76
+ const apply = (r) => {
77
+ if (isSuccess(r)) fn(r.value);
78
+ return r;
79
+ };
80
+ return isPromise(result) ? result.then(apply) : apply(result);
81
+ };
82
+ const inspectError = (fn) => (result) => {
83
+ const apply = (r) => {
84
+ if (isFailure(r)) fn(r.error);
85
+ return r;
86
+ };
87
+ return isPromise(result) ? result.then(apply) : apply(result);
88
+ };
89
+ const map = (fn) => (result) => {
90
+ const apply = (r) => {
91
+ if (isFailure(r)) return r;
92
+ return succeed(fn(r.value));
93
+ };
94
+ if (isPromise(result)) return result.then(apply);
95
+ return apply(result);
96
+ };
97
+ const orElse = (fn) => (result) => {
98
+ const apply = (r) => {
99
+ if (isSuccess(r)) return r;
100
+ return fn(r.error);
101
+ };
102
+ return isPromise(result) ? result.then(apply) : apply(result);
103
+ };
104
+ const pipe = (value, ...functions) => {
105
+ let next = value;
106
+ for (const func of functions) next = func(next);
107
+ return next;
108
+ };
109
+ const try_ = (options) => {
110
+ if (isPromise(options.try)) {
111
+ if ("safe" in options && options.safe) return succeed(options.try);
112
+ return options.try.then((value) => succeed(value), (error) => fail(options.catch(error)));
113
+ }
114
+ return (...args) => {
115
+ try {
116
+ const output = options.try(...args);
117
+ if (isPromise(output)) {
118
+ const promise = succeed(output);
119
+ if ("safe" in options && options.safe) return promise;
120
+ return promise.catch((error) => fail(options.catch(error)));
121
+ }
122
+ return succeed(output);
123
+ } catch (error) {
124
+ if ("safe" in options && options.safe) throw error;
125
+ return fail(options.catch(error));
126
+ }
127
+ };
128
+ };
28
129
  const homeDirectory = F.homedir();
29
130
  const { env } = process;
30
131
  const xdgData = env.XDG_DATA_HOME || (homeDirectory ? path.join(homeDirectory, ".local", "share") : void 0);
@@ -213,116 +314,119 @@ var PricingFetcher = class {
213
314
  * Loads offline pricing data from pre-fetched cache
214
315
  * @returns Map of model names to pricing information
215
316
  */
216
- async loadOfflinePricing() {
217
- const pricing = new Map(Object.entries({
218
- "claude-instant-1": {
219
- "input_cost_per_token": 163e-8,
220
- "output_cost_per_token": 551e-8
221
- },
222
- "claude-instant-1.2": {
223
- "input_cost_per_token": 163e-9,
224
- "output_cost_per_token": 551e-9
225
- },
226
- "claude-2": {
227
- "input_cost_per_token": 8e-6,
228
- "output_cost_per_token": 24e-6
229
- },
230
- "claude-2.1": {
231
- "input_cost_per_token": 8e-6,
232
- "output_cost_per_token": 24e-6
233
- },
234
- "claude-3-haiku-20240307": {
235
- "input_cost_per_token": 25e-8,
236
- "output_cost_per_token": 125e-8,
237
- "cache_creation_input_token_cost": 3e-7,
238
- "cache_read_input_token_cost": 3e-8
239
- },
240
- "claude-3-5-haiku-20241022": {
241
- "input_cost_per_token": 8e-7,
242
- "output_cost_per_token": 4e-6,
243
- "cache_creation_input_token_cost": 1e-6,
244
- "cache_read_input_token_cost": 8e-8
245
- },
246
- "claude-3-5-haiku-latest": {
247
- "input_cost_per_token": 1e-6,
248
- "output_cost_per_token": 5e-6,
249
- "cache_creation_input_token_cost": 125e-8,
250
- "cache_read_input_token_cost": 1e-7
251
- },
252
- "claude-3-opus-latest": {
253
- "input_cost_per_token": 15e-6,
254
- "output_cost_per_token": 75e-6,
255
- "cache_creation_input_token_cost": 1875e-8,
256
- "cache_read_input_token_cost": 15e-7
257
- },
258
- "claude-3-opus-20240229": {
259
- "input_cost_per_token": 15e-6,
260
- "output_cost_per_token": 75e-6,
261
- "cache_creation_input_token_cost": 1875e-8,
262
- "cache_read_input_token_cost": 15e-7
263
- },
264
- "claude-3-sonnet-20240229": {
265
- "input_cost_per_token": 3e-6,
266
- "output_cost_per_token": 15e-6
267
- },
268
- "claude-3-5-sonnet-latest": {
269
- "input_cost_per_token": 3e-6,
270
- "output_cost_per_token": 15e-6,
271
- "cache_creation_input_token_cost": 375e-8,
272
- "cache_read_input_token_cost": 3e-7
273
- },
274
- "claude-3-5-sonnet-20240620": {
275
- "input_cost_per_token": 3e-6,
276
- "output_cost_per_token": 15e-6,
277
- "cache_creation_input_token_cost": 375e-8,
278
- "cache_read_input_token_cost": 3e-7
279
- },
280
- "claude-opus-4-20250514": {
281
- "input_cost_per_token": 15e-6,
282
- "output_cost_per_token": 75e-6,
283
- "cache_creation_input_token_cost": 1875e-8,
284
- "cache_read_input_token_cost": 15e-7
285
- },
286
- "claude-sonnet-4-20250514": {
287
- "input_cost_per_token": 3e-6,
288
- "output_cost_per_token": 15e-6,
289
- "cache_creation_input_token_cost": 375e-8,
290
- "cache_read_input_token_cost": 3e-7
291
- },
292
- "claude-4-opus-20250514": {
293
- "input_cost_per_token": 15e-6,
294
- "output_cost_per_token": 75e-6,
295
- "cache_creation_input_token_cost": 1875e-8,
296
- "cache_read_input_token_cost": 15e-7
297
- },
298
- "claude-4-sonnet-20250514": {
299
- "input_cost_per_token": 3e-6,
300
- "output_cost_per_token": 15e-6,
301
- "cache_creation_input_token_cost": 375e-8,
302
- "cache_read_input_token_cost": 3e-7
303
- },
304
- "claude-3-7-sonnet-latest": {
305
- "input_cost_per_token": 3e-6,
306
- "output_cost_per_token": 15e-6,
307
- "cache_creation_input_token_cost": 375e-8,
308
- "cache_read_input_token_cost": 3e-7
309
- },
310
- "claude-3-7-sonnet-20250219": {
311
- "input_cost_per_token": 3e-6,
312
- "output_cost_per_token": 15e-6,
313
- "cache_creation_input_token_cost": 375e-8,
314
- "cache_read_input_token_cost": 3e-7
315
- },
316
- "claude-3-5-sonnet-20241022": {
317
- "input_cost_per_token": 3e-6,
318
- "output_cost_per_token": 15e-6,
319
- "cache_creation_input_token_cost": 375e-8,
320
- "cache_read_input_token_cost": 3e-7
321
- }
322
- }));
323
- this.cachedPricing = pricing;
324
- return pricing;
325
- }
317
+ loadOfflinePricing = try_({
318
+ try: async () => {
319
+ const pricing = new Map(Object.entries({
320
+ "claude-instant-1": {
321
+ "input_cost_per_token": 163e-8,
322
+ "output_cost_per_token": 551e-8
323
+ },
324
+ "claude-instant-1.2": {
325
+ "input_cost_per_token": 163e-9,
326
+ "output_cost_per_token": 551e-9
327
+ },
328
+ "claude-2": {
329
+ "input_cost_per_token": 8e-6,
330
+ "output_cost_per_token": 24e-6
331
+ },
332
+ "claude-2.1": {
333
+ "input_cost_per_token": 8e-6,
334
+ "output_cost_per_token": 24e-6
335
+ },
336
+ "claude-3-haiku-20240307": {
337
+ "input_cost_per_token": 25e-8,
338
+ "output_cost_per_token": 125e-8,
339
+ "cache_creation_input_token_cost": 3e-7,
340
+ "cache_read_input_token_cost": 3e-8
341
+ },
342
+ "claude-3-5-haiku-20241022": {
343
+ "input_cost_per_token": 8e-7,
344
+ "output_cost_per_token": 4e-6,
345
+ "cache_creation_input_token_cost": 1e-6,
346
+ "cache_read_input_token_cost": 8e-8
347
+ },
348
+ "claude-3-5-haiku-latest": {
349
+ "input_cost_per_token": 1e-6,
350
+ "output_cost_per_token": 5e-6,
351
+ "cache_creation_input_token_cost": 125e-8,
352
+ "cache_read_input_token_cost": 1e-7
353
+ },
354
+ "claude-3-opus-latest": {
355
+ "input_cost_per_token": 15e-6,
356
+ "output_cost_per_token": 75e-6,
357
+ "cache_creation_input_token_cost": 1875e-8,
358
+ "cache_read_input_token_cost": 15e-7
359
+ },
360
+ "claude-3-opus-20240229": {
361
+ "input_cost_per_token": 15e-6,
362
+ "output_cost_per_token": 75e-6,
363
+ "cache_creation_input_token_cost": 1875e-8,
364
+ "cache_read_input_token_cost": 15e-7
365
+ },
366
+ "claude-3-sonnet-20240229": {
367
+ "input_cost_per_token": 3e-6,
368
+ "output_cost_per_token": 15e-6
369
+ },
370
+ "claude-3-5-sonnet-latest": {
371
+ "input_cost_per_token": 3e-6,
372
+ "output_cost_per_token": 15e-6,
373
+ "cache_creation_input_token_cost": 375e-8,
374
+ "cache_read_input_token_cost": 3e-7
375
+ },
376
+ "claude-3-5-sonnet-20240620": {
377
+ "input_cost_per_token": 3e-6,
378
+ "output_cost_per_token": 15e-6,
379
+ "cache_creation_input_token_cost": 375e-8,
380
+ "cache_read_input_token_cost": 3e-7
381
+ },
382
+ "claude-opus-4-20250514": {
383
+ "input_cost_per_token": 15e-6,
384
+ "output_cost_per_token": 75e-6,
385
+ "cache_creation_input_token_cost": 1875e-8,
386
+ "cache_read_input_token_cost": 15e-7
387
+ },
388
+ "claude-sonnet-4-20250514": {
389
+ "input_cost_per_token": 3e-6,
390
+ "output_cost_per_token": 15e-6,
391
+ "cache_creation_input_token_cost": 375e-8,
392
+ "cache_read_input_token_cost": 3e-7
393
+ },
394
+ "claude-4-opus-20250514": {
395
+ "input_cost_per_token": 15e-6,
396
+ "output_cost_per_token": 75e-6,
397
+ "cache_creation_input_token_cost": 1875e-8,
398
+ "cache_read_input_token_cost": 15e-7
399
+ },
400
+ "claude-4-sonnet-20250514": {
401
+ "input_cost_per_token": 3e-6,
402
+ "output_cost_per_token": 15e-6,
403
+ "cache_creation_input_token_cost": 375e-8,
404
+ "cache_read_input_token_cost": 3e-7
405
+ },
406
+ "claude-3-7-sonnet-latest": {
407
+ "input_cost_per_token": 3e-6,
408
+ "output_cost_per_token": 15e-6,
409
+ "cache_creation_input_token_cost": 375e-8,
410
+ "cache_read_input_token_cost": 3e-7
411
+ },
412
+ "claude-3-7-sonnet-20250219": {
413
+ "input_cost_per_token": 3e-6,
414
+ "output_cost_per_token": 15e-6,
415
+ "cache_creation_input_token_cost": 375e-8,
416
+ "cache_read_input_token_cost": 3e-7
417
+ },
418
+ "claude-3-5-sonnet-20241022": {
419
+ "input_cost_per_token": 3e-6,
420
+ "output_cost_per_token": 15e-6,
421
+ "cache_creation_input_token_cost": 375e-8,
422
+ "cache_read_input_token_cost": 3e-7
423
+ }
424
+ }));
425
+ this.cachedPricing = pricing;
426
+ return pricing;
427
+ },
428
+ catch: (error) => new Error("Failed to load offline pricing data", { cause: error })
429
+ });
326
430
  /**
327
431
  * Handles fallback to offline pricing when network fetch fails
328
432
  * @param originalError - The original error from the network fetch
@@ -332,15 +436,12 @@ var PricingFetcher = class {
332
436
  async handleFallbackToCachedPricing(originalError) {
333
437
  logger.warn("Failed to fetch model pricing from LiteLLM, falling back to cached pricing data");
334
438
  logger.debug("Fetch error details:", originalError);
335
- try {
336
- const fallbackPricing = await this.loadOfflinePricing();
337
- logger.info(`Using cached pricing data for ${fallbackPricing.size} models`);
338
- return fallbackPricing;
339
- } catch (fallbackError) {
340
- logger.error("Failed to load cached pricing data as fallback:", fallbackError);
439
+ return pipe(this.loadOfflinePricing(), inspect((pricing) => {
440
+ logger.info(`Using cached pricing data for ${pricing.size} models`);
441
+ }), inspectError((error) => {
442
+ logger.error("Failed to load cached pricing data as fallback:", error);
341
443
  logger.error("Original fetch error:", originalError);
342
- throw new Error("Could not fetch model pricing data and fallback data is unavailable");
343
- }
444
+ }));
344
445
  }
345
446
  /**
346
447
  * Ensures pricing data is loaded, either from cache or by fetching
@@ -348,24 +449,30 @@ var PricingFetcher = class {
348
449
  * @returns Map of model names to pricing information
349
450
  */
350
451
  async ensurePricingLoaded() {
351
- if (this.cachedPricing != null) return this.cachedPricing;
352
- if (this.offline) return this.loadOfflinePricing();
353
- try {
452
+ return pipe(this.cachedPricing != null ? succeed(this.cachedPricing) : fail(/* @__PURE__ */ new Error("Cached pricing not available")), orElse(async () => {
453
+ if (this.offline) return this.loadOfflinePricing();
354
454
  logger.warn("Fetching latest model pricing from LiteLLM...");
355
- const response = await fetch(LITELLM_PRICING_URL);
356
- if (!response.ok) throw new Error(`Failed to fetch pricing data: ${response.statusText}`);
357
- const data = await response.json();
358
- const pricing = /* @__PURE__ */ new Map();
359
- for (const [modelName, modelData] of Object.entries(data)) if (typeof modelData === "object" && modelData !== null) {
360
- const parsed = modelPricingSchema.safeParse(modelData);
361
- if (parsed.success) pricing.set(modelName, parsed.data);
362
- }
363
- this.cachedPricing = pricing;
364
- logger.info(`Loaded pricing for ${pricing.size} models`);
365
- return pricing;
366
- } catch (error) {
367
- return this.handleFallbackToCachedPricing(error);
368
- }
455
+ return pipe(try_({
456
+ try: fetch(LITELLM_PRICING_URL),
457
+ catch: (error) => new Error("Failed to fetch model pricing from LiteLLM", { cause: error })
458
+ }), andThrough((response) => {
459
+ if (!response.ok) return fail(/* @__PURE__ */ new Error(`Failed to fetch pricing data: ${response.statusText}`));
460
+ return succeed();
461
+ }), andThen(async (response) => try_({
462
+ try: response.json(),
463
+ catch: (error) => new Error("Failed to parse pricing data", { cause: error })
464
+ })), map((data) => {
465
+ const pricing = /* @__PURE__ */ new Map();
466
+ for (const [modelName, modelData] of Object.entries(data)) if (typeof modelData === "object" && modelData !== null) {
467
+ const parsed = modelPricingSchema.safeParse(modelData);
468
+ if (parsed.success) pricing.set(modelName, parsed.data);
469
+ }
470
+ return pricing;
471
+ }), inspect((pricing) => {
472
+ this.cachedPricing = pricing;
473
+ logger.info(`Loaded pricing for ${pricing.size} models`);
474
+ }), orElse(async (error) => this.handleFallbackToCachedPricing(error)));
475
+ }));
369
476
  }
370
477
  /**
371
478
  * Fetches all available model pricing data
@@ -381,23 +488,24 @@ var PricingFetcher = class {
381
488
  * @returns Model pricing information or null if not found
382
489
  */
383
490
  async getModelPricing(modelName) {
384
- const pricing = await this.ensurePricingLoaded();
385
- const directMatch = pricing.get(modelName);
386
- if (directMatch != null) return directMatch;
387
- const variations = [
388
- modelName,
389
- `anthropic/${modelName}`,
390
- `claude-3-5-${modelName}`,
391
- `claude-3-${modelName}`,
392
- `claude-${modelName}`
393
- ];
394
- for (const variant of variations) {
395
- const match = pricing.get(variant);
396
- if (match != null) return match;
397
- }
398
- const lowerModel = modelName.toLowerCase();
399
- for (const [key, value] of pricing) if (key.toLowerCase().includes(lowerModel) || lowerModel.includes(key.toLowerCase())) return value;
400
- return null;
491
+ return pipe(this.ensurePricingLoaded(), map((pricing) => {
492
+ const directMatch = pricing.get(modelName);
493
+ if (directMatch != null) return directMatch;
494
+ const variations = [
495
+ modelName,
496
+ `anthropic/${modelName}`,
497
+ `claude-3-5-${modelName}`,
498
+ `claude-3-${modelName}`,
499
+ `claude-${modelName}`
500
+ ];
501
+ for (const variant of variations) {
502
+ const match = pricing.get(variant);
503
+ if (match != null) return match;
504
+ }
505
+ const lowerModel = modelName.toLowerCase();
506
+ for (const [key, value] of pricing) if (key.toLowerCase().includes(lowerModel) || lowerModel.includes(key.toLowerCase())) return value;
507
+ return null;
508
+ }));
401
509
  }
402
510
  /**
403
511
  * Calculates the cost for given token usage and model
@@ -410,9 +518,7 @@ var PricingFetcher = class {
410
518
  * @returns Total cost in USD
411
519
  */
412
520
  async calculateCostFromTokens(tokens, modelName) {
413
- const pricing = await this.getModelPricing(modelName);
414
- if (pricing == null) return 0;
415
- return this.calculateCostFromPricing(tokens, pricing);
521
+ return pipe(this.getModelPricing(modelName), map((pricing) => pricing == null ? 0 : this.calculateCostFromPricing(tokens, pricing)));
416
522
  }
417
523
  /**
418
524
  * Calculates cost from token usage and pricing information
@@ -433,4 +539,4 @@ var PricingFetcher = class {
433
539
  return cost;
434
540
  }
435
541
  };
436
- export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, __commonJSMin, __require, __toESM, require_usingCtx };
542
+ export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx, try_ };
@@ -1,2 +1,2 @@
1
- import { PricingFetcher } from "./pricing-fetcher-CrV0acwD.js";
1
+ import { PricingFetcher } from "./pricing-fetcher-B3SvKOod.js";
2
2
  export { PricingFetcher };
@@ -1,4 +1,4 @@
1
- import { PricingFetcher } from "./pricing-fetcher-fT0o6CKK.js";
2
- import "./_types-CmSE0O0q.js";
3
- import "./logger-CeR-gFvq.js";
1
+ import { PricingFetcher } from "./pricing-fetcher-DaK2jizg.js";
2
+ import "./_types-BHFM59hI.js";
3
+ import "./logger-DeTONwj8.js";
4
4
  export { PricingFetcher };
@@ -381,7 +381,7 @@ const iD = sD(), v = new Set(["\x1B", "›"]), CD = 39, w$1 = "\x07", W$1 = "[",
381
381
  `)];
382
382
  for (const [E, a] of o$1.entries()) {
383
383
  if (e$1 += a, v.has(a)) {
384
- const { groups: B$1 } = new RegExp(`(?:\\${W$1}(?<code>\\d+)m|\\${y}(?<uri>.*)${w$1})`).exec(o$1.slice(E).join("")) || { groups: {} };
384
+ const { groups: B$1 } = (/* @__PURE__ */ new RegExp(`(?:\\${W$1}(?<code>\\d+)m|\\${y}(?<uri>.*)${w$1})`)).exec(o$1.slice(E).join("")) || { groups: {} };
385
385
  if (B$1.code !== void 0) {
386
386
  const p = Number.parseFloat(B$1.code);
387
387
  s = p === CD ? void 0 : p;
@@ -804,7 +804,7 @@ async function prompt(message, opts = {}) {
804
804
  if (typeof value !== "symbol" || value.toString() !== "Symbol(clack:cancel)") return value;
805
805
  switch (opts.cancel) {
806
806
  case "reject": {
807
- const error = new Error("Prompt cancelled.");
807
+ const error = /* @__PURE__ */ new Error("Prompt cancelled.");
808
808
  error.name = "ConsolaPromptCancelledError";
809
809
  if (Error.captureStackTrace) Error.captureStackTrace(error, prompt);
810
810
  throw error;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ccusage",
3
3
  "type": "module",
4
- "version": "15.2.0",
4
+ "version": "15.3.0",
5
5
  "description": "Usage analysis tool for Claude Code",
6
6
  "author": "ryoppippi",
7
7
  "license": "MIT",
@@ -30,5 +30,8 @@
30
30
  "bin": "./dist/index.js",
31
31
  "files": [
32
32
  "dist"
33
- ]
33
+ ],
34
+ "engines": {
35
+ "node": ">=20.19.3"
36
+ }
34
37
  }