ccusage 15.5.1 → 15.6.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.
@@ -382,7 +382,7 @@ Consola.prototype.withScope = Consola.prototype.withTag;
382
382
  Consola.prototype.mock = Consola.prototype.mockTypes;
383
383
  Consola.prototype.pause = Consola.prototype.pauseLogs;
384
384
  Consola.prototype.resume = Consola.prototype.resumeLogs;
385
- function createConsola(options = {}) {
385
+ function createConsola$1(options = {}) {
386
386
  return new Consola(options);
387
387
  }
388
388
  function parseStack(stack, message) {
@@ -517,7 +517,7 @@ function getColor$1(color, fallback = "reset") {
517
517
  return colors[color] || colors[fallback];
518
518
  }
519
519
  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("|");
520
- function stripAnsi(text) {
520
+ function stripAnsi$1(text) {
521
521
  return text.replace(new RegExp(ansiRegex$1, "g"), "");
522
522
  }
523
523
  const boxStylePresets = {
@@ -610,14 +610,14 @@ function box(text, _opts = {}) {
610
610
  if (_color) for (const key in borderStyle) borderStyle[key] = _color(borderStyle[key]);
611
611
  const paddingOffset = opts.style.padding % 2 === 0 ? opts.style.padding : opts.style.padding + 1;
612
612
  const height = textLines.length + paddingOffset;
613
- const width = Math.max(...textLines.map((line) => stripAnsi(line).length), opts.title ? stripAnsi(opts.title).length : 0) + paddingOffset;
613
+ const width = Math.max(...textLines.map((line) => stripAnsi$1(line).length), opts.title ? stripAnsi$1(opts.title).length : 0) + paddingOffset;
614
614
  const widthOffset = width + paddingOffset;
615
615
  const leftSpace = opts.style.marginLeft > 0 ? " ".repeat(opts.style.marginLeft) : "";
616
616
  if (opts.style.marginTop > 0) boxLines.push("".repeat(opts.style.marginTop));
617
617
  if (opts.title) {
618
618
  const title = _color ? _color(opts.title) : opts.title;
619
- const left = borderStyle.h.repeat(Math.floor((width - stripAnsi(opts.title).length) / 2));
620
- const right = borderStyle.h.repeat(width - stripAnsi(opts.title).length - stripAnsi(left).length + paddingOffset);
619
+ const left = borderStyle.h.repeat(Math.floor((width - stripAnsi$1(opts.title).length) / 2));
620
+ const right = borderStyle.h.repeat(width - stripAnsi$1(opts.title).length - stripAnsi$1(left).length + paddingOffset);
621
621
  boxLines.push(`${leftSpace}${borderStyle.tl}${left}${title}${right}${borderStyle.tr}`);
622
622
  } else boxLines.push(`${leftSpace}${borderStyle.tl}${borderStyle.h.repeat(widthOffset)}${borderStyle.tr}`);
623
623
  const valignOffset = opts.style.valign === "center" ? Math.floor((height - textLines.length) / 2) : opts.style.valign === "top" ? height - textLines.length - paddingOffset : height - textLines.length;
@@ -625,7 +625,7 @@ function box(text, _opts = {}) {
625
625
  else {
626
626
  const line = textLines[i$1 - valignOffset];
627
627
  const left = " ".repeat(paddingOffset);
628
- const right = " ".repeat(width - stripAnsi(line).length);
628
+ const right = " ".repeat(width - stripAnsi$1(line).length);
629
629
  boxLines.push(`${leftSpace}${borderStyle.v}${left}${line}${right}${borderStyle.v}`);
630
630
  }
631
631
  boxLines.push(`${leftSpace}${borderStyle.bl}${borderStyle.h.repeat(widthOffset)}${borderStyle.br}`);
@@ -798,7 +798,7 @@ function ansiRegex({ onlyFirst = false } = {}) {
798
798
  return new RegExp(pattern, onlyFirst ? void 0 : "g");
799
799
  }
800
800
  const regex = ansiRegex();
801
- function stripAnsi$1(string) {
801
+ function stripAnsi(string) {
802
802
  if (typeof string !== "string") throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
803
803
  return string.replace(regex, "");
804
804
  }
@@ -827,7 +827,7 @@ const defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
827
827
  function stringWidth$1(string, options = {}) {
828
828
  if (typeof string !== "string" || string.length === 0) return 0;
829
829
  const { ambiguousIsNarrow = true, countAnsiEscapeCodes = false } = options;
830
- if (!countAnsiEscapeCodes) string = stripAnsi$1(string);
830
+ if (!countAnsiEscapeCodes) string = stripAnsi(string);
831
831
  if (string.length === 0) return 0;
832
832
  let width = 0;
833
833
  const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
@@ -881,7 +881,7 @@ const TYPE_ICONS = {
881
881
  };
882
882
  function stringWidth(str) {
883
883
  const hasICU = typeof Intl === "object";
884
- if (!hasICU || !Intl.Segmenter) return stripAnsi(str).length;
884
+ if (!hasICU || !Intl.Segmenter) return stripAnsi$1(str).length;
885
885
  return stringWidth$1(str);
886
886
  }
887
887
  var FancyReporter = class extends BasicReporter {
@@ -915,7 +915,7 @@ ${indent}`);
915
915
  line = space > 0 && (opts.columns || 0) >= 80 ? left + " ".repeat(space) + right : (right ? `${colors.gray(`[${right}]`)} ` : "") + left;
916
916
  line += characterFormat(additional.length > 0 ? "\n" + additional.join("\n") : "");
917
917
  if (logObj.type === "trace") {
918
- const _err = /* @__PURE__ */ new Error("Trace: " + logObj.message);
918
+ const _err = new Error("Trace: " + logObj.message);
919
919
  line += this.formatStack(_err.stack || "", _err.message);
920
920
  }
921
921
  return isBadge ? "\n" + line + "\n" : line;
@@ -930,15 +930,15 @@ function getColor(color = "white") {
930
930
  function getBgColor(color = "bgWhite") {
931
931
  return colors[`bg${color[0].toUpperCase()}${color.slice(1)}`] || colors.bgWhite;
932
932
  }
933
- function createConsola$1(options = {}) {
933
+ function createConsola(options = {}) {
934
934
  let level = _getDefaultLogLevel();
935
935
  if (process.env.CONSOLA_LEVEL) level = Number.parseInt(process.env.CONSOLA_LEVEL) ?? level;
936
- const consola2 = createConsola({
936
+ const consola2 = createConsola$1({
937
937
  level,
938
938
  defaults: { level },
939
939
  stdout: process.stdout,
940
940
  stderr: process.stderr,
941
- prompt: (...args) => import("./prompt-DsUFNEY7.js").then((m) => m.prompt(...args)),
941
+ prompt: (...args) => import("./prompt-lm8M58zJ.js").then((m) => m.prompt(...args)),
942
942
  reporters: options.reporters || [options.fancy ?? !(T || R) ? new FancyReporter() : new BasicReporter()],
943
943
  ...options
944
944
  });
@@ -949,9 +949,9 @@ function _getDefaultLogLevel() {
949
949
  if (R) return LogLevels.warn;
950
950
  return LogLevels.info;
951
951
  }
952
- const consola = createConsola$1();
952
+ const consola = createConsola();
953
953
  var name = "ccusage";
954
- var version = "15.5.1";
954
+ var version = "15.6.0";
955
955
  var description = "Usage analysis tool for Claude Code";
956
956
  /**
957
957
  * Application logger instance with package name tag
package/dist/logger.js CHANGED
@@ -1,2 +1,2 @@
1
- import { log, logger } from "./logger-COLgmk2z.js";
1
+ import { log, logger } from "./logger-C35JCduT.js";
2
2
  export { log, logger };
@@ -1,9 +1,9 @@
1
- import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-eNV76BjF.js";
1
+ import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-CNjC0nXU.js";
2
2
  import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
3
- import { ZodFirstPartyTypeKind, ZodOptional, ZodType, arrayType, booleanType, discriminatedUnionType, enumType, filterDateSchema, literalType, numberType, objectType, optionalType, recordType, stringType, unionType, unknownType } from "./_types-BHFM59hI.js";
3
+ import { ZodFirstPartyTypeKind, ZodOptional, ZodType, arrayType, booleanType, discriminatedUnionType, enumType, filterDateSchema, literalType, numberType, objectType, optionalType, recordType, stringType, unionType, unknownType } from "./_types-ed8-0BH6.js";
4
4
  import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
5
- import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-BAp4u-7e.js";
6
- import { name, version } from "./logger-COLgmk2z.js";
5
+ import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-CwryIrwx.js";
6
+ import { name, version } from "./logger-C35JCduT.js";
7
7
  import process from "node:process";
8
8
  const LATEST_PROTOCOL_VERSION = "2025-06-18";
9
9
  const SUPPORTED_PROTOCOL_VERSIONS = [
@@ -197,7 +197,20 @@ const ResourceContentsSchema = objectType({
197
197
  _meta: optionalType(objectType({}).passthrough())
198
198
  }).passthrough();
199
199
  const TextResourceContentsSchema = ResourceContentsSchema.extend({ text: stringType() });
200
- const BlobResourceContentsSchema = ResourceContentsSchema.extend({ blob: stringType().base64() });
200
+ /**
201
+ * A Zod schema for validating Base64 strings that is more performant and
202
+ * robust for very large inputs than the default regex-based check. It avoids
203
+ * stack overflows by using the native `atob` function for validation.
204
+ */
205
+ const Base64Schema = stringType().refine((val) => {
206
+ try {
207
+ atob(val);
208
+ return true;
209
+ } catch (_a) {
210
+ return false;
211
+ }
212
+ }, { message: "Invalid Base64 string" });
213
+ const BlobResourceContentsSchema = ResourceContentsSchema.extend({ blob: Base64Schema });
201
214
  /**
202
215
  * A known resource that the server is capable of reading.
203
216
  */
@@ -315,7 +328,7 @@ const TextContentSchema = objectType({
315
328
  */
316
329
  const ImageContentSchema = objectType({
317
330
  type: literalType("image"),
318
- data: stringType().base64(),
331
+ data: Base64Schema,
319
332
  mimeType: stringType(),
320
333
  _meta: optionalType(objectType({}).passthrough())
321
334
  }).passthrough();
@@ -324,7 +337,7 @@ const ImageContentSchema = objectType({
324
337
  */
325
338
  const AudioContentSchema = objectType({
326
339
  type: literalType("audio"),
327
- data: stringType().base64(),
340
+ data: Base64Schema,
328
341
  mimeType: stringType(),
329
342
  _meta: optionalType(objectType({}).passthrough())
330
343
  }).passthrough();
@@ -918,7 +931,7 @@ var tryDecode = (str, decoder) => {
918
931
  }
919
932
  };
920
933
  var tryDecodeURI = (str) => tryDecode(str, decodeURI);
921
- var getPath = (request) => {
934
+ var getPath$1 = (request) => {
922
935
  const url = request.url;
923
936
  const start = url.indexOf("/", url.charCodeAt(9) === 58 ? 13 : 8);
924
937
  let i = start;
@@ -933,7 +946,7 @@ var getPath = (request) => {
933
946
  return url.slice(start, i);
934
947
  };
935
948
  var getPathNoStrict = (request) => {
936
- const result = getPath(request);
949
+ const result = getPath$1(request);
937
950
  return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
938
951
  };
939
952
  var mergePath = (base, sub, ...rest) => {
@@ -1214,7 +1227,8 @@ var Context = class {
1214
1227
  return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
1215
1228
  };
1216
1229
  redirect = (location, status) => {
1217
- this.header("Location", String(location));
1230
+ const locationString = String(location);
1231
+ this.header("Location", !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString));
1218
1232
  return this.newResponse(null, status ?? 302);
1219
1233
  };
1220
1234
  notFound = () => {
@@ -1324,7 +1338,7 @@ var StreamableHTTPTransport = class {
1324
1338
  data: JSON.stringify(message)
1325
1339
  });
1326
1340
  } catch {
1327
- this.onerror?.(/* @__PURE__ */ new Error("Failed replay events"));
1341
+ this.onerror?.(new Error("Failed replay events"));
1328
1342
  throw new HTTPException(500, { message: "Failed replay events" });
1329
1343
  }
1330
1344
  } });
@@ -1347,7 +1361,9 @@ var StreamableHTTPTransport = class {
1347
1361
  if (!stream.closed) stream.writeSSE({
1348
1362
  data: "",
1349
1363
  event: "ping"
1350
- }).catch(() => clearInterval(keepAlive));
1364
+ }).catch(() => {
1365
+ clearInterval(keepAlive);
1366
+ });
1351
1367
  }, 3e4);
1352
1368
  stream.onAbort(() => {
1353
1369
  this.#streamMapping.delete(resolvedStreamId);
@@ -1599,13 +1615,13 @@ var Protocol = class {
1599
1615
  constructor(_options) {
1600
1616
  this._options = _options;
1601
1617
  this._requestMessageId = 0;
1602
- this._requestHandlers = /* @__PURE__ */ new Map();
1603
- this._requestHandlerAbortControllers = /* @__PURE__ */ new Map();
1604
- this._notificationHandlers = /* @__PURE__ */ new Map();
1605
- this._responseHandlers = /* @__PURE__ */ new Map();
1606
- this._progressHandlers = /* @__PURE__ */ new Map();
1607
- this._timeoutInfo = /* @__PURE__ */ new Map();
1608
- this._pendingDebouncedNotifications = /* @__PURE__ */ new Set();
1618
+ this._requestHandlers = new Map();
1619
+ this._requestHandlerAbortControllers = new Map();
1620
+ this._notificationHandlers = new Map();
1621
+ this._responseHandlers = new Map();
1622
+ this._progressHandlers = new Map();
1623
+ this._timeoutInfo = new Map();
1624
+ this._pendingDebouncedNotifications = new Set();
1609
1625
  this.setNotificationHandler(CancelledNotificationSchema, (notification) => {
1610
1626
  const controller = this._requestHandlerAbortControllers.get(notification.params.requestId);
1611
1627
  controller === null || controller === void 0 || controller.abort(notification.params.reason);
@@ -1671,14 +1687,14 @@ var Protocol = class {
1671
1687
  if (isJSONRPCResponse(message) || isJSONRPCError(message)) this._onresponse(message);
1672
1688
  else if (isJSONRPCRequest(message)) this._onrequest(message, extra);
1673
1689
  else if (isJSONRPCNotification(message)) this._onnotification(message);
1674
- else this._onerror(/* @__PURE__ */ new Error(`Unknown message type: ${JSON.stringify(message)}`));
1690
+ else this._onerror(new Error(`Unknown message type: ${JSON.stringify(message)}`));
1675
1691
  };
1676
1692
  await this._transport.start();
1677
1693
  }
1678
1694
  _onclose() {
1679
1695
  var _a;
1680
1696
  const responseHandlers = this._responseHandlers;
1681
- this._responseHandlers = /* @__PURE__ */ new Map();
1697
+ this._responseHandlers = new Map();
1682
1698
  this._progressHandlers.clear();
1683
1699
  this._pendingDebouncedNotifications.clear();
1684
1700
  this._transport = void 0;
@@ -1694,7 +1710,7 @@ var Protocol = class {
1694
1710
  var _a;
1695
1711
  const handler = (_a = this._notificationHandlers.get(notification.method)) !== null && _a !== void 0 ? _a : this.fallbackNotificationHandler;
1696
1712
  if (handler === void 0) return;
1697
- Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Uncaught error in notification handler: ${error}`)));
1713
+ Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(new Error(`Uncaught error in notification handler: ${error}`)));
1698
1714
  }
1699
1715
  _onrequest(request, extra) {
1700
1716
  var _a, _b, _c, _d;
@@ -1707,7 +1723,7 @@ var Protocol = class {
1707
1723
  code: ErrorCode.MethodNotFound,
1708
1724
  message: "Method not found"
1709
1725
  }
1710
- }).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Failed to send an error response: ${error}`)));
1726
+ }).catch((error) => this._onerror(new Error(`Failed to send an error response: ${error}`)));
1711
1727
  return;
1712
1728
  }
1713
1729
  const abortController = new AbortController();
@@ -1744,7 +1760,7 @@ var Protocol = class {
1744
1760
  message: (_b$1 = error.message) !== null && _b$1 !== void 0 ? _b$1 : "Internal error"
1745
1761
  }
1746
1762
  });
1747
- }).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Failed to send response: ${error}`))).finally(() => {
1763
+ }).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
1748
1764
  this._requestHandlerAbortControllers.delete(request.id);
1749
1765
  });
1750
1766
  }
@@ -1753,7 +1769,7 @@ var Protocol = class {
1753
1769
  const messageId = Number(progressToken);
1754
1770
  const handler = this._progressHandlers.get(messageId);
1755
1771
  if (!handler) {
1756
- this._onerror(/* @__PURE__ */ new Error(`Received a progress notification for an unknown token: ${JSON.stringify(notification)}`));
1772
+ this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(notification)}`));
1757
1773
  return;
1758
1774
  }
1759
1775
  const responseHandler = this._responseHandlers.get(messageId);
@@ -1770,7 +1786,7 @@ var Protocol = class {
1770
1786
  const messageId = Number(response.id);
1771
1787
  const handler = this._responseHandlers.get(messageId);
1772
1788
  if (handler === void 0) {
1773
- this._onerror(/* @__PURE__ */ new Error(`Received a response for an unknown message ID: ${JSON.stringify(response)}`));
1789
+ this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(response)}`));
1774
1790
  return;
1775
1791
  }
1776
1792
  this._responseHandlers.delete(messageId);
@@ -1802,7 +1818,7 @@ var Protocol = class {
1802
1818
  return new Promise((resolve$4, reject) => {
1803
1819
  var _a, _b, _c, _d, _e, _f;
1804
1820
  if (!this._transport) {
1805
- reject(/* @__PURE__ */ new Error("Not connected"));
1821
+ reject(new Error("Not connected"));
1806
1822
  return;
1807
1823
  }
1808
1824
  if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.enforceStrictCapabilities) === true) this.assertCapabilityForMethod(request.method);
@@ -1839,7 +1855,7 @@ var Protocol = class {
1839
1855
  relatedRequestId,
1840
1856
  resumptionToken,
1841
1857
  onresumptiontoken
1842
- }).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Failed to send cancellation: ${error}`)));
1858
+ }).catch((error) => this._onerror(new Error(`Failed to send cancellation: ${error}`)));
1843
1859
  reject(reason);
1844
1860
  };
1845
1861
  this._responseHandlers.set(messageId, (response) => {
@@ -2006,8 +2022,8 @@ var require_uri_all = __commonJSMin((exports, module) => {
2006
2022
  UNRESERVED: new RegExp(UNRESERVED$$$1, "g"),
2007
2023
  OTHER_CHARS: new RegExp(merge("[^\\%]", UNRESERVED$$$1, RESERVED$$), "g"),
2008
2024
  PCT_ENCODED: new RegExp(PCT_ENCODED$$1, "g"),
2009
- IPV4ADDRESS: /* @__PURE__ */ new RegExp("^(" + IPV4ADDRESS$ + ")$"),
2010
- IPV6ADDRESS: /* @__PURE__ */ new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$$1 + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$")
2025
+ IPV4ADDRESS: new RegExp("^(" + IPV4ADDRESS$ + ")$"),
2026
+ IPV6ADDRESS: new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$$1 + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$")
2011
2027
  };
2012
2028
  }
2013
2029
  var URI_PROTOCOL = buildExps(false);
@@ -2982,7 +2998,7 @@ var require_util = __commonJSMin((exports, module) => {
2982
2998
  schemaUnknownRules,
2983
2999
  toQuotedString,
2984
3000
  getPathExpr,
2985
- getPath: getPath$1,
3001
+ getPath,
2986
3002
  getData,
2987
3003
  unescapeFragment,
2988
3004
  unescapeJsonPointer,
@@ -3084,7 +3100,7 @@ var require_util = __commonJSMin((exports, module) => {
3084
3100
  var path = jsonPointers ? "'/' + " + expr + (isNumber ? "" : ".replace(/~/g, '~0').replace(/\\//g, '~1')") : isNumber ? "'[' + " + expr + " + ']'" : "'[\\'' + " + expr + " + '\\']'";
3085
3101
  return joinPaths(currentPath, path);
3086
3102
  }
3087
- function getPath$1(currentPath, prop, jsonPointers) {
3103
+ function getPath(currentPath, prop, jsonPointers) {
3088
3104
  var path = jsonPointers ? toQuotedString("/" + escapeJsonPointer(prop)) : toQuotedString(getProperty(prop));
3089
3105
  return joinPaths(currentPath, path);
3090
3106
  }
@@ -7693,7 +7709,7 @@ function parseStringDef(def, refs) {
7693
7709
  function escapeLiteralCheckValue(literal, refs) {
7694
7710
  return refs.patternStrategy === "escape" ? escapeNonAlphaNumeric(literal) : literal;
7695
7711
  }
7696
- const ALPHA_NUMERIC = /* @__PURE__ */ new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
7712
+ const ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
7697
7713
  function escapeNonAlphaNumeric(source) {
7698
7714
  let result = "";
7699
7715
  for (let i = 0; i < source.length; i++) {
@@ -8994,7 +9010,7 @@ var Hono$1 = class {
8994
9010
  };
8995
9011
  const { strict,...optionsWithoutStrict } = options;
8996
9012
  Object.assign(this, optionsWithoutStrict);
8997
- this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
9013
+ this.getPath = strict ?? true ? options.getPath ?? getPath$1 : getPathNoStrict;
8998
9014
  }
8999
9015
  #clone() {
9000
9016
  const clone = new Hono$1({
@@ -9150,7 +9166,7 @@ var PatternRouter = class {
9150
9166
  });
9151
9167
  try {
9152
9168
  this.#routes.push([
9153
- /* @__PURE__ */ new RegExp(`^${parts.join("")}${endsWithWildcard ? "" : "/?$"}`),
9169
+ new RegExp(`^${parts.join("")}${endsWithWildcard ? "" : "/?$"}`),
9154
9170
  method,
9155
9171
  handler
9156
9172
  ]);
package/dist/mcp.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { LoadOptions } from "./data-loader-CgvyDaQD.js";
2
- import "./pricing-fetcher-B3SvKOod.js";
1
+ import "./pricing-fetcher-AYfCy7g-.js";
2
+ import { LoadOptions } from "./data-loader-DZMUuqrf.js";
3
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  import { Hono } from "hono/tiny";
5
5
 
package/dist/mcp.js CHANGED
@@ -1,8 +1,8 @@
1
- import "./pricing-fetcher-eNV76BjF.js";
1
+ import "./pricing-fetcher-CNjC0nXU.js";
2
2
  import "./_token-utils-WjkbrjKv.js";
3
- import "./_types-BHFM59hI.js";
3
+ import "./_types-ed8-0BH6.js";
4
4
  import "./calculate-cost-BDqO4yWA.js";
5
- import "./data-loader-BAp4u-7e.js";
6
- import "./logger-COLgmk2z.js";
7
- import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-Ta2UK9sc.js";
5
+ import "./data-loader-CwryIrwx.js";
6
+ import "./logger-C35JCduT.js";
7
+ import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-CqzLeEbX.js";
8
8
  export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
@@ -75,7 +75,11 @@ type NumberBool = typeof numberBool[number];
75
75
  type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never;
76
76
  //#endregion
77
77
  //#region src/_types.d.ts
78
-
78
+ declare const monthlyDateSchema: z.ZodBranded<z.ZodString, "MonthlyDate">;
79
+ declare const weeklyDateSchema: z.ZodBranded<z.ZodString, "WeeklyDate">;
80
+ type MonthlyDate = z.infer<typeof monthlyDateSchema>;
81
+ type WeeklyDate = z.infer<typeof weeklyDateSchema>;
82
+ type Bucket = MonthlyDate | WeeklyDate;
79
83
  /**
80
84
  * Available cost calculation modes
81
85
  * - auto: Use pre-calculated costs when available, otherwise calculate from tokens
@@ -193,4 +197,4 @@ declare class PricingFetcher implements Disposable {
193
197
  }, pricing: ModelPricing): number;
194
198
  }
195
199
  //#endregion
196
- export { CostMode, PricingFetcher, SortOrder };
200
+ export { Bucket, CostMode, PricingFetcher as PricingFetcher$1, SortOrder, type TupleToUnion };
@@ -1,5 +1,5 @@
1
- import { modelPricingSchema } from "./_types-BHFM59hI.js";
2
- import { logger } from "./logger-COLgmk2z.js";
1
+ import { modelPricingSchema } from "./_types-ed8-0BH6.js";
2
+ import { logger } from "./logger-C35JCduT.js";
3
3
  import { createRequire } from "node:module";
4
4
  import path from "node:path";
5
5
  import F, { homedir } from "node:os";
@@ -255,6 +255,18 @@ const BURN_RATE_THRESHOLDS = {
255
255
  HIGH: 1e3,
256
256
  MODERATE: 500
257
257
  };
258
+ /**
259
+ * Days of the week for weekly aggregation
260
+ */
261
+ const WEEK_DAYS = [
262
+ "sunday",
263
+ "monday",
264
+ "tuesday",
265
+ "wednesday",
266
+ "thursday",
267
+ "friday",
268
+ "saturday"
269
+ ];
258
270
  var require_usingCtx = __commonJSMin((exports, module) => {
259
271
  function _usingCtx() {
260
272
  var r = "function" == typeof SuppressedError ? SuppressedError : function(r$1, e$1) {
@@ -346,14 +358,6 @@ var PricingFetcher = class {
346
358
  loadOfflinePricing = try_({
347
359
  try: async () => {
348
360
  const pricing = new Map(Object.entries({
349
- "claude-2": {
350
- "input_cost_per_token": 8e-6,
351
- "output_cost_per_token": 24e-6
352
- },
353
- "claude-2.1": {
354
- "input_cost_per_token": 8e-6,
355
- "output_cost_per_token": 24e-6
356
- },
357
361
  "claude-3-haiku-20240307": {
358
362
  "input_cost_per_token": 25e-8,
359
363
  "output_cost_per_token": 125e-8,
@@ -384,10 +388,6 @@ var PricingFetcher = class {
384
388
  "cache_creation_input_token_cost": 1875e-8,
385
389
  "cache_read_input_token_cost": 15e-7
386
390
  },
387
- "claude-3-sonnet-20240229": {
388
- "input_cost_per_token": 3e-6,
389
- "output_cost_per_token": 15e-6
390
- },
391
391
  "claude-3-5-sonnet-latest": {
392
392
  "input_cost_per_token": 3e-6,
393
393
  "output_cost_per_token": 15e-6,
@@ -470,20 +470,20 @@ var PricingFetcher = class {
470
470
  * @returns Map of model names to pricing information
471
471
  */
472
472
  async ensurePricingLoaded() {
473
- return pipe(this.cachedPricing != null ? succeed(this.cachedPricing) : fail(/* @__PURE__ */ new Error("Cached pricing not available")), orElse(async () => {
473
+ return pipe(this.cachedPricing != null ? succeed(this.cachedPricing) : fail(new Error("Cached pricing not available")), orElse(async () => {
474
474
  if (this.offline) return this.loadOfflinePricing();
475
475
  logger.warn("Fetching latest model pricing from LiteLLM...");
476
476
  return pipe(try_({
477
477
  try: fetch(LITELLM_PRICING_URL),
478
478
  catch: (error) => new Error("Failed to fetch model pricing from LiteLLM", { cause: error })
479
479
  }), andThrough((response) => {
480
- if (!response.ok) return fail(/* @__PURE__ */ new Error(`Failed to fetch pricing data: ${response.statusText}`));
480
+ if (!response.ok) return fail(new Error(`Failed to fetch pricing data: ${response.statusText}`));
481
481
  return succeed();
482
482
  }), andThen(async (response) => try_({
483
483
  try: response.json(),
484
484
  catch: (error) => new Error("Failed to parse pricing data", { cause: error })
485
485
  })), map((data) => {
486
- const pricing = /* @__PURE__ */ new Map();
486
+ const pricing = new Map();
487
487
  for (const [modelName, modelData] of Object.entries(data)) if (typeof modelData === "object" && modelData !== null) {
488
488
  const parsed = modelPricingSchema.safeParse(modelData);
489
489
  if (parsed.success) pricing.set(modelName, parsed.data);
@@ -560,4 +560,4 @@ var PricingFetcher = class {
560
560
  return cost;
561
561
  }
562
562
  };
563
- export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, 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, PROJECT_ALIASES_ENV, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx, try_ };
563
+ export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, 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, PROJECT_ALIASES_ENV, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, WEEK_DAYS, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx, try_ };
@@ -1,2 +1,2 @@
1
- import { PricingFetcher } from "./pricing-fetcher-B3SvKOod.js";
1
+ import { PricingFetcher$1 as PricingFetcher } from "./pricing-fetcher-AYfCy7g-.js";
2
2
  export { PricingFetcher };
@@ -1,4 +1,4 @@
1
- import { PricingFetcher } from "./pricing-fetcher-eNV76BjF.js";
2
- import "./_types-BHFM59hI.js";
3
- import "./logger-COLgmk2z.js";
1
+ import { PricingFetcher } from "./pricing-fetcher-CNjC0nXU.js";
2
+ import "./_types-ed8-0BH6.js";
3
+ import "./logger-C35JCduT.js";
4
4
  export { PricingFetcher };
@@ -263,7 +263,7 @@ Object.keys(r.modifier);
263
263
  const tD = Object.keys(r.color), eD = Object.keys(r.bgColor);
264
264
  [...tD, ...eD];
265
265
  function sD() {
266
- const t = /* @__PURE__ */ new Map();
266
+ const t = new Map();
267
267
  for (const [u$1, F$1] of Object.entries(r)) {
268
268
  for (const [e$1, s] of Object.entries(F$1)) r[e$1] = {
269
269
  open: `\x1B[${s[0]}m`,
@@ -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 } = (/* @__PURE__ */ new RegExp(`(?:\\${W$1}(?<code>\\d+)m|\\${y}(?<uri>.*)${w$1})`)).exec(o$1.slice(E).join("")) || { groups: {} };
384
+ const { groups: B$1 } = 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;
@@ -446,7 +446,7 @@ var AD = Object.defineProperty, pD = (t, u$1, F$1) => u$1 in t ? AD(t, u$1, {
446
446
  }) : t[u$1] = F$1, h = (t, u$1, F$1) => (pD(t, typeof u$1 != "symbol" ? u$1 + "" : u$1, F$1), F$1);
447
447
  var x = class {
448
448
  constructor(u$1, F$1 = true) {
449
- h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", false), h(this, "_prevFrame", ""), h(this, "_subscribers", /* @__PURE__ */ new Map()), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
449
+ h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", false), h(this, "_prevFrame", ""), h(this, "_subscribers", new Map()), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
450
450
  const { input: e$1 = stdin, output: s = stdout, render: i, signal: D,...C$1 } = u$1;
451
451
  this.opts = C$1, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = F$1, this._abortSignal = D, this.input = e$1, this.output = s;
452
452
  }
@@ -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 = /* @__PURE__ */ new Error("Prompt cancelled.");
807
+ const error = 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,6 +1,6 @@
1
1
  {
2
2
  "name": "ccusage",
3
- "version": "15.5.1",
3
+ "version": "15.6.0",
4
4
  "description": "Usage analysis tool for Claude Code",
5
5
  "homepage": "https://github.com/ryoppippi/ccusage#readme",
6
6
  "bugs": {