ccusage 15.9.0 → 15.9.2

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,7 +1,7 @@
1
- import { CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_RECENT_DAYS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx } from "./pricing-fetcher-S0o3dB03.js";
1
+ import { CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_RECENT_DAYS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx } from "./pricing-fetcher-DXFi0Cxk.js";
2
2
  import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
3
3
  import { activityDateSchema, arrayType, booleanType, createBucket, createDailyDate, createMonthlyDate, createProjectPath, createSessionId, createWeeklyDate, dailyDateSchema, isoTimestampSchema, messageIdSchema, modelNameSchema, monthlyDateSchema, numberType, objectType, projectPathSchema, requestIdSchema, sessionIdSchema, stringType, unionType, versionSchema, weeklyDateSchema } from "./_types-B-1t4mxD.js";
4
- import { logger } from "./logger-DxuNm8GV.js";
4
+ import { logger } from "./logger-BrRa0CCy.js";
5
5
  import a, { readFile } from "node:fs/promises";
6
6
  import path, { posix } from "node:path";
7
7
  import process$1 from "node:process";
@@ -1,6 +1,6 @@
1
- import "./pricing-fetcher-S0o3dB03.js";
1
+ import "./pricing-fetcher-DXFi0Cxk.js";
2
2
  import "./_token-utils-WjkbrjKv.js";
3
3
  import "./_types-B-1t4mxD.js";
4
- import { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema } from "./data-loader-CKAeM9ir.js";
5
- import "./logger-DxuNm8GV.js";
4
+ import { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema } from "./data-loader-KL1zbb-w.js";
5
+ import "./logger-BrRa0CCy.js";
6
6
  export { bucketUsageSchema, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, usageDataSchema, weeklyUsageSchema };
@@ -1,6 +1,6 @@
1
- import { CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, PricingFetcher, USAGE_DATA_GLOB_PATTERN, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-S0o3dB03.js";
2
- import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-CKAeM9ir.js";
3
- import { logger } from "./logger-DxuNm8GV.js";
1
+ import { CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, PricingFetcher, USAGE_DATA_GLOB_PATTERN, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-DXFi0Cxk.js";
2
+ import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-KL1zbb-w.js";
3
+ import { logger } from "./logger-BrRa0CCy.js";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  var import_usingCtx = __toESM(require_usingCtx(), 1);
package/dist/debug.js CHANGED
@@ -1,7 +1,7 @@
1
- import "./pricing-fetcher-S0o3dB03.js";
1
+ import "./pricing-fetcher-DXFi0Cxk.js";
2
2
  import "./_token-utils-WjkbrjKv.js";
3
3
  import "./_types-B-1t4mxD.js";
4
- import "./data-loader-CKAeM9ir.js";
5
- import "./logger-DxuNm8GV.js";
6
- import { detectMismatches, printMismatchReport } from "./debug-DMwiBRRn.js";
4
+ import "./data-loader-KL1zbb-w.js";
5
+ import "./logger-BrRa0CCy.js";
6
+ import { detectMismatches, printMismatchReport } from "./debug-zMK0YYJP.js";
7
7
  export { detectMismatches, printMismatchReport };
package/dist/index.js CHANGED
@@ -1,14 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, 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, WEEK_DAYS, __commonJSMin, __require, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-S0o3dB03.js";
2
+ import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, 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, WEEK_DAYS, __commonJSMin, __require, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-DXFi0Cxk.js";
3
3
  import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
4
4
  import { CostModes, SortOrders, filterDateSchema, statuslineHookJsonSchema } from "./_types-B-1t4mxD.js";
5
5
  import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
6
- import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, uniq, usageDataSchema } from "./data-loader-CKAeM9ir.js";
7
- import { description, log, logger, name, version } from "./logger-DxuNm8GV.js";
8
- import { detectMismatches, printMismatchReport } from "./debug-DMwiBRRn.js";
9
- import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-pA-Z7D2o.js";
10
- import { readFile } from "node:fs/promises";
6
+ import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, uniq, usageDataSchema } from "./data-loader-KL1zbb-w.js";
7
+ import { description, log, logger, name, version } from "./logger-BrRa0CCy.js";
8
+ import { detectMismatches, printMismatchReport } from "./debug-zMK0YYJP.js";
9
+ import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-BBhsgnNL.js";
10
+ import a, { readFile } from "node:fs/promises";
11
+ import path from "node:path";
11
12
  import process$1 from "node:process";
13
+ import { stripVTControlCharacters } from "node:util";
14
+ import { fileURLToPath } from "node:url";
15
+ import { spawn } from "node:child_process";
16
+ import { on, once } from "node:events";
17
+ import { pipeline } from "node:stream/promises";
18
+ import * as readline from "node:readline/promises";
12
19
  import { createServer } from "node:http";
13
20
  import { Http2ServerRequest } from "node:http2";
14
21
  import { Readable } from "node:stream";
@@ -1187,6 +1194,253 @@ var require_picocolors = __commonJSMin((exports, module) => {
1187
1194
  module.exports = createColors();
1188
1195
  module.exports.createColors = createColors;
1189
1196
  });
1197
+ const getContext = (raw) => ({
1198
+ start: process$1.hrtime.bigint(),
1199
+ command: raw.map((part) => getCommandPart(stripVTControlCharacters(part))).join(" "),
1200
+ state: {
1201
+ stdout: "",
1202
+ stderr: "",
1203
+ output: ""
1204
+ }
1205
+ });
1206
+ const getCommandPart = (part) => /[^\w./-]/.test(part) ? `'${part.replaceAll("'", "'\\''")}'` : part;
1207
+ const getOptions = ({ stdin: stdin$2, stdout: stdout$1, stderr, stdio = [
1208
+ stdin$2,
1209
+ stdout$1,
1210
+ stderr
1211
+ ], env: envOption, preferLocal, cwd: cwdOption = ".",...options }) => {
1212
+ const cwd = cwdOption instanceof URL ? fileURLToPath(cwdOption) : path.resolve(cwdOption);
1213
+ const env$2 = envOption ? {
1214
+ ...process$1.env,
1215
+ ...envOption
1216
+ } : void 0;
1217
+ const input = stdio[0]?.string;
1218
+ return {
1219
+ ...options,
1220
+ input,
1221
+ stdio: input === void 0 ? stdio : ["pipe", ...stdio.slice(1)],
1222
+ env: preferLocal ? addLocalPath(env$2 ?? process$1.env, cwd) : env$2,
1223
+ cwd
1224
+ };
1225
+ };
1226
+ const addLocalPath = ({ Path = "", PATH = Path,...env$2 }, cwd) => {
1227
+ const pathParts = PATH.split(path.delimiter);
1228
+ const localPaths = getLocalPaths([], path.resolve(cwd)).map((localPath) => path.join(localPath, "node_modules/.bin")).filter((localPath) => !pathParts.includes(localPath));
1229
+ return {
1230
+ ...env$2,
1231
+ PATH: [...localPaths, PATH].filter(Boolean).join(path.delimiter)
1232
+ };
1233
+ };
1234
+ const getLocalPaths = (localPaths, localPath) => localPaths.at(-1) === localPath ? localPaths : getLocalPaths([...localPaths, localPath], path.resolve(localPath, ".."));
1235
+ const applyForceShell = async (file, commandArguments, options) => await shouldForceShell(file, options) ? [
1236
+ escapeFile(file),
1237
+ commandArguments.map((argument) => escapeArgument(argument)),
1238
+ {
1239
+ ...options,
1240
+ shell: true
1241
+ }
1242
+ ] : [
1243
+ file,
1244
+ commandArguments,
1245
+ options
1246
+ ];
1247
+ const shouldForceShell = async (file, { shell, cwd, env: env$2 = process$1.env }) => process$1.platform === "win32" && !shell && !await isExe(file, cwd, env$2);
1248
+ const isExe = (file, cwd, { Path = "", PATH = Path }) => exeExtensions.some((extension) => file.toLowerCase().endsWith(extension)) || mIsExe(file, cwd, PATH);
1249
+ const EXE_MEMO = {};
1250
+ const memoize = (function_) => (...arguments_) => EXE_MEMO[arguments_.join("\0")] ??= function_(...arguments_);
1251
+ const access = memoize(a.access);
1252
+ const mIsExe = memoize(async (file, cwd, PATH) => {
1253
+ const parts = PATH.split(path.delimiter).filter(Boolean).map((part) => part.replace(/^"(.*)"$/, "$1"));
1254
+ try {
1255
+ await Promise.any([cwd, ...parts].flatMap((part) => exeExtensions.map((extension) => access(`${path.resolve(part, file)}${extension}`))));
1256
+ } catch {
1257
+ return false;
1258
+ }
1259
+ return true;
1260
+ });
1261
+ const exeExtensions = [".exe", ".com"];
1262
+ const escapeArgument = (argument) => escapeFile(escapeFile(`"${argument.replaceAll(/(\\*)"/g, "$1$1\\\"").replace(/(\\*)$/, "$1$1")}"`));
1263
+ const escapeFile = (file) => file.replaceAll(/([()\][%!^"`<>&|;, *?])/g, "^$1");
1264
+ const getResult = async (nodeChildProcess, { input }, context) => {
1265
+ const instance = await nodeChildProcess;
1266
+ if (input !== void 0) instance.stdin.end(input);
1267
+ const onClose = once(instance, "close");
1268
+ try {
1269
+ await Promise.race([onClose, ...instance.stdio.filter(Boolean).map((stream) => onStreamError(stream))]);
1270
+ checkFailure(context, getErrorOutput(instance));
1271
+ return getOutputs(context);
1272
+ } catch (error) {
1273
+ await Promise.allSettled([onClose]);
1274
+ throw getResultError(error, instance, context);
1275
+ }
1276
+ };
1277
+ const onStreamError = async (stream) => {
1278
+ for await (const [error] of on(stream, "error")) if (!["ERR_STREAM_PREMATURE_CLOSE", "EPIPE"].includes(error?.code)) throw error;
1279
+ };
1280
+ const checkFailure = ({ command }, { exitCode, signalName }) => {
1281
+ if (signalName !== void 0) throw new SubprocessError(`Command was terminated with ${signalName}: ${command}`);
1282
+ if (exitCode !== void 0) throw new SubprocessError(`Command failed with exit code ${exitCode}: ${command}`);
1283
+ };
1284
+ const getResultError = (error, instance, context) => Object.assign(getErrorInstance(error, context), getErrorOutput(instance), getOutputs(context));
1285
+ const getErrorInstance = (error, { command }) => error instanceof SubprocessError ? error : new SubprocessError(`Command failed: ${command}`, { cause: error });
1286
+ var SubprocessError = class extends Error {
1287
+ name = "SubprocessError";
1288
+ };
1289
+ const getErrorOutput = ({ exitCode, signalCode }) => ({
1290
+ ...exitCode < 1 ? {} : { exitCode },
1291
+ ...signalCode === null ? {} : { signalName: signalCode }
1292
+ });
1293
+ const getOutputs = ({ state: { stdout: stdout$1, stderr, output }, command, start }) => ({
1294
+ stdout: getOutput(stdout$1),
1295
+ stderr: getOutput(stderr),
1296
+ output: getOutput(output),
1297
+ command,
1298
+ durationMs: Number(process$1.hrtime.bigint() - start) / 1e6
1299
+ });
1300
+ const getOutput = (output) => output.at(-1) === "\n" ? output.slice(0, output.at(-2) === "\r" ? -2 : -1) : output;
1301
+ const spawnSubprocess = async (file, commandArguments, options, context) => {
1302
+ try {
1303
+ if (["node", "node.exe"].includes(file.toLowerCase())) {
1304
+ file = process$1.execPath;
1305
+ commandArguments = [...process$1.execArgv.filter((flag) => !flag.startsWith("--inspect")), ...commandArguments];
1306
+ }
1307
+ [file, commandArguments, options] = await applyForceShell(file, commandArguments, options);
1308
+ [file, commandArguments, options] = concatenateShell(file, commandArguments, options);
1309
+ const instance = spawn(file, commandArguments, options);
1310
+ bufferOutput(instance.stdout, context, "stdout");
1311
+ bufferOutput(instance.stderr, context, "stderr");
1312
+ instance.once("error", () => {});
1313
+ await once(instance, "spawn");
1314
+ return instance;
1315
+ } catch (error) {
1316
+ throw getResultError(error, {}, context);
1317
+ }
1318
+ };
1319
+ const concatenateShell = (file, commandArguments, options) => options.shell && commandArguments.length > 0 ? [
1320
+ [file, ...commandArguments].join(" "),
1321
+ [],
1322
+ options
1323
+ ] : [
1324
+ file,
1325
+ commandArguments,
1326
+ options
1327
+ ];
1328
+ const bufferOutput = (stream, { state }, streamName) => {
1329
+ if (stream) {
1330
+ stream.setEncoding("utf8");
1331
+ if (!state.isIterating) {
1332
+ state.isIterating = false;
1333
+ stream.on("data", (chunk) => {
1334
+ state[streamName] += chunk;
1335
+ state.output += chunk;
1336
+ });
1337
+ }
1338
+ }
1339
+ };
1340
+ const handlePipe = async (subprocesses) => {
1341
+ const [[from, to]] = await Promise.all([Promise.allSettled(subprocesses), pipeStreams(subprocesses)]);
1342
+ if (to.reason) {
1343
+ to.reason.pipedFrom = from.reason ?? from.value;
1344
+ throw to.reason;
1345
+ }
1346
+ if (from.reason) throw from.reason;
1347
+ return {
1348
+ ...to.value,
1349
+ pipedFrom: from.value
1350
+ };
1351
+ };
1352
+ const pipeStreams = async (subprocesses) => {
1353
+ try {
1354
+ const [{ stdout: stdout$1 }, { stdin: stdin$2 }] = await Promise.all(subprocesses.map(({ nodeChildProcess }) => nodeChildProcess));
1355
+ if (stdin$2 === null) throw new Error("The \"stdin\" option must be set on the first \"spawn()\" call in the pipeline.");
1356
+ if (stdout$1 === null) throw new Error("The \"stdout\" option must be set on the last \"spawn()\" call in the pipeline.");
1357
+ pipeline(stdout$1, stdin$2).catch(() => {});
1358
+ } catch (error) {
1359
+ await Promise.allSettled(subprocesses.map(({ nodeChildProcess }) => closeStdin(nodeChildProcess)));
1360
+ throw error;
1361
+ }
1362
+ };
1363
+ const closeStdin = async (nodeChildProcess) => {
1364
+ const { stdin: stdin$2 } = await nodeChildProcess;
1365
+ stdin$2.end();
1366
+ };
1367
+ const lineIterator = async function* (subprocess, { state }, streamName) {
1368
+ if (state.isIterating === false) throw new Error(`The subprocess must be iterated right away, for example:
1369
+ for await (const line of spawn(...)) { ... }`);
1370
+ state.isIterating = true;
1371
+ try {
1372
+ const { [streamName]: stream } = await subprocess.nodeChildProcess;
1373
+ if (!stream) return;
1374
+ yield* readline.createInterface({ input: stream });
1375
+ } finally {
1376
+ await subprocess;
1377
+ }
1378
+ };
1379
+ const combineAsyncIterators = async function* (...iterators) {
1380
+ try {
1381
+ let promises = [];
1382
+ while (iterators.length > 0) {
1383
+ promises = iterators.map((iterator$1, index$1) => promises[index$1] ?? getNext(iterator$1));
1384
+ const [{ value, done }, index] = await Promise.race(promises.map((promise, index$1) => Promise.all([promise, index$1])));
1385
+ const [iterator] = iterators.splice(index, 1);
1386
+ promises.splice(index, 1);
1387
+ if (!done) {
1388
+ iterators.push(iterator);
1389
+ yield value;
1390
+ }
1391
+ }
1392
+ } finally {
1393
+ await Promise.all(iterators.map((iterator) => iterator.return()));
1394
+ }
1395
+ };
1396
+ const getNext = async (iterator) => {
1397
+ try {
1398
+ return await iterator.next();
1399
+ } catch (error) {
1400
+ await iterator.throw(error);
1401
+ }
1402
+ };
1403
+ function spawn$1(file, second, third, previous) {
1404
+ const [commandArguments = [], options = {}] = Array.isArray(second) ? [second, third] : [[], second];
1405
+ const context = getContext([file, ...commandArguments]);
1406
+ const spawnOptions = getOptions(options);
1407
+ const nodeChildProcess = spawnSubprocess(file, commandArguments, spawnOptions, context);
1408
+ let subprocess = getResult(nodeChildProcess, spawnOptions, context);
1409
+ Object.assign(subprocess, { nodeChildProcess });
1410
+ subprocess = previous ? handlePipe([previous, subprocess]) : subprocess;
1411
+ const stdout$1 = lineIterator(subprocess, context, "stdout");
1412
+ const stderr = lineIterator(subprocess, context, "stderr");
1413
+ return Object.assign(subprocess, {
1414
+ nodeChildProcess,
1415
+ stdout: stdout$1,
1416
+ stderr,
1417
+ [Symbol.asyncIterator]: () => combineAsyncIterators(stdout$1, stderr),
1418
+ pipe: (file$1, second$1, third$1) => spawn$1(file$1, second$1, third$1, subprocess)
1419
+ });
1420
+ }
1421
+ /**
1422
+ * Process JSON data with a jq command
1423
+ * @param jsonData - The JSON data to process
1424
+ * @param jqCommand - The jq command/filter to apply
1425
+ * @returns The processed output from jq
1426
+ */
1427
+ async function processWithJq(jsonData, jqCommand) {
1428
+ const jsonString = JSON.stringify(jsonData);
1429
+ const result = try_({
1430
+ try: async () => {
1431
+ const spawnResult = await spawn$1("jq", [jqCommand], { stdin: { string: jsonString } });
1432
+ return spawnResult.output.trim();
1433
+ },
1434
+ catch: (error) => {
1435
+ if (error instanceof Error) {
1436
+ if (error.message.includes("ENOENT") || error.message.includes("not found")) return new Error("jq command not found. Please install jq to use the --jq option.");
1437
+ return new Error(`jq processing failed: ${error.message}`);
1438
+ }
1439
+ return new Error("Unknown error during jq processing");
1440
+ }
1441
+ });
1442
+ return result();
1443
+ }
1190
1444
  /**
1191
1445
  * Parses and validates a date argument in YYYYMMDD format
1192
1446
  * @param value - Date string to parse
@@ -1276,6 +1530,11 @@ const sharedArgs = {
1276
1530
  short: "l",
1277
1531
  description: "Locale for date/time formatting (e.g., en-US, ja-JP, de-DE)",
1278
1532
  default: "en-CA"
1533
+ },
1534
+ jq: {
1535
+ type: "string",
1536
+ short: "q",
1537
+ description: "Process JSON output with jq command (requires jq binary, implies --json)"
1279
1538
  }
1280
1539
  };
1281
1540
  /**
@@ -1392,10 +1651,10 @@ var require_utils = __commonJSMin((exports, module) => {
1392
1651
  return str;
1393
1652
  }
1394
1653
  let codeCache = {};
1395
- function addToCodeCache(name$1, on, off) {
1396
- on = "\x1B[" + on + "m";
1654
+ function addToCodeCache(name$1, on$1, off) {
1655
+ on$1 = "\x1B[" + on$1 + "m";
1397
1656
  off = "\x1B[" + off + "m";
1398
- codeCache[on] = {
1657
+ codeCache[on$1] = {
1399
1658
  set: name$1,
1400
1659
  to: true
1401
1660
  };
@@ -1404,7 +1663,7 @@ var require_utils = __commonJSMin((exports, module) => {
1404
1663
  to: false
1405
1664
  };
1406
1665
  codeCache[name$1] = {
1407
- on,
1666
+ on: on$1,
1408
1667
  off
1409
1668
  };
1410
1669
  }
@@ -4138,7 +4397,8 @@ const blocksCommand = define({
4138
4397
  },
4139
4398
  toKebab: true,
4140
4399
  async run(ctx) {
4141
- if (ctx.values.json) logger.level = 0;
4400
+ const useJson = ctx.values.json || ctx.values.jq != null;
4401
+ if (useJson) logger.level = 0;
4142
4402
  if (ctx.values.sessionLength <= 0) {
4143
4403
  logger.error("Session length must be a positive number");
4144
4404
  process$1.exit(1);
@@ -4154,7 +4414,7 @@ const blocksCommand = define({
4154
4414
  locale: ctx.values.locale
4155
4415
  });
4156
4416
  if (blocks.length === 0) {
4157
- if (ctx.values.json) log(JSON.stringify({ blocks: [] }));
4417
+ if (useJson) log(JSON.stringify({ blocks: [] }));
4158
4418
  else logger.warn("No Claude usage data found.");
4159
4419
  process$1.exit(0);
4160
4420
  }
@@ -4164,13 +4424,13 @@ const blocksCommand = define({
4164
4424
  const blockTokens = getTotalTokens(block.tokenCounts);
4165
4425
  if (blockTokens > maxTokensFromAll) maxTokensFromAll = blockTokens;
4166
4426
  }
4167
- if (!ctx.values.json && maxTokensFromAll > 0) logger.info(`Using max tokens from previous sessions: ${formatNumber(maxTokensFromAll)}`);
4427
+ if (!useJson && maxTokensFromAll > 0) logger.info(`Using max tokens from previous sessions: ${formatNumber(maxTokensFromAll)}`);
4168
4428
  }
4169
4429
  if (ctx.values.recent) blocks = filterRecentBlocks(blocks, DEFAULT_RECENT_DAYS);
4170
4430
  if (ctx.values.active) {
4171
4431
  blocks = blocks.filter((block) => block.isActive);
4172
4432
  if (blocks.length === 0) {
4173
- if (ctx.values.json) log(JSON.stringify({
4433
+ if (useJson) log(JSON.stringify({
4174
4434
  blocks: [],
4175
4435
  message: "No active block"
4176
4436
  }));
@@ -4178,7 +4438,7 @@ const blocksCommand = define({
4178
4438
  process$1.exit(0);
4179
4439
  }
4180
4440
  }
4181
- if (ctx.values.live && !ctx.values.json) {
4441
+ if (ctx.values.live && !useJson) {
4182
4442
  if (!ctx.values.active) logger.info("Live mode automatically shows only active blocks.");
4183
4443
  let tokenLimitValue = ctx.values.tokenLimit;
4184
4444
  if (tokenLimitValue == null || tokenLimitValue === "") {
@@ -4202,7 +4462,7 @@ const blocksCommand = define({
4202
4462
  });
4203
4463
  return;
4204
4464
  }
4205
- if (ctx.values.json) {
4465
+ if (useJson) {
4206
4466
  const jsonOutput = { blocks: blocks.map((block) => {
4207
4467
  const burnRate = block.isActive ? calculateBurnRate(block) : null;
4208
4468
  const projection = block.isActive ? projectBlockUsage(block) : null;
@@ -4232,7 +4492,14 @@ const blocksCommand = define({
4232
4492
  usageLimitResetTime: block.usageLimitResetTime
4233
4493
  };
4234
4494
  }) };
4235
- log(JSON.stringify(jsonOutput, null, 2));
4495
+ if (ctx.values.jq != null) {
4496
+ const jqResult = await processWithJq(jsonOutput, ctx.values.jq);
4497
+ if (isFailure(jqResult)) {
4498
+ logger.error(jqResult.error.message);
4499
+ process$1.exit(1);
4500
+ }
4501
+ log(jqResult.value);
4502
+ } else log(JSON.stringify(jsonOutput, null, 2));
4236
4503
  } else if (ctx.values.active && blocks.length === 1) {
4237
4504
  const block = blocks[0];
4238
4505
  if (block == null) {
@@ -4533,7 +4800,8 @@ const dailyCommand = define({
4533
4800
  }
4534
4801
  },
4535
4802
  async run(ctx) {
4536
- if (ctx.values.json) logger.level = 0;
4803
+ const useJson = ctx.values.json || ctx.values.jq != null;
4804
+ if (useJson) logger.level = 0;
4537
4805
  const dailyData = await loadDailyUsageData({
4538
4806
  since: ctx.values.since,
4539
4807
  until: ctx.values.until,
@@ -4546,16 +4814,16 @@ const dailyCommand = define({
4546
4814
  locale: ctx.values.locale
4547
4815
  });
4548
4816
  if (dailyData.length === 0) {
4549
- if (ctx.values.json) log(JSON.stringify([]));
4817
+ if (useJson) log(JSON.stringify([]));
4550
4818
  else logger.warn("No Claude usage data found.");
4551
4819
  process$1.exit(0);
4552
4820
  }
4553
4821
  const totals = calculateTotals(dailyData);
4554
- if (ctx.values.debug && !ctx.values.json) {
4822
+ if (ctx.values.debug && !useJson) {
4555
4823
  const mismatchStats = await detectMismatches(void 0);
4556
4824
  printMismatchReport(mismatchStats, ctx.values.debugSamples);
4557
4825
  }
4558
- if (ctx.values.json) {
4826
+ if (useJson) {
4559
4827
  const jsonOutput = ctx.values.instances && dailyData.some((d) => d.project != null) ? {
4560
4828
  projects: groupByProject(dailyData),
4561
4829
  totals: createTotalsObject(totals)
@@ -4574,7 +4842,14 @@ const dailyCommand = define({
4574
4842
  })),
4575
4843
  totals: createTotalsObject(totals)
4576
4844
  };
4577
- log(JSON.stringify(jsonOutput, null, 2));
4845
+ if (ctx.values.jq != null) {
4846
+ const jqResult = await processWithJq(jsonOutput, ctx.values.jq);
4847
+ if (isFailure(jqResult)) {
4848
+ logger.error(jqResult.error.message);
4849
+ process$1.exit(1);
4850
+ }
4851
+ log(jqResult.value);
4852
+ } else log(JSON.stringify(jsonOutput, null, 2));
4578
4853
  } else {
4579
4854
  logger.box("Claude Code Token Usage Report - Daily");
4580
4855
  const table = new ResponsiveTable({
@@ -5176,7 +5451,8 @@ const monthlyCommand = define({
5176
5451
  description: "Show usage report grouped by month",
5177
5452
  ...sharedCommandConfig,
5178
5453
  async run(ctx) {
5179
- if (ctx.values.json) logger.level = 0;
5454
+ const useJson = ctx.values.json || ctx.values.jq != null;
5455
+ if (useJson) logger.level = 0;
5180
5456
  const monthlyData = await loadMonthlyUsageData({
5181
5457
  since: ctx.values.since,
5182
5458
  until: ctx.values.until,
@@ -5187,7 +5463,7 @@ const monthlyCommand = define({
5187
5463
  locale: ctx.values.locale
5188
5464
  });
5189
5465
  if (monthlyData.length === 0) {
5190
- if (ctx.values.json) {
5466
+ if (useJson) {
5191
5467
  const emptyOutput = {
5192
5468
  monthly: [],
5193
5469
  totals: {
@@ -5204,11 +5480,11 @@ const monthlyCommand = define({
5204
5480
  process$1.exit(0);
5205
5481
  }
5206
5482
  const totals = calculateTotals(monthlyData);
5207
- if (ctx.values.debug && !ctx.values.json) {
5483
+ if (ctx.values.debug && !useJson) {
5208
5484
  const mismatchStats = await detectMismatches(void 0);
5209
5485
  printMismatchReport(mismatchStats, ctx.values.debugSamples);
5210
5486
  }
5211
- if (ctx.values.json) {
5487
+ if (useJson) {
5212
5488
  const jsonOutput = {
5213
5489
  monthly: monthlyData.map((data) => ({
5214
5490
  month: data.month,
@@ -5223,7 +5499,14 @@ const monthlyCommand = define({
5223
5499
  })),
5224
5500
  totals: createTotalsObject(totals)
5225
5501
  };
5226
- log(JSON.stringify(jsonOutput, null, 2));
5502
+ if (ctx.values.jq != null) {
5503
+ const jqResult = await processWithJq(jsonOutput, ctx.values.jq);
5504
+ if (isFailure(jqResult)) {
5505
+ logger.error(jqResult.error.message);
5506
+ process$1.exit(1);
5507
+ }
5508
+ log(jqResult.value);
5509
+ } else log(JSON.stringify(jsonOutput, null, 2));
5227
5510
  } else {
5228
5511
  logger.box("Claude Code Token Usage Report - Monthly");
5229
5512
  const table = new ResponsiveTable({
@@ -5312,7 +5595,8 @@ const sessionCommand = define({
5312
5595
  description: "Show usage report grouped by conversation session",
5313
5596
  ...sharedCommandConfig,
5314
5597
  async run(ctx) {
5315
- if (ctx.values.json) logger.level = 0;
5598
+ const useJson = ctx.values.json || ctx.values.jq != null;
5599
+ if (useJson) logger.level = 0;
5316
5600
  const sessionData = await loadSessionData({
5317
5601
  since: ctx.values.since,
5318
5602
  until: ctx.values.until,
@@ -5323,16 +5607,16 @@ const sessionCommand = define({
5323
5607
  locale: ctx.values.locale
5324
5608
  });
5325
5609
  if (sessionData.length === 0) {
5326
- if (ctx.values.json) log(JSON.stringify([]));
5610
+ if (useJson) log(JSON.stringify([]));
5327
5611
  else logger.warn("No Claude usage data found.");
5328
5612
  process$1.exit(0);
5329
5613
  }
5330
5614
  const totals = calculateTotals(sessionData);
5331
- if (ctx.values.debug && !ctx.values.json) {
5615
+ if (ctx.values.debug && !useJson) {
5332
5616
  const mismatchStats = await detectMismatches(void 0);
5333
5617
  printMismatchReport(mismatchStats, ctx.values.debugSamples);
5334
5618
  }
5335
- if (ctx.values.json) {
5619
+ if (useJson) {
5336
5620
  const jsonOutput = {
5337
5621
  sessions: sessionData.map((data) => ({
5338
5622
  sessionId: data.sessionId,
@@ -5349,7 +5633,14 @@ const sessionCommand = define({
5349
5633
  })),
5350
5634
  totals: createTotalsObject(totals)
5351
5635
  };
5352
- log(JSON.stringify(jsonOutput, null, 2));
5636
+ if (ctx.values.jq != null) {
5637
+ const jqResult = await processWithJq(jsonOutput, ctx.values.jq);
5638
+ if (isFailure(jqResult)) {
5639
+ logger.error(jqResult.error.message);
5640
+ process$1.exit(1);
5641
+ }
5642
+ log(jqResult.value);
5643
+ } else log(JSON.stringify(jsonOutput, null, 2));
5353
5644
  } else {
5354
5645
  logger.box("Claude Code Token Usage Report - By Session");
5355
5646
  const table = new ResponsiveTable({
@@ -5476,8 +5767,11 @@ function formatRemainingTime(remaining) {
5476
5767
  const statuslineCommand = define({
5477
5768
  name: "statusline",
5478
5769
  description: "Display compact status line for Claude Code hooks (Beta)",
5479
- args: {},
5480
- async run() {
5770
+ args: { offline: {
5771
+ ...sharedArgs.offline,
5772
+ default: true
5773
+ } },
5774
+ async run(ctx) {
5481
5775
  logger.level = 0;
5482
5776
  const stdin$2 = await getStdin();
5483
5777
  if (stdin$2.length === 0) {
@@ -5499,19 +5793,23 @@ const statuslineCommand = define({
5499
5793
  const sessionId = hookData.session_id;
5500
5794
  let sessionCost = null;
5501
5795
  try {
5502
- const sessionData = await loadSessionUsageById(sessionId, { mode: "auto" });
5796
+ const sessionData = await loadSessionUsageById(sessionId, {
5797
+ mode: "auto",
5798
+ offline: ctx.values.offline
5799
+ });
5503
5800
  if (sessionData != null) sessionCost = sessionData.totalCost;
5504
5801
  } catch (error) {
5505
5802
  logger.error("Failed to load session data:", error);
5506
5803
  }
5507
5804
  const today = new Date();
5508
- const todayStr = today.toISOString().split("T")[0];
5805
+ const todayStr = today.toISOString().split("T")[0]?.replace(/-/g, "") ?? "";
5509
5806
  let todayCost = 0;
5510
5807
  try {
5511
5808
  const dailyData = await loadDailyUsageData({
5512
5809
  since: todayStr,
5513
5810
  until: todayStr,
5514
- mode: "auto"
5811
+ mode: "auto",
5812
+ offline: ctx.values.offline
5515
5813
  });
5516
5814
  if (dailyData.length > 0) {
5517
5815
  const totals = calculateTotals(dailyData);
@@ -5523,7 +5821,10 @@ const statuslineCommand = define({
5523
5821
  let blockInfo = "";
5524
5822
  let burnRateInfo = "";
5525
5823
  try {
5526
- const blocks = await loadSessionBlockData({ mode: "auto" });
5824
+ const blocks = await loadSessionBlockData({
5825
+ mode: "auto",
5826
+ offline: ctx.values.offline
5827
+ });
5527
5828
  if (blocks.length === 0) blockInfo = "No active block";
5528
5829
  else {
5529
5830
  const activeBlock = blocks.find((block) => {
@@ -5573,7 +5874,8 @@ const weeklyCommand = define({
5573
5874
  },
5574
5875
  toKebab: true,
5575
5876
  async run(ctx) {
5576
- if (ctx.values.json) logger.level = 0;
5877
+ const useJson = ctx.values.json || ctx.values.jq != null;
5878
+ if (useJson) logger.level = 0;
5577
5879
  const weeklyData = await loadWeeklyUsageData({
5578
5880
  since: ctx.values.since,
5579
5881
  until: ctx.values.until,
@@ -5585,7 +5887,7 @@ const weeklyCommand = define({
5585
5887
  locale: ctx.values.locale
5586
5888
  });
5587
5889
  if (weeklyData.length === 0) {
5588
- if (ctx.values.json) {
5890
+ if (useJson) {
5589
5891
  const emptyOutput = {
5590
5892
  weekly: [],
5591
5893
  totals: {
@@ -5602,11 +5904,11 @@ const weeklyCommand = define({
5602
5904
  process$1.exit(0);
5603
5905
  }
5604
5906
  const totals = calculateTotals(weeklyData);
5605
- if (ctx.values.debug && !ctx.values.json) {
5907
+ if (ctx.values.debug && !useJson) {
5606
5908
  const mismatchStats = await detectMismatches(void 0);
5607
5909
  printMismatchReport(mismatchStats, ctx.values.debugSamples);
5608
5910
  }
5609
- if (ctx.values.json) {
5911
+ if (useJson) {
5610
5912
  const jsonOutput = {
5611
5913
  weekly: weeklyData.map((data) => ({
5612
5914
  week: data.week,
@@ -5621,7 +5923,14 @@ const weeklyCommand = define({
5621
5923
  })),
5622
5924
  totals: createTotalsObject(totals)
5623
5925
  };
5624
- log(JSON.stringify(jsonOutput, null, 2));
5926
+ if (ctx.values.jq != null) {
5927
+ const jqResult = await processWithJq(jsonOutput, ctx.values.jq);
5928
+ if (isFailure(jqResult)) {
5929
+ logger.error(jqResult.error.message);
5930
+ process$1.exit(1);
5931
+ }
5932
+ log(jqResult.value);
5933
+ } else log(JSON.stringify(jsonOutput, null, 2));
5625
5934
  } else {
5626
5935
  logger.box("Claude Code Token Usage Report - Weekly");
5627
5936
  const table = new ResponsiveTable({
@@ -951,7 +951,7 @@ function _getDefaultLogLevel() {
951
951
  }
952
952
  const consola = createConsola();
953
953
  var name = "ccusage";
954
- var version = "15.9.0";
954
+ var version = "15.9.2";
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-DxuNm8GV.js";
1
+ import { log, logger } from "./logger-BrRa0CCy.js";
2
2
  export { log, logger };
@@ -1,9 +1,9 @@
1
- import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-S0o3dB03.js";
1
+ import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-DXFi0Cxk.js";
2
2
  import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
3
3
  import { ZodFirstPartyTypeKind, ZodOptional, ZodType, arrayType, booleanType, discriminatedUnionType, enumType, filterDateSchema, literalType, numberType, objectType, optionalType, recordType, stringType, unionType, unknownType } from "./_types-B-1t4mxD.js";
4
4
  import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
5
- import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-CKAeM9ir.js";
6
- import { name, version } from "./logger-DxuNm8GV.js";
5
+ import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-KL1zbb-w.js";
6
+ import { name, version } from "./logger-BrRa0CCy.js";
7
7
  import process from "node:process";
8
8
  const LATEST_PROTOCOL_VERSION = "2025-06-18";
9
9
  const SUPPORTED_PROTOCOL_VERSIONS = [
package/dist/mcp.js CHANGED
@@ -1,8 +1,8 @@
1
- import "./pricing-fetcher-S0o3dB03.js";
1
+ import "./pricing-fetcher-DXFi0Cxk.js";
2
2
  import "./_token-utils-WjkbrjKv.js";
3
3
  import "./_types-B-1t4mxD.js";
4
4
  import "./calculate-cost-BDqO4yWA.js";
5
- import "./data-loader-CKAeM9ir.js";
6
- import "./logger-DxuNm8GV.js";
7
- import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-pA-Z7D2o.js";
5
+ import "./data-loader-KL1zbb-w.js";
6
+ import "./logger-BrRa0CCy.js";
7
+ import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-BBhsgnNL.js";
8
8
  export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
@@ -1,5 +1,5 @@
1
1
  import { modelPricingSchema } from "./_types-B-1t4mxD.js";
2
- import { logger } from "./logger-DxuNm8GV.js";
2
+ import { logger } from "./logger-BrRa0CCy.js";
3
3
  import { createRequire } from "node:module";
4
4
  import path from "node:path";
5
5
  import F, { homedir } from "node:os";
@@ -1,4 +1,4 @@
1
- import { PricingFetcher } from "./pricing-fetcher-S0o3dB03.js";
1
+ import { PricingFetcher } from "./pricing-fetcher-DXFi0Cxk.js";
2
2
  import "./_types-B-1t4mxD.js";
3
- import "./logger-DxuNm8GV.js";
3
+ import "./logger-BrRa0CCy.js";
4
4
  export { PricingFetcher };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccusage",
3
- "version": "15.9.0",
3
+ "version": "15.9.2",
4
4
  "description": "Usage analysis tool for Claude Code",
5
5
  "homepage": "https://github.com/ryoppippi/ccusage#readme",
6
6
  "bugs": {