ccusage 15.1.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.
@@ -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 = new Error("Trace: " + logObj.message);
918
+ const _err = /* @__PURE__ */ new Error("Trace: " + logObj.message);
919
919
  line += this.formatStack(_err.stack || "", _err.message);
920
920
  }
921
921
  return isBadge ? "\n" + line + "\n" : line;
@@ -938,7 +938,7 @@ function createConsola$1(options = {}) {
938
938
  defaults: { level },
939
939
  stdout: process.stdout,
940
940
  stderr: process.stderr,
941
- prompt: (...args) => import("./prompt-j5YimnLx.js").then((m) => m.prompt(...args)),
941
+ prompt: (...args) => import("./prompt-DsUFNEY7.js").then((m) => m.prompt(...args)),
942
942
  reporters: options.reporters || [options.fancy ?? !(T || R) ? new FancyReporter() : new BasicReporter()],
943
943
  ...options
944
944
  });
@@ -951,7 +951,7 @@ function _getDefaultLogLevel() {
951
951
  }
952
952
  const consola = createConsola$1();
953
953
  var name = "ccusage";
954
- var version = "15.1.0";
954
+ var version = "15.3.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.d.ts CHANGED
@@ -10,6 +10,9 @@ declare const logger: ConsolaInstance;
10
10
  * Direct console.log function for cases where logger formatting is not desired
11
11
  */
12
12
  // eslint-disable-next-line no-console
13
- declare const log: (message?: any, ...optionalParams: any[]) => void;
13
+ declare const log: {
14
+ (...data: any[]): void;
15
+ (message?: any, ...optionalParams: any[]): void;
16
+ };
14
17
  //#endregion
15
18
  export { log, logger };
package/dist/logger.js CHANGED
@@ -1,2 +1,2 @@
1
- import { log, logger } from "./logger-Cke8hliP.js";
1
+ import { log, logger } from "./logger-DeTONwj8.js";
2
2
  export { log, logger };
@@ -1,7 +1,9 @@
1
- import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-Dm8hcn_h.js";
2
- import { ZodFirstPartyTypeKind, ZodOptional, ZodType, arrayType, booleanType, dateSchema, discriminatedUnionType, enumType, literalType, numberType, objectType, optionalType, recordType, stringType, unionType, unknownType } from "./_types-Cr2YEzKm.js";
3
- import { getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-BeaFK_sH.js";
4
- import { name, version } from "./logger-Cke8hliP.js";
1
+ import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-DaK2jizg.js";
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";
4
+ import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
5
+ import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-R9pMvoQp.js";
6
+ import { name, version } from "./logger-DeTONwj8.js";
5
7
  import process from "node:process";
6
8
  const LATEST_PROTOCOL_VERSION = "2025-06-18";
7
9
  const SUPPORTED_PROTOCOL_VERSIONS = [
@@ -1322,7 +1324,7 @@ var StreamableHTTPTransport = class {
1322
1324
  data: JSON.stringify(message)
1323
1325
  });
1324
1326
  } catch {
1325
- this.onerror?.(new Error("Failed replay events"));
1327
+ this.onerror?.(/* @__PURE__ */ new Error("Failed replay events"));
1326
1328
  throw new HTTPException(500, { message: "Failed replay events" });
1327
1329
  }
1328
1330
  } });
@@ -1650,18 +1652,25 @@ var Protocol = class {
1650
1652
  * The Protocol object assumes ownership of the Transport, replacing any callbacks that have already been set, and expects that it is the only user of the Transport instance going forward.
1651
1653
  */
1652
1654
  async connect(transport) {
1655
+ var _a, _b, _c;
1653
1656
  this._transport = transport;
1657
+ const _onclose = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.onclose;
1654
1658
  this._transport.onclose = () => {
1659
+ _onclose === null || _onclose === void 0 || _onclose();
1655
1660
  this._onclose();
1656
1661
  };
1662
+ const _onerror = (_b = this.transport) === null || _b === void 0 ? void 0 : _b.onerror;
1657
1663
  this._transport.onerror = (error) => {
1664
+ _onerror === null || _onerror === void 0 || _onerror(error);
1658
1665
  this._onerror(error);
1659
1666
  };
1667
+ const _onmessage = (_c = this._transport) === null || _c === void 0 ? void 0 : _c.onmessage;
1660
1668
  this._transport.onmessage = (message, extra) => {
1669
+ _onmessage === null || _onmessage === void 0 || _onmessage(message, extra);
1661
1670
  if (isJSONRPCResponse(message) || isJSONRPCError(message)) this._onresponse(message);
1662
1671
  else if (isJSONRPCRequest(message)) this._onrequest(message, extra);
1663
1672
  else if (isJSONRPCNotification(message)) this._onnotification(message);
1664
- else this._onerror(new Error(`Unknown message type: ${JSON.stringify(message)}`));
1673
+ else this._onerror(/* @__PURE__ */ new Error(`Unknown message type: ${JSON.stringify(message)}`));
1665
1674
  };
1666
1675
  await this._transport.start();
1667
1676
  }
@@ -1683,7 +1692,7 @@ var Protocol = class {
1683
1692
  var _a;
1684
1693
  const handler = (_a = this._notificationHandlers.get(notification.method)) !== null && _a !== void 0 ? _a : this.fallbackNotificationHandler;
1685
1694
  if (handler === void 0) return;
1686
- Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(new Error(`Uncaught error in notification handler: ${error}`)));
1695
+ Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Uncaught error in notification handler: ${error}`)));
1687
1696
  }
1688
1697
  _onrequest(request, extra) {
1689
1698
  var _a, _b, _c, _d;
@@ -1696,7 +1705,7 @@ var Protocol = class {
1696
1705
  code: ErrorCode.MethodNotFound,
1697
1706
  message: "Method not found"
1698
1707
  }
1699
- }).catch((error) => this._onerror(new Error(`Failed to send an error response: ${error}`)));
1708
+ }).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Failed to send an error response: ${error}`)));
1700
1709
  return;
1701
1710
  }
1702
1711
  const abortController = new AbortController();
@@ -1711,7 +1720,8 @@ var Protocol = class {
1711
1720
  relatedRequestId: request.id
1712
1721
  }),
1713
1722
  authInfo: extra === null || extra === void 0 ? void 0 : extra.authInfo,
1714
- requestId: request.id
1723
+ requestId: request.id,
1724
+ requestInfo: extra === null || extra === void 0 ? void 0 : extra.requestInfo
1715
1725
  };
1716
1726
  Promise.resolve().then(() => handler(request, fullExtra)).then((result) => {
1717
1727
  var _a$1;
@@ -1732,7 +1742,7 @@ var Protocol = class {
1732
1742
  message: (_b$1 = error.message) !== null && _b$1 !== void 0 ? _b$1 : "Internal error"
1733
1743
  }
1734
1744
  });
1735
- }).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
1745
+ }).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Failed to send response: ${error}`))).finally(() => {
1736
1746
  this._requestHandlerAbortControllers.delete(request.id);
1737
1747
  });
1738
1748
  }
@@ -1741,7 +1751,7 @@ var Protocol = class {
1741
1751
  const messageId = Number(progressToken);
1742
1752
  const handler = this._progressHandlers.get(messageId);
1743
1753
  if (!handler) {
1744
- this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(notification)}`));
1754
+ this._onerror(/* @__PURE__ */ new Error(`Received a progress notification for an unknown token: ${JSON.stringify(notification)}`));
1745
1755
  return;
1746
1756
  }
1747
1757
  const responseHandler = this._responseHandlers.get(messageId);
@@ -1758,7 +1768,7 @@ var Protocol = class {
1758
1768
  const messageId = Number(response.id);
1759
1769
  const handler = this._responseHandlers.get(messageId);
1760
1770
  if (handler === void 0) {
1761
- this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(response)}`));
1771
+ this._onerror(/* @__PURE__ */ new Error(`Received a response for an unknown message ID: ${JSON.stringify(response)}`));
1762
1772
  return;
1763
1773
  }
1764
1774
  this._responseHandlers.delete(messageId);
@@ -1790,7 +1800,7 @@ var Protocol = class {
1790
1800
  return new Promise((resolve$4, reject) => {
1791
1801
  var _a, _b, _c, _d, _e, _f;
1792
1802
  if (!this._transport) {
1793
- reject(new Error("Not connected"));
1803
+ reject(/* @__PURE__ */ new Error("Not connected"));
1794
1804
  return;
1795
1805
  }
1796
1806
  if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.enforceStrictCapabilities) === true) this.assertCapabilityForMethod(request.method);
@@ -1827,7 +1837,7 @@ var Protocol = class {
1827
1837
  relatedRequestId,
1828
1838
  resumptionToken,
1829
1839
  onresumptiontoken
1830
- }).catch((error) => this._onerror(new Error(`Failed to send cancellation: ${error}`)));
1840
+ }).catch((error) => this._onerror(/* @__PURE__ */ new Error(`Failed to send cancellation: ${error}`)));
1831
1841
  reject(reason);
1832
1842
  };
1833
1843
  this._responseHandlers.set(messageId, (response) => {
@@ -1976,8 +1986,8 @@ var require_uri_all = __commonJSMin((exports, module) => {
1976
1986
  UNRESERVED: new RegExp(UNRESERVED$$$1, "g"),
1977
1987
  OTHER_CHARS: new RegExp(merge("[^\\%]", UNRESERVED$$$1, RESERVED$$), "g"),
1978
1988
  PCT_ENCODED: new RegExp(PCT_ENCODED$$1, "g"),
1979
- IPV4ADDRESS: new RegExp("^(" + IPV4ADDRESS$ + ")$"),
1980
- IPV6ADDRESS: new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$$1 + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$")
1989
+ IPV4ADDRESS: /* @__PURE__ */ new RegExp("^(" + IPV4ADDRESS$ + ")$"),
1990
+ IPV6ADDRESS: /* @__PURE__ */ new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$$1 + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$")
1981
1991
  };
1982
1992
  }
1983
1993
  var URI_PROTOCOL = buildExps(false);
@@ -7663,7 +7673,7 @@ function parseStringDef(def, refs) {
7663
7673
  function escapeLiteralCheckValue(literal, refs) {
7664
7674
  return refs.patternStrategy === "escape" ? escapeNonAlphaNumeric(literal) : literal;
7665
7675
  }
7666
- const ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
7676
+ const ALPHA_NUMERIC = /* @__PURE__ */ new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
7667
7677
  function escapeNonAlphaNumeric(source) {
7668
7678
  let result = "";
7669
7679
  for (let i = 0; i < source.length; i++) {
@@ -8411,7 +8421,7 @@ var McpServer = class {
8411
8421
  };
8412
8422
  }
8413
8423
  }
8414
- if (tool.outputSchema) {
8424
+ if (tool.outputSchema && !result.isError) {
8415
8425
  if (!result.structuredContent) throw new McpError(ErrorCode.InvalidParams, `Tool ${request.params.name} has an output schema but no structured content was provided`);
8416
8426
  const parseResult = await tool.outputSchema.safeParseAsync(result.structuredContent);
8417
8427
  if (!parseResult.success) throw new McpError(ErrorCode.InvalidParams, `Invalid structured content for tool ${request.params.name}: ${parseResult.error.message}`);
@@ -9121,7 +9131,7 @@ var PatternRouter = class {
9121
9131
  });
9122
9132
  try {
9123
9133
  this.#routes.push([
9124
- new RegExp(`^${parts.join("")}${endsWithWildcard ? "" : "/?$"}`),
9134
+ /* @__PURE__ */ new RegExp(`^${parts.join("")}${endsWithWildcard ? "" : "/?$"}`),
9125
9135
  method,
9126
9136
  handler
9127
9137
  ]);
@@ -9148,8 +9158,120 @@ var Hono = class extends Hono$1 {
9148
9158
  }
9149
9159
  };
9150
9160
  var import_usingCtx = __toESM(require_usingCtx(), 1);
9161
+ const modelBreakdownSchema = objectType({
9162
+ modelName: stringType(),
9163
+ inputTokens: numberType(),
9164
+ outputTokens: numberType(),
9165
+ cacheCreationTokens: numberType().optional(),
9166
+ cacheReadTokens: numberType().optional(),
9167
+ cost: numberType()
9168
+ });
9169
+ const dailyUsageSchema = objectType({
9170
+ date: stringType(),
9171
+ inputTokens: numberType(),
9172
+ outputTokens: numberType(),
9173
+ cacheCreationTokens: numberType().optional(),
9174
+ cacheReadTokens: numberType().optional(),
9175
+ totalTokens: numberType(),
9176
+ totalCost: numberType(),
9177
+ modelsUsed: arrayType(stringType()),
9178
+ modelBreakdowns: arrayType(modelBreakdownSchema)
9179
+ });
9180
+ const sessionUsageSchema = objectType({
9181
+ sessionId: stringType(),
9182
+ inputTokens: numberType(),
9183
+ outputTokens: numberType(),
9184
+ cacheCreationTokens: numberType().optional(),
9185
+ cacheReadTokens: numberType().optional(),
9186
+ totalTokens: numberType(),
9187
+ totalCost: numberType(),
9188
+ lastActivity: stringType(),
9189
+ modelsUsed: arrayType(stringType()),
9190
+ modelBreakdowns: arrayType(modelBreakdownSchema)
9191
+ });
9192
+ const monthlyUsageSchema = objectType({
9193
+ month: stringType(),
9194
+ inputTokens: numberType(),
9195
+ outputTokens: numberType(),
9196
+ cacheCreationTokens: numberType().optional(),
9197
+ cacheReadTokens: numberType().optional(),
9198
+ totalTokens: numberType(),
9199
+ totalCost: numberType(),
9200
+ modelsUsed: arrayType(stringType()),
9201
+ modelBreakdowns: arrayType(modelBreakdownSchema)
9202
+ });
9203
+ const blockUsageSchema = objectType({
9204
+ id: stringType(),
9205
+ startTime: stringType(),
9206
+ endTime: stringType().optional(),
9207
+ actualEndTime: stringType().optional(),
9208
+ isActive: booleanType(),
9209
+ isGap: booleanType(),
9210
+ entries: numberType(),
9211
+ tokenCounts: objectType({
9212
+ inputTokens: numberType(),
9213
+ outputTokens: numberType(),
9214
+ cacheCreationInputTokens: numberType(),
9215
+ cacheReadInputTokens: numberType()
9216
+ }),
9217
+ totalTokens: numberType(),
9218
+ costUSD: numberType(),
9219
+ models: arrayType(stringType()),
9220
+ burnRate: numberType().nullable(),
9221
+ projection: unknownType().nullable()
9222
+ });
9223
+ const dailyResponseSchema = {
9224
+ daily: arrayType(dailyUsageSchema),
9225
+ totals: objectType({
9226
+ totalInputTokens: numberType().optional(),
9227
+ totalOutputTokens: numberType().optional(),
9228
+ totalCacheCreationTokens: numberType().optional(),
9229
+ totalCacheReadTokens: numberType().optional(),
9230
+ totalTokens: numberType().optional(),
9231
+ totalCost: numberType().optional(),
9232
+ modelsUsed: arrayType(stringType()).optional()
9233
+ })
9234
+ };
9235
+ const sessionResponseSchema = {
9236
+ sessions: arrayType(sessionUsageSchema),
9237
+ totals: objectType({
9238
+ totalInputTokens: numberType().optional(),
9239
+ totalOutputTokens: numberType().optional(),
9240
+ totalCacheCreationTokens: numberType().optional(),
9241
+ totalCacheReadTokens: numberType().optional(),
9242
+ totalTokens: numberType().optional(),
9243
+ totalCost: numberType().optional(),
9244
+ modelsUsed: arrayType(stringType()).optional()
9245
+ })
9246
+ };
9247
+ const monthlyResponseSchema = {
9248
+ monthly: arrayType(monthlyUsageSchema),
9249
+ totals: objectType({
9250
+ totalInputTokens: numberType().optional(),
9251
+ totalOutputTokens: numberType().optional(),
9252
+ totalCacheCreationTokens: numberType().optional(),
9253
+ totalCacheReadTokens: numberType().optional(),
9254
+ totalTokens: numberType().optional(),
9255
+ totalCost: numberType().optional(),
9256
+ modelsUsed: arrayType(stringType()).optional()
9257
+ })
9258
+ };
9259
+ const blocksResponseSchema = { blocks: arrayType(blockUsageSchema) };
9260
+ /**
9261
+ * Helper function to transform usage data with totals into JSON output format
9262
+ */
9263
+ function transformUsageDataWithTotals(data, totals, mapper, key) {
9264
+ return {
9265
+ [key]: data.map(mapper),
9266
+ totals: createTotalsObject(totals)
9267
+ };
9268
+ }
9151
9269
  /** Default options for the MCP server */
9152
- const defaultOptions = { claudePath: getDefaultClaudePath() };
9270
+ const defaultOptions = { claudePath: (() => {
9271
+ const paths = getClaudePaths();
9272
+ if (paths.length === 0) throw new Error("No valid Claude path found. Ensure getClaudePaths() returns at least one valid path.");
9273
+ return paths[0];
9274
+ })() };
9153
9275
  /**
9154
9276
  * Creates an MCP server with tools for showing usage reports.
9155
9277
  * Registers tools for daily, session, monthly, and blocks usage data.
@@ -9164,8 +9286,8 @@ function createMcpServer({ claudePath } = defaultOptions) {
9164
9286
  version
9165
9287
  });
9166
9288
  const parametersZodSchema = {
9167
- since: dateSchema.optional(),
9168
- until: dateSchema.optional(),
9289
+ since: filterDateSchema.optional(),
9290
+ until: filterDateSchema.optional(),
9169
9291
  mode: enumType([
9170
9292
  "auto",
9171
9293
  "calculate",
@@ -9174,55 +9296,125 @@ function createMcpServer({ claudePath } = defaultOptions) {
9174
9296
  };
9175
9297
  server.registerTool("daily", {
9176
9298
  description: "Show usage report grouped by date",
9177
- inputSchema: parametersZodSchema
9299
+ inputSchema: parametersZodSchema,
9300
+ outputSchema: dailyResponseSchema
9178
9301
  }, async (args) => {
9179
9302
  const dailyData = await loadDailyUsageData({
9180
9303
  ...args,
9181
9304
  claudePath
9182
9305
  });
9183
- return { content: [{
9184
- type: "text",
9185
- text: JSON.stringify(dailyData, null, 2)
9186
- }] };
9306
+ const totals = calculateTotals(dailyData);
9307
+ const jsonOutput = transformUsageDataWithTotals(dailyData, totals, (data) => ({
9308
+ date: data.date,
9309
+ inputTokens: data.inputTokens,
9310
+ outputTokens: data.outputTokens,
9311
+ cacheCreationTokens: data.cacheCreationTokens,
9312
+ cacheReadTokens: data.cacheReadTokens,
9313
+ totalTokens: getTotalTokens(data),
9314
+ totalCost: data.totalCost,
9315
+ modelsUsed: data.modelsUsed,
9316
+ modelBreakdowns: data.modelBreakdowns
9317
+ }), "daily");
9318
+ return {
9319
+ content: [{
9320
+ type: "text",
9321
+ text: JSON.stringify(jsonOutput, null, 2)
9322
+ }],
9323
+ structuredContent: jsonOutput
9324
+ };
9187
9325
  });
9188
9326
  server.registerTool("session", {
9189
9327
  description: "Show usage report grouped by conversation session",
9190
- inputSchema: parametersZodSchema
9328
+ inputSchema: parametersZodSchema,
9329
+ outputSchema: sessionResponseSchema
9191
9330
  }, async (args) => {
9192
9331
  const sessionData = await loadSessionData({
9193
9332
  ...args,
9194
9333
  claudePath
9195
9334
  });
9196
- return { content: [{
9197
- type: "text",
9198
- text: JSON.stringify(sessionData, null, 2)
9199
- }] };
9335
+ const totals = calculateTotals(sessionData);
9336
+ const jsonOutput = transformUsageDataWithTotals(sessionData, totals, (data) => ({
9337
+ sessionId: data.sessionId,
9338
+ inputTokens: data.inputTokens,
9339
+ outputTokens: data.outputTokens,
9340
+ cacheCreationTokens: data.cacheCreationTokens,
9341
+ cacheReadTokens: data.cacheReadTokens,
9342
+ totalTokens: getTotalTokens(data),
9343
+ totalCost: data.totalCost,
9344
+ lastActivity: data.lastActivity,
9345
+ modelsUsed: data.modelsUsed,
9346
+ modelBreakdowns: data.modelBreakdowns
9347
+ }), "sessions");
9348
+ return {
9349
+ content: [{
9350
+ type: "text",
9351
+ text: JSON.stringify(jsonOutput, null, 2)
9352
+ }],
9353
+ structuredContent: jsonOutput
9354
+ };
9200
9355
  });
9201
9356
  server.registerTool("monthly", {
9202
9357
  description: "Show usage report grouped by month",
9203
- inputSchema: parametersZodSchema
9358
+ inputSchema: parametersZodSchema,
9359
+ outputSchema: monthlyResponseSchema
9204
9360
  }, async (args) => {
9205
9361
  const monthlyData = await loadMonthlyUsageData({
9206
9362
  ...args,
9207
9363
  claudePath
9208
9364
  });
9209
- return { content: [{
9210
- type: "text",
9211
- text: JSON.stringify(monthlyData, null, 2)
9212
- }] };
9365
+ const totals = calculateTotals(monthlyData);
9366
+ const jsonOutput = transformUsageDataWithTotals(monthlyData, totals, (data) => ({
9367
+ month: data.month,
9368
+ inputTokens: data.inputTokens,
9369
+ outputTokens: data.outputTokens,
9370
+ cacheCreationTokens: data.cacheCreationTokens,
9371
+ cacheReadTokens: data.cacheReadTokens,
9372
+ totalTokens: getTotalTokens(data),
9373
+ totalCost: data.totalCost,
9374
+ modelsUsed: data.modelsUsed,
9375
+ modelBreakdowns: data.modelBreakdowns
9376
+ }), "monthly");
9377
+ return {
9378
+ content: [{
9379
+ type: "text",
9380
+ text: JSON.stringify(jsonOutput, null, 2)
9381
+ }],
9382
+ structuredContent: jsonOutput
9383
+ };
9213
9384
  });
9214
9385
  server.registerTool("blocks", {
9215
9386
  description: "Show usage report grouped by session billing blocks",
9216
- inputSchema: parametersZodSchema
9387
+ inputSchema: parametersZodSchema,
9388
+ outputSchema: blocksResponseSchema
9217
9389
  }, async (args) => {
9218
- const blocksData = await loadSessionBlockData({
9390
+ const blocks = await loadSessionBlockData({
9219
9391
  ...args,
9220
9392
  claudePath
9221
9393
  });
9222
- return { content: [{
9223
- type: "text",
9224
- text: JSON.stringify(blocksData, null, 2)
9225
- }] };
9394
+ const jsonOutput = { blocks: blocks.map((block) => {
9395
+ return {
9396
+ id: block.id,
9397
+ startTime: block.startTime.toISOString(),
9398
+ endTime: block.endTime.toISOString(),
9399
+ actualEndTime: block.actualEndTime?.toISOString() ?? null,
9400
+ isActive: block.isActive,
9401
+ isGap: block.isGap ?? false,
9402
+ entries: block.entries.length,
9403
+ tokenCounts: block.tokenCounts,
9404
+ totalTokens: block.tokenCounts.inputTokens + block.tokenCounts.outputTokens,
9405
+ costUSD: block.costUSD,
9406
+ models: block.models,
9407
+ burnRate: null,
9408
+ projection: null
9409
+ };
9410
+ }) };
9411
+ return {
9412
+ content: [{
9413
+ type: "text",
9414
+ text: JSON.stringify(jsonOutput, null, 2)
9415
+ }],
9416
+ structuredContent: jsonOutput
9417
+ };
9226
9418
  });
9227
9419
  return server;
9228
9420
  }
package/dist/mcp.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { LoadOptions } from "./data-loader-DZczD-9E.js";
2
- import "./pricing-fetcher-BZe7AafW.js";
1
+ import { LoadOptions } from "./data-loader-a9CiVyT5.js";
2
+ import "./pricing-fetcher-B3SvKOod.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,6 +1,8 @@
1
- import "./pricing-fetcher-Dm8hcn_h.js";
2
- import "./_types-Cr2YEzKm.js";
3
- import "./data-loader-BeaFK_sH.js";
4
- import "./logger-Cke8hliP.js";
5
- import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-DKqp_F9c.js";
1
+ import "./pricing-fetcher-DaK2jizg.js";
2
+ import "./_token-utils-WjkbrjKv.js";
3
+ import "./_types-BHFM59hI.js";
4
+ import "./calculate-cost-BDqO4yWA.js";
5
+ import "./data-loader-R9pMvoQp.js";
6
+ import "./logger-DeTONwj8.js";
7
+ import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-Kff7A2dF.js";
6
8
  export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { Result } from "@praha/byethrow";
2
3
 
3
4
  //#region node_modules/type-fest/source/observable-like.d.ts
4
5
  declare global {
@@ -139,19 +140,25 @@ declare class PricingFetcher implements Disposable {
139
140
  * Clears the cached pricing data
140
141
  */
141
142
  clearCache(): void;
143
+ /**
144
+ * Loads offline pricing data from pre-fetched cache
145
+ * @returns Map of model names to pricing information
146
+ */
147
+ private loadOfflinePricing;
148
+ private handleFallbackToCachedPricing;
142
149
  private ensurePricingLoaded;
143
150
  /**
144
151
  * Fetches all available model pricing data
145
152
  * @returns Map of model names to pricing information
146
153
  */
147
- fetchModelPricing(): Promise<Map<string, ModelPricing>>;
154
+ fetchModelPricing(): Result.ResultAsync<Map<string, ModelPricing>, Error>;
148
155
  /**
149
156
  * Gets pricing information for a specific model with fallback matching
150
157
  * Tries exact match first, then provider prefixes, then partial matches
151
158
  * @param modelName - Name of the model to get pricing for
152
159
  * @returns Model pricing information or null if not found
153
160
  */
154
- getModelPricing(modelName: string): Promise<ModelPricing | null>;
161
+ getModelPricing(modelName: string): Result.ResultAsync<ModelPricing | null, Error>;
155
162
  /**
156
163
  * Calculates the cost for given token usage and model
157
164
  * @param tokens - Token usage breakdown
@@ -167,7 +174,7 @@ declare class PricingFetcher implements Disposable {
167
174
  output_tokens: number;
168
175
  cache_creation_input_tokens?: number;
169
176
  cache_read_input_tokens?: number;
170
- }, modelName: string): Promise<number>;
177
+ }, modelName: string): Result.ResultAsync<number, Error>;
171
178
  /**
172
179
  * Calculates cost from token usage and pricing information
173
180
  * @param tokens - Token usage breakdown