ccusage 11.0.2 → 12.0.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.
package/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { CostModes, SortOrders, __commonJSMin, __require, __toESM, dateSchema } from "./pricing-fetcher-DDs53oR8.js";
2
+ import { CostModes, SortOrders, __commonJSMin, __require, __toESM, dateSchema } from "./pricing-fetcher-3m6_Ejp8.js";
3
3
  import { calculateTotals, createTotalsObject, getTotalTokens } from "./calculate-cost-D3IraeGW.js";
4
- import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, filterRecentBlocks, formatDateCompact, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, projectBlockUsage } from "./data-loader-B2EwZ_7B.js";
5
- import { safeParse } from "./dist-DCvt9hEv.js";
6
- import { description, log, logger, name, version } from "./logger-DPEwxrOW.js";
7
- import { detectMismatches, printMismatchReport } from "./debug-D4Ka6IrY.js";
8
- import "./types-5-VF7WcO.js";
9
- import { createMcpServer } from "./mcp-CklIto13.js";
10
- import "./index-CISmcbXk-DpuCarFe.js";
4
+ import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, filterRecentBlocks, formatDateCompact, getDefaultClaudePath, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, projectBlockUsage } from "./data-loader-rsgRy-no.js";
5
+ import { description, log, logger, name, version } from "./logger-CTFDCX5W.js";
6
+ import { detectMismatches, printMismatchReport } from "./debug-BhnEVNbA.js";
7
+ import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-Cg5potQX.js";
11
8
  import process$1 from "node:process";
9
+ import { createServer } from "http";
10
+ import { Http2ServerRequest } from "http2";
11
+ import { Readable } from "stream";
12
+ import crypto from "crypto";
12
13
  /**
13
14
  * The default locale string, which format is BCP 47 language tag.
14
15
  */
@@ -1190,9 +1191,9 @@ var require_picocolors = __commonJSMin((exports, module) => {
1190
1191
  * @throws TypeError if date format is invalid
1191
1192
  */
1192
1193
  function parseDateArg(value) {
1193
- const result = safeParse(dateSchema, value);
1194
- if (!result.success) throw new TypeError(result.issues[0].message);
1195
- return result.output;
1194
+ const result = dateSchema.safeParse(value);
1195
+ if (!result.success) throw new TypeError(result.error.issues[0]?.message ?? "Invalid date format");
1196
+ return result.data;
1196
1197
  }
1197
1198
  /**
1198
1199
  * Shared command line arguments used across multiple CLI commands
@@ -3253,7 +3254,7 @@ const blocksCommand = define({
3253
3254
  id: block.id,
3254
3255
  startTime: block.startTime.toISOString(),
3255
3256
  endTime: block.endTime.toISOString(),
3256
- actualEndTime: block.actualEndTime != null ? block.actualEndTime.toISOString() : null,
3257
+ actualEndTime: block.actualEndTime?.toISOString() ?? null,
3257
3258
  isActive: block.isActive,
3258
3259
  isGap: block.isGap ?? false,
3259
3260
  entries: block.entries.length,
@@ -3522,9 +3523,378 @@ const dailyCommand = define({
3522
3523
  }
3523
3524
  }
3524
3525
  });
3526
+ var RequestError = class extends Error {
3527
+ constructor(message, options) {
3528
+ super(message, options);
3529
+ this.name = "RequestError";
3530
+ }
3531
+ };
3532
+ var toRequestError = (e) => {
3533
+ if (e instanceof RequestError) return e;
3534
+ return new RequestError(e.message, { cause: e });
3535
+ };
3536
+ var GlobalRequest = global.Request;
3537
+ var Request = class extends GlobalRequest {
3538
+ constructor(input, options) {
3539
+ if (typeof input === "object" && getRequestCache in input) input = input[getRequestCache]();
3540
+ if (typeof options?.body?.getReader !== "undefined") options.duplex ??= "half";
3541
+ super(input, options);
3542
+ }
3543
+ };
3544
+ var newRequestFromIncoming = (method, url, incoming, abortController) => {
3545
+ const headerRecord = [];
3546
+ const rawHeaders = incoming.rawHeaders;
3547
+ for (let i = 0; i < rawHeaders.length; i += 2) {
3548
+ const { [i]: key, [i + 1]: value } = rawHeaders;
3549
+ if (key.charCodeAt(0) !== 58) headerRecord.push([key, value]);
3550
+ }
3551
+ const init$1 = {
3552
+ method,
3553
+ headers: headerRecord,
3554
+ signal: abortController.signal
3555
+ };
3556
+ if (method === "TRACE") {
3557
+ init$1.method = "GET";
3558
+ const req = new Request(url, init$1);
3559
+ Object.defineProperty(req, "method", { get() {
3560
+ return "TRACE";
3561
+ } });
3562
+ return req;
3563
+ }
3564
+ if (!(method === "GET" || method === "HEAD")) if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) init$1.body = new ReadableStream({ start(controller) {
3565
+ controller.enqueue(incoming.rawBody);
3566
+ controller.close();
3567
+ } });
3568
+ else init$1.body = Readable.toWeb(incoming);
3569
+ return new Request(url, init$1);
3570
+ };
3571
+ var getRequestCache = Symbol("getRequestCache");
3572
+ var requestCache = Symbol("requestCache");
3573
+ var incomingKey = Symbol("incomingKey");
3574
+ var urlKey = Symbol("urlKey");
3575
+ var abortControllerKey = Symbol("abortControllerKey");
3576
+ var getAbortController = Symbol("getAbortController");
3577
+ var requestPrototype = {
3578
+ get method() {
3579
+ return this[incomingKey].method || "GET";
3580
+ },
3581
+ get url() {
3582
+ return this[urlKey];
3583
+ },
3584
+ [getAbortController]() {
3585
+ this[getRequestCache]();
3586
+ return this[abortControllerKey];
3587
+ },
3588
+ [getRequestCache]() {
3589
+ this[abortControllerKey] ||= new AbortController();
3590
+ return this[requestCache] ||= newRequestFromIncoming(this.method, this[urlKey], this[incomingKey], this[abortControllerKey]);
3591
+ }
3592
+ };
3593
+ [
3594
+ "body",
3595
+ "bodyUsed",
3596
+ "cache",
3597
+ "credentials",
3598
+ "destination",
3599
+ "headers",
3600
+ "integrity",
3601
+ "mode",
3602
+ "redirect",
3603
+ "referrer",
3604
+ "referrerPolicy",
3605
+ "signal",
3606
+ "keepalive"
3607
+ ].forEach((k) => {
3608
+ Object.defineProperty(requestPrototype, k, { get() {
3609
+ return this[getRequestCache]()[k];
3610
+ } });
3611
+ });
3612
+ [
3613
+ "arrayBuffer",
3614
+ "blob",
3615
+ "clone",
3616
+ "formData",
3617
+ "json",
3618
+ "text"
3619
+ ].forEach((k) => {
3620
+ Object.defineProperty(requestPrototype, k, { value: function() {
3621
+ return this[getRequestCache]()[k]();
3622
+ } });
3623
+ });
3624
+ Object.setPrototypeOf(requestPrototype, Request.prototype);
3625
+ var newRequest = (incoming, defaultHostname) => {
3626
+ const req = Object.create(requestPrototype);
3627
+ req[incomingKey] = incoming;
3628
+ const incomingUrl = incoming.url || "";
3629
+ if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
3630
+ if (incoming instanceof Http2ServerRequest) throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
3631
+ try {
3632
+ const url2 = new URL(incomingUrl);
3633
+ req[urlKey] = url2.href;
3634
+ } catch (e) {
3635
+ throw new RequestError("Invalid absolute URL", { cause: e });
3636
+ }
3637
+ return req;
3638
+ }
3639
+ const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
3640
+ if (!host) throw new RequestError("Missing host header");
3641
+ let scheme;
3642
+ if (incoming instanceof Http2ServerRequest) {
3643
+ scheme = incoming.scheme;
3644
+ if (!(scheme === "http" || scheme === "https")) throw new RequestError("Unsupported scheme");
3645
+ } else scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
3646
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
3647
+ if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) throw new RequestError("Invalid host header");
3648
+ req[urlKey] = url.href;
3649
+ return req;
3650
+ };
3651
+ var responseCache = Symbol("responseCache");
3652
+ var getResponseCache = Symbol("getResponseCache");
3653
+ var cacheKey = Symbol("cache");
3654
+ var GlobalResponse = global.Response;
3655
+ var Response2 = class _Response {
3656
+ #body;
3657
+ #init;
3658
+ [getResponseCache]() {
3659
+ delete this[cacheKey];
3660
+ return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
3661
+ }
3662
+ constructor(body, init$1) {
3663
+ let headers;
3664
+ this.#body = body;
3665
+ if (init$1 instanceof _Response) {
3666
+ const cachedGlobalResponse = init$1[responseCache];
3667
+ if (cachedGlobalResponse) {
3668
+ this.#init = cachedGlobalResponse;
3669
+ this[getResponseCache]();
3670
+ return;
3671
+ } else {
3672
+ this.#init = init$1.#init;
3673
+ headers = new Headers(init$1.#init.headers);
3674
+ }
3675
+ } else this.#init = init$1;
3676
+ if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
3677
+ headers ||= init$1?.headers || { "content-type": "text/plain; charset=UTF-8" };
3678
+ this[cacheKey] = [
3679
+ init$1?.status || 200,
3680
+ body,
3681
+ headers
3682
+ ];
3683
+ }
3684
+ }
3685
+ get headers() {
3686
+ const cache = this[cacheKey];
3687
+ if (cache) {
3688
+ if (!(cache[2] instanceof Headers)) cache[2] = new Headers(cache[2]);
3689
+ return cache[2];
3690
+ }
3691
+ return this[getResponseCache]().headers;
3692
+ }
3693
+ get status() {
3694
+ return this[cacheKey]?.[0] ?? this[getResponseCache]().status;
3695
+ }
3696
+ get ok() {
3697
+ const status = this.status;
3698
+ return status >= 200 && status < 300;
3699
+ }
3700
+ };
3701
+ [
3702
+ "body",
3703
+ "bodyUsed",
3704
+ "redirected",
3705
+ "statusText",
3706
+ "trailers",
3707
+ "type",
3708
+ "url"
3709
+ ].forEach((k) => {
3710
+ Object.defineProperty(Response2.prototype, k, { get() {
3711
+ return this[getResponseCache]()[k];
3712
+ } });
3713
+ });
3714
+ [
3715
+ "arrayBuffer",
3716
+ "blob",
3717
+ "clone",
3718
+ "formData",
3719
+ "json",
3720
+ "text"
3721
+ ].forEach((k) => {
3722
+ Object.defineProperty(Response2.prototype, k, { value: function() {
3723
+ return this[getResponseCache]()[k]();
3724
+ } });
3725
+ });
3726
+ Object.setPrototypeOf(Response2, GlobalResponse);
3727
+ Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
3728
+ function writeFromReadableStream(stream, writable) {
3729
+ if (stream.locked) throw new TypeError("ReadableStream is locked.");
3730
+ else if (writable.destroyed) {
3731
+ stream.cancel();
3732
+ return;
3733
+ }
3734
+ const reader = stream.getReader();
3735
+ writable.on("close", cancel);
3736
+ writable.on("error", cancel);
3737
+ reader.read().then(flow, cancel);
3738
+ return reader.closed.finally(() => {
3739
+ writable.off("close", cancel);
3740
+ writable.off("error", cancel);
3741
+ });
3742
+ function cancel(error) {
3743
+ reader.cancel(error).catch(() => {});
3744
+ if (error) writable.destroy(error);
3745
+ }
3746
+ function onDrain() {
3747
+ reader.read().then(flow, cancel);
3748
+ }
3749
+ function flow({ done, value }) {
3750
+ try {
3751
+ if (done) writable.end();
3752
+ else if (!writable.write(value)) writable.once("drain", onDrain);
3753
+ else return reader.read().then(flow, cancel);
3754
+ } catch (e) {
3755
+ cancel(e);
3756
+ }
3757
+ }
3758
+ }
3759
+ var buildOutgoingHttpHeaders = (headers) => {
3760
+ const res = {};
3761
+ if (!(headers instanceof Headers)) headers = new Headers(headers ?? void 0);
3762
+ const cookies = [];
3763
+ for (const [k, v] of headers) if (k === "set-cookie") cookies.push(v);
3764
+ else res[k] = v;
3765
+ if (cookies.length > 0) res["set-cookie"] = cookies;
3766
+ res["content-type"] ??= "text/plain; charset=UTF-8";
3767
+ return res;
3768
+ };
3769
+ var X_ALREADY_SENT = "x-hono-already-sent";
3770
+ var webFetch = global.fetch;
3771
+ if (typeof global.crypto === "undefined") global.crypto = crypto;
3772
+ global.fetch = (info$1, init$1) => {
3773
+ init$1 = {
3774
+ compress: false,
3775
+ ...init$1
3776
+ };
3777
+ return webFetch(info$1, init$1);
3778
+ };
3779
+ var regBuffer = /^no$/i;
3780
+ var regContentType = /^(application\/json\b|text\/(?!event-stream\b))/i;
3781
+ var handleRequestError = () => new Response(null, { status: 400 });
3782
+ var handleFetchError = (e) => new Response(null, { status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500 });
3783
+ var handleResponseError = (e, outgoing) => {
3784
+ const err = e instanceof Error ? e : new Error("unknown error", { cause: e });
3785
+ if (err.code === "ERR_STREAM_PREMATURE_CLOSE") console.info("The user aborted a request.");
3786
+ else {
3787
+ console.error(e);
3788
+ if (!outgoing.headersSent) outgoing.writeHead(500, { "Content-Type": "text/plain" });
3789
+ outgoing.end(`Error: ${err.message}`);
3790
+ outgoing.destroy(err);
3791
+ }
3792
+ };
3793
+ var flushHeaders = (outgoing) => {
3794
+ if ("flushHeaders" in outgoing && outgoing.writable) outgoing.flushHeaders();
3795
+ };
3796
+ var responseViaCache = async (res, outgoing) => {
3797
+ let [status, body, header] = res[cacheKey];
3798
+ if (header instanceof Headers) header = buildOutgoingHttpHeaders(header);
3799
+ if (typeof body === "string") header["Content-Length"] = Buffer.byteLength(body);
3800
+ else if (body instanceof Uint8Array) header["Content-Length"] = body.byteLength;
3801
+ else if (body instanceof Blob) header["Content-Length"] = body.size;
3802
+ outgoing.writeHead(status, header);
3803
+ if (typeof body === "string" || body instanceof Uint8Array) outgoing.end(body);
3804
+ else if (body instanceof Blob) outgoing.end(new Uint8Array(await body.arrayBuffer()));
3805
+ else {
3806
+ flushHeaders(outgoing);
3807
+ return writeFromReadableStream(body, outgoing)?.catch((e) => handleResponseError(e, outgoing));
3808
+ }
3809
+ };
3810
+ var responseViaResponseObject = async (res, outgoing, options = {}) => {
3811
+ if (res instanceof Promise) if (options.errorHandler) try {
3812
+ res = await res;
3813
+ } catch (err) {
3814
+ const errRes = await options.errorHandler(err);
3815
+ if (!errRes) return;
3816
+ res = errRes;
3817
+ }
3818
+ else res = await res.catch(handleFetchError);
3819
+ if (cacheKey in res) return responseViaCache(res, outgoing);
3820
+ const resHeaderRecord = buildOutgoingHttpHeaders(res.headers);
3821
+ if (res.body) {
3822
+ const { "transfer-encoding": transferEncoding, "content-encoding": contentEncoding, "content-length": contentLength, "x-accel-buffering": accelBuffering, "content-type": contentType } = resHeaderRecord;
3823
+ if (transferEncoding || contentEncoding || contentLength || accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
3824
+ outgoing.writeHead(res.status, resHeaderRecord);
3825
+ flushHeaders(outgoing);
3826
+ await writeFromReadableStream(res.body, outgoing);
3827
+ } else {
3828
+ const buffer = await res.arrayBuffer();
3829
+ resHeaderRecord["content-length"] = buffer.byteLength;
3830
+ outgoing.writeHead(res.status, resHeaderRecord);
3831
+ outgoing.end(new Uint8Array(buffer));
3832
+ }
3833
+ } else if (resHeaderRecord[X_ALREADY_SENT]) {} else {
3834
+ outgoing.writeHead(res.status, resHeaderRecord);
3835
+ outgoing.end();
3836
+ }
3837
+ };
3838
+ var getRequestListener = (fetchCallback, options = {}) => {
3839
+ if (options.overrideGlobalObjects !== false && global.Request !== Request) {
3840
+ Object.defineProperty(global, "Request", { value: Request });
3841
+ Object.defineProperty(global, "Response", { value: Response2 });
3842
+ }
3843
+ return async (incoming, outgoing) => {
3844
+ let res, req;
3845
+ try {
3846
+ req = newRequest(incoming, options.hostname);
3847
+ outgoing.on("close", () => {
3848
+ const abortController = req[abortControllerKey];
3849
+ if (!abortController) return;
3850
+ if (incoming.errored) req[abortControllerKey].abort(incoming.errored.toString());
3851
+ else if (!outgoing.writableFinished) req[abortControllerKey].abort("Client connection prematurely closed.");
3852
+ });
3853
+ res = fetchCallback(req, {
3854
+ incoming,
3855
+ outgoing
3856
+ });
3857
+ if (cacheKey in res) return responseViaCache(res, outgoing);
3858
+ } catch (e) {
3859
+ if (!res) if (options.errorHandler) {
3860
+ res = await options.errorHandler(req ? e : toRequestError(e));
3861
+ if (!res) return;
3862
+ } else if (!req) res = handleRequestError();
3863
+ else res = handleFetchError(e);
3864
+ else return handleResponseError(e, outgoing);
3865
+ }
3866
+ try {
3867
+ return await responseViaResponseObject(res, outgoing, options);
3868
+ } catch (e) {
3869
+ return handleResponseError(e, outgoing);
3870
+ }
3871
+ };
3872
+ };
3873
+ var createAdaptorServer = (options) => {
3874
+ const fetchCallback = options.fetch;
3875
+ const requestListener = getRequestListener(fetchCallback, {
3876
+ hostname: options.hostname,
3877
+ overrideGlobalObjects: options.overrideGlobalObjects
3878
+ });
3879
+ const createServer$1 = options.createServer || createServer;
3880
+ const server = createServer$1(options.serverOptions || {}, requestListener);
3881
+ return server;
3882
+ };
3883
+ var serve = (options, listeningListener) => {
3884
+ const server = createAdaptorServer(options);
3885
+ server.listen(options?.port ?? 3e3, options.hostname, () => {
3886
+ const serverInfo = server.address();
3887
+ listeningListener && listeningListener(serverInfo);
3888
+ });
3889
+ return server;
3890
+ };
3891
+ /**
3892
+ * MCP server command that supports both stdio and HTTP transports.
3893
+ * Allows starting an MCP server for external integrations with usage reporting tools.
3894
+ */
3525
3895
  const mcpCommand = define({
3526
3896
  name: "mcp",
3527
- description: "Show usage report for MCP",
3897
+ description: "Start MCP server with usage reporting tools",
3528
3898
  args: {
3529
3899
  mode: sharedArgs.mode,
3530
3900
  type: {
@@ -3543,14 +3913,21 @@ const mcpCommand = define({
3543
3913
  async run(ctx) {
3544
3914
  const { type, mode, port } = ctx.values;
3545
3915
  if (type === "stdio") logger.level = 0;
3546
- const server = createMcpServer({
3916
+ const options = {
3547
3917
  claudePath: getDefaultClaudePath(),
3548
3918
  mode
3549
- });
3550
- await server.start(ctx.values.type === "http" ? {
3551
- transportType: "httpStream",
3552
- httpStream: { port }
3553
- } : { transportType: "stdio" });
3919
+ };
3920
+ if (type === "stdio") {
3921
+ const server = createMcpServer(options);
3922
+ await startMcpServerStdio(server);
3923
+ } else {
3924
+ const app = createMcpHttpApp(options);
3925
+ serve({
3926
+ fetch: app.fetch,
3927
+ port
3928
+ });
3929
+ logger.info(`MCP server is running on http://localhost:${port}`);
3930
+ }
3554
3931
  }
3555
3932
  });
3556
3933
  var import_picocolors$1 = __toESM(require_picocolors(), 1);
@@ -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-CUbwSrjo.js").then((m) => m.prompt(...args)),
941
+ prompt: (...args) => import("./prompt-E8j7mEMw.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 = "11.0.2";
954
+ var version = "12.0.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-DPEwxrOW.js";
1
+ import { log, logger } from "./logger-CTFDCX5W.js";
2
2
  export { log, logger };