ccusage
Version:
Usage analysis tool for Claude Code
1,278 lines • 129 kB
JavaScript
#!/usr/bin/env node
import { $ as DEFAULT_RECENT_DAYS, B as pushBreakdownRows, D as calculateBurnRate, E as DEFAULT_SESSION_DURATION_HOURS, F as formatDateCompact, G as BLOCKS_COMPACT_WIDTH_THRESHOLD, H as getFileModifiedTime, I as formatModelsDisplayMultiline, K as BLOCKS_DEFAULT_TERMINAL_WIDTH, L as formatNumber, M as addEmptySeparatorRow, N as createUsageReportTable, O as filterRecentBlocks, P as formatCurrency, Q as DEFAULT_LOCALE, R as formatTotalsRow, U as unreachable, V as require_picocolors, W as _usingCtx, Y as CONFIG_FILE_NAME, Z as DEFAULT_CONTEXT_USAGE_THRESHOLDS, _ as loadWeeklyUsageData, at as try_, ct as inspectError, dt as isSuccess, et as DEFAULT_REFRESH_INTERVAL_SECONDS, f as loadDailyUsageData, ft as isFailure, g as loadSessionUsageById, h as loadSessionData, it as unwrap, j as ResponsiveTable, k as projectBlockUsage, lt as inspect, m as loadSessionBlockData, mt as __toESM, n as calculateContextTokens, nt as WEEK_DAYS, ot as pipe, p as loadMonthlyUsageData, pt as toArray, q as BLOCKS_WARNING_THRESHOLD, s as getClaudePaths, st as map$1, ut as succeed, z as formatUsageDataRow } from "./data-loader-B58Zt4YE.js";
import { B as getTotalTokens, D as maxValue, E as integer$1, F as safeParse, I as string, L as transform, M as parse$1, O as minValue, P as pipe$1, R as trim, T as flatten, d as filterDateSchema, k as number, n as SortOrders, t as CostModes, w as check, y as statuslineHookJsonSchema, z as union } from "./_types-DY3gqCWm.js";
import { n as createTotalsObject, t as calculateTotals } from "./calculate-cost-DWGfKMSD.js";
import { a as version, i as name, n as logger, r as description, t as log } from "./logger-TGVysPie.js";
import { n as printMismatchReport, t as detectMismatches } from "./debug-0PxspX9a.js";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import a from "node:fs/promises";
import path, { join } from "node:path";
import process$1 from "node:process";
import { tmpdir } from "node:os";
import { fileURLToPath } from "node:url";
import { stripVTControlCharacters } from "node:util";
import { spawn } from "node:child_process";
import { on, once } from "node:events";
import { pipeline } from "node:stream/promises";
import * as readline from "node:readline/promises";
const DEFAULT_LOCALE$1 = "en-US";
const BUILT_IN_PREFIX = "_";
const ARG_PREFIX = "arg";
const BUILT_IN_KEY_SEPARATOR = ":";
const ANONYMOUS_COMMAND_NAME = "(anonymous)";
const NOOP = () => {};
const COMMON_ARGS = {
help: {
type: "boolean",
short: "h",
description: "Display this help message"
},
version: {
type: "boolean",
short: "v",
description: "Display this version"
}
};
const COMMAND_OPTIONS_DEFAULT = {
name: void 0,
description: void 0,
version: void 0,
cwd: void 0,
usageSilent: false,
subCommands: void 0,
leftMargin: 2,
middleMargin: 10,
usageOptionType: false,
usageOptionValue: true,
renderHeader: void 0,
renderUsage: void 0,
renderValidationErrors: void 0,
translationAdapterFactory: void 0
};
function isLazyCommand(cmd) {
return typeof cmd === "function" && "commandName" in cmd && !!cmd.commandName;
}
async function resolveLazyCommand(cmd, name$1, needRunResolving = false) {
let command;
if (isLazyCommand(cmd)) {
command = Object.assign(create(), {
name: cmd.commandName,
description: cmd.description,
args: cmd.args,
examples: cmd.examples,
resource: cmd.resource
});
if (needRunResolving) {
const loaded = await cmd();
if (typeof loaded === "function") command.run = loaded;
else if (typeof loaded === "object") {
if (loaded.run == null) throw new TypeError(`'run' is required in command: ${cmd.name || name$1}`);
command.run = loaded.run;
command.name = loaded.name;
command.description = loaded.description;
command.args = loaded.args;
command.examples = loaded.examples;
command.resource = loaded.resource;
} else throw new TypeError(`Cannot resolve command: ${cmd.name || name$1}`);
}
} else command = Object.assign(create(), cmd);
if (command.name == null && name$1) command.name = name$1;
return deepFreeze(command);
}
function resolveBuiltInKey(key) {
return `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
}
function resolveArgKey(key) {
return `${ARG_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
}
async function resolveExamples(ctx, examples) {
return typeof examples === "string" ? examples : typeof examples === "function" ? await examples(ctx) : "";
}
function mapResourceWithBuiltinKey(resource) {
return Object.entries(resource).reduce((acc, [key, value$1]) => {
acc[resolveBuiltInKey(key)] = value$1;
return acc;
}, create());
}
function create(obj = null) {
return Object.create(obj);
}
function log$1(...args) {
console.log(...args);
}
function deepFreeze(obj) {
if (obj === null || typeof obj !== "object") return obj;
for (const key of Object.keys(obj)) {
const value$1 = obj[key];
if (typeof value$1 === "object" && value$1 !== null) deepFreeze(value$1);
}
return Object.freeze(obj);
}
var en_US_default = {
COMMAND: "COMMAND",
COMMANDS: "COMMANDS",
SUBCOMMAND: "SUBCOMMAND",
USAGE: "USAGE",
ARGUMENTS: "ARGUMENTS",
OPTIONS: "OPTIONS",
EXAMPLES: "EXAMPLES",
FORMORE: "For more info, run any command with the `--help` flag:",
NEGATABLE: "Negatable of",
DEFAULT: "default",
CHOICES: "choices",
help: "Display this help message",
version: "Display this version"
};
function createTranslationAdapter(options) {
return new DefaultTranslation(options);
}
var DefaultTranslation = class {
#resources = /* @__PURE__ */ new Map();
#options;
constructor(options) {
this.#options = options;
this.#resources.set(options.locale, create());
if (options.locale !== options.fallbackLocale) this.#resources.set(options.fallbackLocale, create());
}
getResource(locale) {
return this.#resources.get(locale);
}
setResource(locale, resource) {
this.#resources.set(locale, resource);
}
getMessage(locale, key) {
const resource = this.getResource(locale);
if (resource) return resource[key];
}
translate(locale, key, values = create()) {
let message = this.getMessage(locale, key);
if (message === void 0 && locale !== this.#options.fallbackLocale) message = this.getMessage(this.#options.fallbackLocale, key);
if (message === void 0) return;
return message.replaceAll(/\{\{(\w+)\}\}/g, (_$1, name$1) => {
return values[name$1] == null ? "" : values[name$1].toString();
});
}
};
const BUILT_IN_PREFIX_CODE = BUILT_IN_PREFIX.codePointAt(0);
async function createCommandContext({ args, values, positionals, rest, argv, tokens, command, cliOptions, callMode = "entry", omitted = false }) {
const _args = Object.entries(args).reduce((acc, [key, value$1]) => {
acc[key] = Object.assign(create(), value$1);
return acc;
}, create());
const env = Object.assign(create(), COMMAND_OPTIONS_DEFAULT, cliOptions);
const locale = resolveLocale(cliOptions.locale);
const localeStr = locale.toString();
const adapter = (cliOptions.translationAdapterFactory || createTranslationAdapter)({
locale: localeStr,
fallbackLocale: DEFAULT_LOCALE$1
});
const localeResources = /* @__PURE__ */ new Map();
let builtInLoadedResources;
localeResources.set(DEFAULT_LOCALE$1, mapResourceWithBuiltinKey(en_US_default));
if (DEFAULT_LOCALE$1 !== localeStr) try {
builtInLoadedResources = (await import(`./locales/${localeStr}.json`, { with: { type: "json" } })).default;
localeResources.set(localeStr, mapResourceWithBuiltinKey(builtInLoadedResources));
} catch {}
function translate(key, values$1 = create()) {
const strKey = key;
if (strKey.codePointAt(0) === BUILT_IN_PREFIX_CODE) return (localeResources.get(localeStr) || localeResources.get(DEFAULT_LOCALE$1))[strKey] || strKey;
else return adapter.translate(locale.toString(), strKey, values$1) || "";
}
let cachedCommands;
async function loadCommands() {
if (cachedCommands) return cachedCommands;
const subCommands$1 = [...cliOptions.subCommands || []];
return cachedCommands = await Promise.all(subCommands$1.map(async ([name$1, cmd]) => await resolveLazyCommand(cmd, name$1)));
}
const ctx = deepFreeze(Object.assign(create(), {
name: getCommandName(command),
description: command.description,
omitted,
callMode,
locale,
env,
args: _args,
values,
positionals,
rest,
_: argv,
tokens,
toKebab: command.toKebab,
log: cliOptions.usageSilent ? NOOP : log$1,
loadCommands,
translate
}));
const defaultCommandResource = Object.entries(args).map(([key, arg]) => {
return [key, arg.description || ""];
}).reduce((res, [key, value$1]) => {
res[resolveArgKey(key)] = value$1;
return res;
}, create());
defaultCommandResource.description = command.description || "";
defaultCommandResource.examples = await resolveExamples(ctx, command.examples);
adapter.setResource(DEFAULT_LOCALE$1, defaultCommandResource);
const originalResource = await loadCommandResource(ctx, command);
if (originalResource) {
const resource = Object.assign(create(), originalResource, { examples: await resolveExamples(ctx, originalResource.examples) });
if (builtInLoadedResources) {
resource.help = builtInLoadedResources.help;
resource.version = builtInLoadedResources.version;
}
adapter.setResource(localeStr, resource);
}
return ctx;
}
function getCommandName(cmd) {
if (isLazyCommand(cmd)) return cmd.commandName || cmd.name || ANONYMOUS_COMMAND_NAME;
else if (typeof cmd === "object") return cmd.name || ANONYMOUS_COMMAND_NAME;
else return ANONYMOUS_COMMAND_NAME;
}
function resolveLocale(locale) {
return locale instanceof Intl.Locale ? locale : typeof locale === "string" ? new Intl.Locale(locale) : new Intl.Locale(DEFAULT_LOCALE$1);
}
async function loadCommandResource(ctx, command) {
let resource;
try {
resource = await command.resource?.(ctx);
} catch {}
return resource;
}
function define(definition) {
return definition;
}
/**
* @author kazuya kawaguchi (a.k.a. kazupon)
* @license MIT
*/
function kebabnize(str$1) {
return str$1.replace(/[A-Z]/g, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase());
}
function renderHeader(ctx) {
const title = ctx.env.description || ctx.env.name || "";
return Promise.resolve(title ? `${title} (${ctx.env.name || ""}${ctx.env.version ? ` v${ctx.env.version}` : ""})` : title);
}
const COMMON_ARGS_KEYS = Object.keys(COMMON_ARGS);
async function renderUsage(ctx) {
const messages = [];
if (!ctx.omitted) {
const description$1 = resolveDescription(ctx);
if (description$1) messages.push(description$1, "");
}
messages.push(...await renderUsageSection(ctx), "");
if (ctx.omitted && await hasCommands(ctx)) messages.push(...await renderCommandsSection(ctx), "");
if (hasPositionalArgs(ctx)) messages.push(...await renderPositionalArgsSection(ctx), "");
if (hasOptionalArgs(ctx)) messages.push(...await renderOptionalArgsSection(ctx), "");
const examples = await renderExamplesSection(ctx);
if (examples.length > 0) messages.push(...examples, "");
return messages.join("\n");
}
async function renderPositionalArgsSection(ctx) {
const messages = [];
messages.push(`${ctx.translate(resolveBuiltInKey("ARGUMENTS"))}:`);
messages.push(await generatePositionalArgsUsage(ctx));
return messages;
}
async function renderOptionalArgsSection(ctx) {
const messages = [];
messages.push(`${ctx.translate(resolveBuiltInKey("OPTIONS"))}:`);
messages.push(await generateOptionalArgsUsage(ctx, getOptionalArgsPairs(ctx)));
return messages;
}
async function renderExamplesSection(ctx) {
const messages = [];
const resolvedExamples = await resolveExamples$1(ctx);
if (resolvedExamples) {
const examples = resolvedExamples.split("\n").map((example) => example.padStart(ctx.env.leftMargin + example.length));
messages.push(`${ctx.translate(resolveBuiltInKey("EXAMPLES"))}:`, ...examples);
}
return messages;
}
async function renderUsageSection(ctx) {
const messages = [`${ctx.translate(resolveBuiltInKey("USAGE"))}:`];
if (ctx.omitted) {
const defaultCommand = `${resolveEntry(ctx)}${await hasCommands(ctx) ? ` [${resolveSubCommand(ctx)}]` : ""} ${[generateOptionsSymbols(ctx), generatePositionalSymbols(ctx)].filter(Boolean).join(" ")}`;
messages.push(defaultCommand.padStart(ctx.env.leftMargin + defaultCommand.length));
if (await hasCommands(ctx)) {
const commandsUsage = `${resolveEntry(ctx)} <${ctx.translate(resolveBuiltInKey("COMMANDS"))}>`;
messages.push(commandsUsage.padStart(ctx.env.leftMargin + commandsUsage.length));
}
} else {
const usageStr = `${resolveEntry(ctx)} ${resolveSubCommand(ctx)} ${[generateOptionsSymbols(ctx), generatePositionalSymbols(ctx)].filter(Boolean).join(" ")}`;
messages.push(usageStr.padStart(ctx.env.leftMargin + usageStr.length));
}
return messages;
}
async function renderCommandsSection(ctx) {
const messages = [`${ctx.translate(resolveBuiltInKey("COMMANDS"))}:`];
const loadedCommands = await ctx.loadCommands();
const commandMaxLength = Math.max(...loadedCommands.map((cmd) => (cmd.name || "").length));
const commandsStr = await Promise.all(loadedCommands.map((cmd) => {
const key = cmd.name || "";
const desc = cmd.description || "";
const command = `${key.padEnd(commandMaxLength + ctx.env.middleMargin)}${desc} `;
return `${command.padStart(ctx.env.leftMargin + command.length)} `;
}));
messages.push(...commandsStr, "", ctx.translate(resolveBuiltInKey("FORMORE")));
messages.push(...loadedCommands.map((cmd) => {
const commandHelp = `${ctx.env.name} ${cmd.name} --help`;
return `${commandHelp.padStart(ctx.env.leftMargin + commandHelp.length)}`;
}));
return messages;
}
function resolveEntry(ctx) {
return ctx.env.name || ctx.translate(resolveBuiltInKey("COMMAND"));
}
function resolveSubCommand(ctx) {
return ctx.name || ctx.translate(resolveBuiltInKey("SUBCOMMAND"));
}
function resolveDescription(ctx) {
return ctx.translate("description") || ctx.description || "";
}
async function resolveExamples$1(ctx) {
const ret = ctx.translate("examples");
if (ret) return ret;
const command = ctx.env.subCommands?.get(ctx.name || "");
return await resolveExamples(ctx, command?.examples);
}
async function hasCommands(ctx) {
return (await ctx.loadCommands()).length > 1;
}
function hasOptionalArgs(ctx) {
return !!(ctx.args && Object.values(ctx.args).some((arg) => arg.type !== "positional"));
}
function hasPositionalArgs(ctx) {
return !!(ctx.args && Object.values(ctx.args).some((arg) => arg.type === "positional"));
}
function hasAllDefaultOptions(ctx) {
return !!(ctx.args && Object.values(ctx.args).every((arg) => arg.default));
}
function generateOptionsSymbols(ctx) {
return hasOptionalArgs(ctx) ? hasAllDefaultOptions(ctx) ? `[${ctx.translate(resolveBuiltInKey("OPTIONS"))}]` : `<${ctx.translate(resolveBuiltInKey("OPTIONS"))}>` : "";
}
function makeShortLongOptionPair(schema, name$1, toKebab) {
let key = `--${toKebab || schema.toKebab ? kebabnize(name$1) : name$1}`;
if (schema.short) key = `-${schema.short}, ${key}`;
return key;
}
function getOptionalArgsPairs(ctx) {
return Object.entries(ctx.args).reduce((acc, [name$1, schema]) => {
if (schema.type === "positional") return acc;
let key = makeShortLongOptionPair(schema, name$1, ctx.toKebab);
if (schema.type !== "boolean") {
const displayName = ctx.toKebab || schema.toKebab ? kebabnize(name$1) : name$1;
key = schema.default ? `${key} [${displayName}]` : `${key} <${displayName}>`;
}
acc[name$1] = key;
if (schema.type === "boolean" && schema.negatable && !COMMON_ARGS_KEYS.includes(name$1)) {
const displayName = ctx.toKebab || schema.toKebab ? kebabnize(name$1) : name$1;
acc[`no-${name$1}`] = `--no-${displayName}`;
}
return acc;
}, create());
}
const resolveNegatableKey = (key) => key.split("no-")[1];
function resolveNegatableType(key, ctx) {
return ctx.args[key.startsWith("no-") ? resolveNegatableKey(key) : key].type;
}
function generateDefaultDisplayValue(ctx, schema) {
return `${ctx.translate(resolveBuiltInKey("DEFAULT"))}: ${schema.default}`;
}
function resolveDisplayValue(ctx, key) {
if (COMMON_ARGS_KEYS.includes(key)) return "";
const schema = ctx.args[key];
if ((schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "custom") && schema.default !== void 0) return `(${generateDefaultDisplayValue(ctx, schema)})`;
if (schema.type === "enum") {
const _default = schema.default !== void 0 ? generateDefaultDisplayValue(ctx, schema) : "";
const choices = `${ctx.translate(resolveBuiltInKey("CHOICES"))}: ${schema.choices.join(" | ")}`;
return `(${_default ? `${_default}, ${choices}` : choices})`;
}
return "";
}
async function generateOptionalArgsUsage(ctx, optionsPairs) {
const optionsMaxLength = Math.max(...Object.entries(optionsPairs).map(([_$1, value$1]) => value$1.length));
const optionSchemaMaxLength = ctx.env.usageOptionType ? Math.max(...Object.entries(optionsPairs).map(([key]) => resolveNegatableType(key, ctx).length)) : 0;
return (await Promise.all(Object.entries(optionsPairs).map(([key, value$1]) => {
let rawDesc = ctx.translate(resolveArgKey(key));
if (!rawDesc && key.startsWith("no-")) {
const name$1 = resolveNegatableKey(key);
const schema = ctx.args[name$1];
const optionKey = makeShortLongOptionPair(schema, name$1, ctx.toKebab);
rawDesc = `${ctx.translate(resolveBuiltInKey("NEGATABLE"))} ${optionKey}`;
}
const optionsSchema = ctx.env.usageOptionType ? `[${resolveNegatableType(key, ctx)}] ` : "";
const valueDesc = key.startsWith("no-") ? "" : resolveDisplayValue(ctx, key);
const desc = `${optionsSchema ? optionsSchema.padEnd(optionSchemaMaxLength + 3) : ""}${rawDesc}`;
const option = `${value$1.padEnd(optionsMaxLength + ctx.env.middleMargin)}${desc}${valueDesc ? ` ${valueDesc}` : ""}`;
return `${option.padStart(ctx.env.leftMargin + option.length)}`;
}))).join("\n");
}
function getPositionalArgs(ctx) {
return Object.entries(ctx.args).filter(([_$1, schema]) => schema.type === "positional");
}
async function generatePositionalArgsUsage(ctx) {
const positionals = getPositionalArgs(ctx);
const argsMaxLength = Math.max(...positionals.map(([name$1]) => name$1.length));
return (await Promise.all(positionals.map(([name$1]) => {
const desc = ctx.translate(resolveArgKey(name$1)) || ctx.args[name$1].description || "";
const arg = `${name$1.padEnd(argsMaxLength + ctx.env.middleMargin)} ${desc}`;
return `${arg.padStart(ctx.env.leftMargin + arg.length)}`;
}))).join("\n");
}
function generatePositionalSymbols(ctx) {
return hasPositionalArgs(ctx) ? getPositionalArgs(ctx).map(([name$1]) => `<${name$1}>`).join(" ") : "";
}
function renderValidationErrors(_ctx, error) {
const messages = [];
for (const err of error.errors) messages.push(err.message);
return Promise.resolve(messages.join("\n"));
}
const HYPHEN_CHAR = "-";
const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
const EQUAL_CHAR = "=";
const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
const TERMINATOR = "--";
const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
const LONG_OPTION_PREFIX = "--";
function parseArgs(args, options = {}) {
const { allowCompatible = false } = options;
const tokens = [];
const remainings = [...args];
let index = -1;
let groupCount = 0;
let hasShortValueSeparator = false;
while (remainings.length > 0) {
const arg = remainings.shift();
if (arg == void 0) break;
const nextArg = remainings[0];
if (groupCount > 0) groupCount--;
else index++;
if (arg === TERMINATOR) {
tokens.push({
kind: "option-terminator",
index
});
const mapped = remainings.map((arg$1) => {
return {
kind: "positional",
index: ++index,
value: arg$1
};
});
tokens.push(...mapped);
break;
}
if (isShortOption(arg)) {
const shortOption = arg.charAt(1);
let value$1;
let inlineValue;
if (groupCount) {
tokens.push({
kind: "option",
name: shortOption,
rawName: arg,
index,
value: value$1,
inlineValue
});
if (groupCount === 1 && hasOptionValue(nextArg)) {
value$1 = remainings.shift();
if (hasShortValueSeparator) {
inlineValue = true;
hasShortValueSeparator = false;
}
tokens.push({
kind: "option",
index,
value: value$1,
inlineValue
});
}
} else tokens.push({
kind: "option",
name: shortOption,
rawName: arg,
index,
value: value$1,
inlineValue
});
if (value$1 != null) ++index;
continue;
}
if (isShortOptionGroup(arg)) {
const expanded = [];
let shortValue = "";
for (let i = 1; i < arg.length; i++) {
const shortableOption = arg.charAt(i);
if (hasShortValueSeparator) shortValue += shortableOption;
else if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE) hasShortValueSeparator = true;
else expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
}
if (shortValue) expanded.push(shortValue);
remainings.unshift(...expanded);
groupCount = expanded.length;
continue;
}
if (isLongOption(arg)) {
const longOption = arg.slice(2);
tokens.push({
kind: "option",
name: longOption,
rawName: arg,
index,
value: void 0,
inlineValue: void 0
});
continue;
}
if (isLongOptionAndValue(arg)) {
const equalIndex = arg.indexOf(EQUAL_CHAR);
const longOption = arg.slice(2, equalIndex);
const value$1 = arg.slice(equalIndex + 1);
tokens.push({
kind: "option",
name: longOption,
rawName: `${LONG_OPTION_PREFIX}${longOption}`,
index,
value: value$1,
inlineValue: true
});
continue;
}
tokens.push({
kind: "positional",
index,
value: arg
});
}
return tokens;
}
function isShortOption(arg) {
return arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE;
}
function isShortOptionGroup(arg) {
if (arg.length <= 2) return false;
if (arg.codePointAt(0) !== HYPHEN_CODE) return false;
if (arg.codePointAt(1) === HYPHEN_CODE) return false;
return true;
}
function isLongOption(arg) {
return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
}
function isLongOptionAndValue(arg) {
return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
}
function hasLongOptionPrefix(arg) {
return arg.length > 2 && ~arg.indexOf(LONG_OPTION_PREFIX);
}
function hasOptionValue(value$1) {
return !(value$1 == null) && value$1.codePointAt(0) !== HYPHEN_CODE;
}
const SKIP_POSITIONAL_DEFAULT = -1;
function resolveArgs(args, tokens, { shortGrouping = false, skipPositional = SKIP_POSITIONAL_DEFAULT, toKebab = false } = {}) {
const skipPositionalIndex = typeof skipPositional === "number" ? Math.max(skipPositional, SKIP_POSITIONAL_DEFAULT) : SKIP_POSITIONAL_DEFAULT;
const rest = [];
const optionTokens = [];
const positionalTokens = [];
let currentLongOption;
let currentShortOption;
const expandableShortOptions = [];
function toShortValue() {
if (expandableShortOptions.length === 0) return void 0;
else {
const value$1 = expandableShortOptions.map((token) => token.name).join("");
expandableShortOptions.length = 0;
return value$1;
}
}
function applyLongOptionValue(value$1 = void 0) {
if (currentLongOption) {
currentLongOption.value = value$1;
optionTokens.push({ ...currentLongOption });
currentLongOption = void 0;
}
}
function applyShortOptionValue(value$1 = void 0) {
if (currentShortOption) {
currentShortOption.value = value$1 || toShortValue();
optionTokens.push({ ...currentShortOption });
currentShortOption = void 0;
}
}
const schemas = Object.values(args);
let terminated = false;
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
if (token.kind === "positional") {
if (terminated && token.value) {
rest.push(token.value);
continue;
}
if (currentShortOption) {
if (schemas.find((schema) => schema.short === currentShortOption.name && schema.type === "boolean")) positionalTokens.push({ ...token });
} else if (currentLongOption) {
if (args[currentLongOption.name]?.type === "boolean") positionalTokens.push({ ...token });
} else positionalTokens.push({ ...token });
applyLongOptionValue(token.value);
applyShortOptionValue(token.value);
} else if (token.kind === "option") if (token.rawName) {
if (hasLongOptionPrefix(token.rawName)) {
applyLongOptionValue();
if (token.inlineValue) optionTokens.push({ ...token });
else currentLongOption = { ...token };
applyShortOptionValue();
} else if (isShortOption(token.rawName)) if (currentShortOption) {
if (currentShortOption.index === token.index) if (shortGrouping) {
currentShortOption.value = token.value;
optionTokens.push({ ...currentShortOption });
currentShortOption = { ...token };
} else expandableShortOptions.push({ ...token });
else {
currentShortOption.value = toShortValue();
optionTokens.push({ ...currentShortOption });
currentShortOption = { ...token };
}
applyLongOptionValue();
} else {
currentShortOption = { ...token };
applyLongOptionValue();
}
} else {
if (currentShortOption && currentShortOption.index == token.index && token.inlineValue) {
currentShortOption.value = token.value;
optionTokens.push({ ...currentShortOption });
currentShortOption = void 0;
}
applyLongOptionValue();
}
else {
if (token.kind === "option-terminator") terminated = true;
applyLongOptionValue();
applyShortOptionValue();
}
}
applyLongOptionValue();
applyShortOptionValue();
const values = Object.create(null);
const errors = [];
function checkTokenName(option, schema, token) {
return token.name === (schema.type === "boolean" ? schema.negatable && token.name?.startsWith("no-") ? `no-${option}` : option : option);
}
const positionalItemCount = tokens.filter((token) => token.kind === "positional").length;
function getPositionalSkipIndex() {
return Math.min(skipPositionalIndex, positionalItemCount);
}
let positionalsCount = 0;
for (const [rawArg, schema] of Object.entries(args)) {
const arg = toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
if (schema.required) {
if (!optionTokens.find((token) => {
return schema.short && token.name === schema.short || token.rawName && hasLongOptionPrefix(token.rawName) && token.name === arg;
})) {
errors.push(createRequireError(arg, schema));
continue;
}
}
if (schema.type === "positional") {
if (skipPositionalIndex > SKIP_POSITIONAL_DEFAULT) while (positionalsCount <= getPositionalSkipIndex()) positionalsCount++;
const positional = positionalTokens[positionalsCount];
if (positional != null) values[rawArg] = positional.value;
else errors.push(createRequireError(arg, schema));
positionalsCount++;
continue;
}
for (let i = 0; i < optionTokens.length; i++) {
const token = optionTokens[i];
if (checkTokenName(arg, schema, token) && token.rawName != void 0 && hasLongOptionPrefix(token.rawName) || schema.short === token.name && token.rawName != void 0 && isShortOption(token.rawName)) {
const invalid = validateRequire(token, arg, schema);
if (invalid) {
errors.push(invalid);
continue;
}
if (schema.type === "boolean") token.value = void 0;
const [parsedValue, error] = parse(token, arg, schema);
if (error) errors.push(error);
else if (schema.multiple) {
values[rawArg] ||= [];
values[rawArg].push(parsedValue);
} else values[rawArg] = parsedValue;
}
}
if (values[rawArg] == null && schema.default != null) values[rawArg] = schema.default;
}
return {
values,
positionals: positionalTokens.map((token) => token.value),
rest,
error: errors.length > 0 ? new AggregateError(errors) : void 0
};
}
function parse(token, option, schema) {
switch (schema.type) {
case "string": return typeof token.value === "string" ? [token.value || schema.default, void 0] : [void 0, createTypeError(option, schema)];
case "boolean": return token.value ? [token.value || schema.default, void 0] : [!(schema.negatable && token.name.startsWith("no-")), void 0];
case "number":
if (!isNumeric(token.value)) return [void 0, createTypeError(option, schema)];
return token.value ? [+token.value, void 0] : [+(schema.default || ""), void 0];
case "enum":
if (schema.choices && !schema.choices.includes(token.value)) return [void 0, new ArgResolveError(`Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}should be chosen from '${schema.type}' [${schema.choices.map((c) => JSON.stringify(c)).join(", ")}] values`, option, "type", schema)];
return [token.value || schema.default, void 0];
case "custom":
if (typeof schema.parse !== "function") throw new TypeError(`argument '${option}' should have a 'parse' function`);
try {
return [schema.parse(token.value || String(schema.default || "")), void 0];
} catch (error) {
return [void 0, error];
}
default: throw new Error(`Unsupported argument type '${schema.type}' for option '${option}'`);
}
}
function createRequireError(option, schema) {
return new ArgResolveError(schema.type === "positional" ? `Positional argument '${option}' is required` : `Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}is required`, option, "required", schema);
}
var ArgResolveError = class extends Error {
name;
schema;
type;
constructor(message, name$1, type, schema) {
super(message);
this.name = name$1;
this.type = type;
this.schema = schema;
}
};
function validateRequire(token, option, schema) {
if (schema.required && schema.type !== "boolean" && !token.value) return createRequireError(option, schema);
}
function isNumeric(str$1) {
return str$1.trim() !== "" && !isNaN(str$1);
}
function createTypeError(option, schema) {
return new ArgResolveError(`Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}should be '${schema.type}'`, option, "type", schema);
}
async function cli(argv, entry, options = {}) {
const cliOptions = resolveCliOptions(options, entry);
const tokens = parseArgs(argv);
const subCommand = getSubCommand(tokens);
const { commandName: name$1, command, callMode } = await resolveCommand(subCommand, entry, cliOptions);
if (!command) throw new Error(`Command not found: ${name$1 || ""}`);
const args = resolveArguments(getCommandArgs(command));
const { values, positionals, rest, error } = resolveArgs(args, tokens, {
shortGrouping: true,
toKebab: command.toKebab,
skipPositional: cliOptions.subCommands.size > 0 ? 0 : -1
});
const ctx = await createCommandContext({
args,
values,
positionals,
rest,
argv,
tokens,
omitted: !subCommand,
callMode,
command,
cliOptions
});
if (values.version) {
showVersion(ctx);
return;
}
const usageBuffer = [];
const header = await showHeader(ctx);
if (header) usageBuffer.push(header);
if (values.help) {
const usage = await showUsage(ctx);
if (usage) usageBuffer.push(usage);
return usageBuffer.join("\n");
}
if (error) {
await showValidationErrors(ctx, error);
return;
}
await executeCommand(command, ctx, name$1 || "");
}
function getCommandArgs(cmd) {
if (isLazyCommand(cmd)) return cmd.args || create();
else if (typeof cmd === "object") return cmd.args || create();
else return create();
}
function resolveArguments(args) {
return Object.assign(create(), args, COMMON_ARGS);
}
function resolveCliOptions(options, entry) {
const subCommands$1 = new Map(options.subCommands);
if (options.subCommands) {
if (isLazyCommand(entry)) subCommands$1.set(entry.commandName, entry);
else if (typeof entry === "object" && entry.name) subCommands$1.set(entry.name, entry);
}
return Object.assign(create(), COMMAND_OPTIONS_DEFAULT, options, { subCommands: subCommands$1 });
}
function getSubCommand(tokens) {
const firstToken = tokens[0];
return firstToken && firstToken.kind === "positional" && firstToken.index === 0 && firstToken.value ? firstToken.value : "";
}
async function showUsage(ctx) {
if (ctx.env.renderUsage === null) return;
const usage = await (ctx.env.renderUsage || renderUsage)(ctx);
if (usage) {
ctx.log(usage);
return usage;
}
}
function showVersion(ctx) {
ctx.log(ctx.env.version);
}
async function showHeader(ctx) {
if (ctx.env.renderHeader === null) return;
const header = await (ctx.env.renderHeader || renderHeader)(ctx);
if (header) {
ctx.log(header);
ctx.log();
return header;
}
}
async function showValidationErrors(ctx, error) {
if (ctx.env.renderValidationErrors === null) return;
const render = ctx.env.renderValidationErrors || renderValidationErrors;
ctx.log(await render(ctx, error));
}
const CANNOT_RESOLVE_COMMAND = { callMode: "unexpected" };
async function resolveCommand(sub, entry, options) {
const omitted = !sub;
async function doResolveCommand() {
if (typeof entry === "function") if ("commandName" in entry && entry.commandName) return {
commandName: entry.commandName,
command: entry,
callMode: "entry"
};
else return {
command: { run: entry },
callMode: "entry"
};
else if (typeof entry === "object") return {
commandName: resolveEntryName(entry),
command: entry,
callMode: "entry"
};
else return CANNOT_RESOLVE_COMMAND;
}
if (omitted || options.subCommands?.size === 0) return doResolveCommand();
const cmd = options.subCommands?.get(sub);
if (cmd == null) return {
commandName: sub,
callMode: "unexpected"
};
if (isLazyCommand(cmd) && cmd.commandName == null) cmd.commandName = sub;
else if (typeof cmd === "object" && cmd.name == null) cmd.name = sub;
return {
commandName: sub,
command: cmd,
callMode: "subCommand"
};
}
function resolveEntryName(entry) {
return entry.name || ANONYMOUS_COMMAND_NAME;
}
async function executeCommand(cmd, ctx, name$1) {
const resolved = isLazyCommand(cmd) ? await resolveLazyCommand(cmd, name$1, true) : cmd;
if (resolved.run == null) throw new Error(`'run' not found on Command \`${name$1}\``);
await resolved.run(ctx);
}
var import_picocolors$2 = /* @__PURE__ */ __toESM(require_picocolors(), 1);
function extractExplicitArgs(tokens) {
const explicit = {};
for (const token of tokens) if (typeof token === "object" && token !== null) {
const t = token;
if (t.kind === "option" && typeof t.name === "string") explicit[t.name] = true;
}
return explicit;
}
function getConfigSearchPaths() {
return [join(process$1.cwd(), ".ccusage"), ...toArray(getClaudePaths())].map((dir) => join(dir, CONFIG_FILE_NAME));
}
function validateConfigJson(data) {
if (typeof data !== "object" || data === null) return false;
const config = data;
if (config.$schema != null && typeof config.$schema !== "string") return false;
if (config.defaults != null && (typeof config.defaults !== "object" || config.defaults === null)) return false;
if (config.commands != null && (typeof config.commands !== "object" || config.commands === null)) return false;
return true;
}
function loadConfigFile(filePath, debug = false) {
if (!existsSync(filePath)) {
if (debug) logger.info(` • Checking: ${filePath} (not found)`);
return;
}
return pipe(try_({
try: () => {
const content = readFileSync(filePath, "utf-8");
const data = JSON.parse(content);
if (!validateConfigJson(data)) throw new Error("Invalid configuration structure");
data.source = filePath;
return data;
},
catch: (error) => error
})(), inspect(() => {
logger.debug(`Parsed configuration file: ${filePath}`);
if (debug) logger.info(` • Checking: ${filePath} (found ✓)`);
}), inspectError((error) => {
const errorMessage = error instanceof Error ? error.message : String(error);
logger.warn(`Error parsing configuration file at ${filePath}: ${errorMessage}`);
if (debug) logger.info(` • Checking: ${filePath} (error: ${errorMessage})`);
}), unwrap(void 0));
}
function loadConfig(configPath, debug = false) {
if (debug) logger.info("Debug mode enabled - showing config loading details\n");
if (configPath != null) {
if (debug) {
logger.info("Using specified config file:");
logger.info(` • Path: ${configPath}`);
}
const config = loadConfigFile(configPath, debug);
if (config == null) logger.warn(`Configuration file not found or invalid: ${configPath}`);
else if (debug) {
logger.info("");
logger.info(`Loaded config from: ${configPath}`);
logger.info(` • Schema: ${config.$schema ?? "none"}`);
logger.info(` • Has defaults: ${config.defaults != null ? "yes" : "no"}${config.defaults != null ? ` (${Object.keys(config.defaults).length} options)` : ""}`);
logger.info(` • Has command configs: ${config.commands != null ? "yes" : "no"}${config.commands != null ? ` (${Object.keys(config.commands).join(", ")})` : ""}`);
}
return config;
}
if (debug) logger.info("Searching for config files:");
for (const searchPath of getConfigSearchPaths()) {
const config = loadConfigFile(searchPath, debug);
if (config != null) {
if (debug) {
logger.info("");
logger.info(`Loaded config from: ${searchPath}`);
logger.info(` • Schema: ${config.$schema ?? "none"}`);
logger.info(` • Has defaults: ${config.defaults != null ? "yes" : "no"}${config.defaults != null ? ` (${Object.keys(config.defaults).length} options)` : ""}`);
logger.info(` • Has command configs: ${config.commands != null ? "yes" : "no"}${config.commands != null ? ` (${Object.keys(config.commands).join(", ")})` : ""}`);
}
return config;
}
}
logger.debug("No valid configuration file found");
if (debug) {
logger.info("");
logger.info("No valid configuration file found");
}
}
function mergeConfigWithArgs(ctx, config, debug = false) {
if (config == null) {
if (debug) {
logger.info("");
logger.info(`No config file loaded, using CLI args only for '${ctx.name ?? "unknown"}' command`);
}
return ctx.values;
}
const merged = {};
const commandName = ctx.name;
const sources = {};
if (config.defaults != null) for (const [key, value$1] of Object.entries(config.defaults)) {
merged[key] = value$1;
sources[key] = "defaults";
}
if (commandName != null && config.commands?.[commandName] != null) for (const [key, value$1] of Object.entries(config.commands[commandName])) {
merged[key] = value$1;
sources[key] = "command config";
}
const explicit = extractExplicitArgs(ctx.tokens);
for (const [key, value$1] of Object.entries(ctx.values)) if (value$1 != null && explicit[key] === true) {
merged[key] = value$1;
sources[key] = "CLI";
}
logger.debug(`Merged config for ${commandName ?? "unknown"}:`, merged);
if (debug) {
logger.info("");
logger.info(`Merging options for '${commandName ?? "unknown"}' command:`);
const bySource = {
defaults: [],
"command config": [],
CLI: []
};
for (const [key, source] of Object.entries(sources)) if (bySource[source] != null) bySource[source].push(`${key}=${JSON.stringify(merged[key])}`);
if (bySource.defaults.length > 0) logger.info(` • From defaults: ${bySource.defaults.join(", ")}`);
if (bySource["command config"].length > 0) logger.info(` • From command config: ${bySource["command config"].join(", ")}`);
if (bySource.CLI.length > 0) logger.info(` • From CLI args: ${bySource.CLI.join(", ")}`);
logger.info(" • Final merged options: {");
for (const [key, value$1] of Object.entries(merged)) {
const source = sources[key] ?? "unknown";
logger.info(` ${key}: ${JSON.stringify(value$1)} (from ${source}),`);
}
logger.info(" }");
}
return merged;
}
const getContext = (raw) => ({
start: process$1.hrtime.bigint(),
command: raw.map((part) => getCommandPart(stripVTControlCharacters(part))).join(" "),
state: {
stdout: "",
stderr: "",
output: ""
}
});
const getCommandPart = (part) => /[^\w./-]/.test(part) ? `'${part.replaceAll("'", "'\\''")}'` : part;
const getOptions = ({ stdin: stdin$2, stdout: stdout$1, stderr, stdio = [
stdin$2,
stdout$1,
stderr
], env: envOption, preferLocal, cwd: cwdOption = ".", ...options }) => {
const cwd = cwdOption instanceof URL ? fileURLToPath(cwdOption) : path.resolve(cwdOption);
const env = envOption ? {
...process$1.env,
...envOption
} : void 0;
const input = stdio[0]?.string;
return {
...options,
input,
stdio: input === void 0 ? stdio : ["pipe", ...stdio.slice(1)],
env: preferLocal ? addLocalPath(env ?? process$1.env, cwd) : env,
cwd
};
};
const addLocalPath = ({ Path = "", PATH = Path, ...env }, cwd) => {
const pathParts = PATH.split(path.delimiter);
const localPaths = getLocalPaths([], path.resolve(cwd)).map((localPath) => path.join(localPath, "node_modules/.bin")).filter((localPath) => !pathParts.includes(localPath));
return {
...env,
PATH: [...localPaths, PATH].filter(Boolean).join(path.delimiter)
};
};
const getLocalPaths = (localPaths, localPath) => localPaths.at(-1) === localPath ? localPaths : getLocalPaths([...localPaths, localPath], path.resolve(localPath, ".."));
const applyForceShell = async (file, commandArguments, options) => await shouldForceShell(file, options) ? [
escapeFile(file),
commandArguments.map((argument) => escapeArgument(argument)),
{
...options,
shell: true
}
] : [
file,
commandArguments,
options
];
const shouldForceShell = async (file, { shell, cwd, env = process$1.env }) => process$1.platform === "win32" && !shell && !await isExe(file, cwd, env);
const isExe = (file, cwd, { Path = "", PATH = Path }) => exeExtensions.some((extension) => file.toLowerCase().endsWith(extension)) || mIsExe(file, cwd, PATH);
const EXE_MEMO = {};
const memoize = (function_) => (...arguments_) => EXE_MEMO[arguments_.join("\0")] ??= function_(...arguments_);
const access = memoize(a.access);
const mIsExe = memoize(async (file, cwd, PATH) => {
const parts = PATH.split(path.delimiter).filter(Boolean).map((part) => part.replace(/^"(.*)"$/, "$1"));
try {
await Promise.any([cwd, ...parts].flatMap((part) => exeExtensions.map((extension) => access(`${path.resolve(part, file)}${extension}`))));
} catch {
return false;
}
return true;
});
const exeExtensions = [".exe", ".com"];
const escapeArgument = (argument) => escapeFile(escapeFile(`"${argument.replaceAll(/(\\*)"/g, "$1$1\\\"").replace(/(\\*)$/, "$1$1")}"`));
const escapeFile = (file) => file.replaceAll(/([()\][%!^"`<>&|;, *?])/g, "^$1");
const getResult = async (nodeChildProcess, { input }, context) => {
const instance = await nodeChildProcess;
if (input !== void 0) instance.stdin.end(input);
const onClose = once(instance, "close");
try {
await Promise.race([onClose, ...instance.stdio.filter(Boolean).map((stream) => onStreamError(stream))]);
checkFailure(context, getErrorOutput(instance));
return getOutputs(context);
} catch (error) {
await Promise.allSettled([onClose]);
throw getResultError(error, instance, context);
}
};
const onStreamError = async (stream) => {
for await (const [error] of on(stream, "error")) if (!["ERR_STREAM_PREMATURE_CLOSE", "EPIPE"].includes(error?.code)) throw error;
};
const checkFailure = ({ command }, { exitCode, signalName }) => {
if (signalName !== void 0) throw new SubprocessError(`Command was terminated with ${signalName}: ${command}`);
if (exitCode !== void 0) throw new SubprocessError(`Command failed with exit code ${exitCode}: ${command}`);
};
const getResultError = (error, instance, context) => Object.assign(getErrorInstance(error, context), getErrorOutput(instance), getOutputs(context));
const getErrorInstance = (error, { command }) => error instanceof SubprocessError ? error : new SubprocessError(`Command failed: ${command}`, { cause: error });
var SubprocessError = class extends Error {
name = "SubprocessError";
};
const getErrorOutput = ({ exitCode, signalCode }) => ({
...exitCode < 1 ? {} : { exitCode },
...signalCode === null ? {} : { signalName: signalCode }
});
const getOutputs = ({ state: { stdout: stdout$1, stderr, output }, command, start }) => ({
stdout: getOutput(stdout$1),
stderr: getOutput(stderr),
output: getOutput(output),
command,
durationMs: Number(process$1.hrtime.bigint() - start) / 1e6
});
const getOutput = (output) => output.at(-1) === "\n" ? output.slice(0, output.at(-2) === "\r" ? -2 : -1) : output;
const spawnSubprocess = async (file, commandArguments, options, context) => {
try {
if (["node", "node.exe"].includes(file.toLowerCase())) {
file = process$1.execPath;
commandArguments = [...process$1.execArgv.filter((flag) => !flag.startsWith("--inspect")), ...commandArguments];
}
[file, commandArguments, options] = await applyForceShell(file, commandArguments, options);
[file, commandArguments, options] = concatenateShell(file, commandArguments, options);
const instance = spawn(file, commandArguments, options);
bufferOutput(instance.stdout, context, "stdout");
bufferOutput(instance.stderr, context, "stderr");
instance.once("error", () => {});
await once(instance, "spawn");
return instance;
} catch (error) {
throw getResultError(error, {}, context);
}
};
const concatenateShell = (file, commandArguments, options) => options.shell && commandArguments.length > 0 ? [
[file, ...commandArguments].join(" "),
[],
options
] : [
file,
commandArguments,
options
];
const bufferOutput = (stream, { state }, streamName) => {
if (stream) {
stream.setEncoding("utf8");
if (!state.isIterating) {
state.isIterating = false;
stream.on("data", (chunk) => {
state[streamName] += chunk;
state.output += chunk;
});
}
}
};
const handlePipe = async (subprocesses) => {
const [[from, to]] = await Promise.all([Promise.allSettled(subprocesses), pipeStreams(subprocesses)]);
if (to.reason) {
to.reason.pipedFrom = from.reason ?? from.value;
throw to.reason;
}
if (from.reason) throw from.reason;
return {
...to.value,
pipedFrom: from.value
};
};
const pipeStreams = async (subprocesses) => {
try {
const [{ stdout: stdout$1 }, { stdin: stdin$2 }] = await Promise.all(subprocesses.map(({ nodeChildProcess }) => nodeChildProcess));
if (stdin$2 === null) throw new Error("The \"stdin\" option must be set on the first \"spawn()\" call in the pipeline.");
if (stdout$1 === null) throw new Error("The \"stdout\" option must be set on the last \"spawn()\" call in the pipeline.");
pipeline(stdout$1, stdin$2).catch(() => {});
} catch (error) {
await Promise.allSettled(subprocesses.map(({ nodeChildProcess }) => closeStdin(nodeChildProcess)));
throw error;
}
};
const closeStdin = async (nodeChildProcess) => {
const { stdin: stdin$2 } = await nodeChildProcess;
stdin$2.end();
};
const lineIterator = async function* (subprocess, { state }, streamName) {
if (state.isIterating === false) throw new Error(`The subprocess must be iterated right away, for example:
for await (const line of spawn(...)) { ... }`);
state.isIterating = true;
try {
const { [streamName]: stream } = await subprocess.nodeChildProcess;
if (!stream) return;
handleErrors(subprocess);
yield* readline.createInterface({ input: stream });
} finally {
await subprocess;
}
};
const handleErrors = async (subprocess) => {
try {
await subprocess;
} catch {}
};
const combineAsyncIterators = async function* (...iterators) {
try {
let promises = [];
while (iterators.length > 0) {
promises = iterators.map((iterator$1, index$1) => promises[index$1] ?? getNext(iterator$1));
const [{ value: value$1, done }, index] = await Promise.race(promises.map((promise, index$1) => Promise.all([promise, index$1])));
const [iterator] = iterators.splice(index, 1);
promises.splice(index, 1);
if (!done) {
iterators.push(iterator);
yield value$1;
}
}
} finally {
await Promise.all(iterators.map((iterator) => iterator.return()));
}
};
const getNext = async (iterator) => {
try {
return await iterator.next();
} catch (error) {
await iterator.throw(error);
}
};
function spawn$1(file, second, third, previous) {
const [commandArguments = [], options = {}] = Array.isArray(second) ? [second, third] : [[], second];
const context = getContext([file, ...commandArguments]);
const spawnOptions = getOptions(options);
const nodeChildProcess = spawnSubprocess(file, commandArguments, spawnOptions, context);
let subprocess = getResult(nodeChildProcess, spawnOptions, context);
Object.assign(subprocess, { nodeChildProcess });
subprocess = previous ? handlePipe([previous, subprocess]) : subprocess;
const stdout$1 = lineIterator(subprocess, context, "stdout");
const stderr = lineIterator(subprocess, context, "stderr");
return Object.assign(subprocess, {
nodeChildProcess,
stdout: stdout$1,
stderr,
[Symbol.asyncIterator]: () => combineAsyncIterators(stdout$1, stderr),
pipe: (file$1, second$1, third$1) => spawn$1(file$1, second$1, third$1, subprocess)
});
}
async function processWithJq(jsonData, jqCommand) {
const jsonString = JSON.stringify(jsonData);
return try_({
try: async () => {
return (await spawn$1("jq", [jqCommand], { stdin: { string: jsonString } })).output.trim();
},
catch: (error) => {
if (error instanceof Error) {
if (error.message.includes("ENOENT") || error.message.includes("not found")) return /* @__PURE__ */ new Error("jq command not found. Please install jq to use the --jq option.");
return /* @__PURE__ */ new Error(`jq processing failed: ${error.message}`);
}
return /* @__PURE__ */ new Error("Unknown error during jq processing");
}
})();
}
function parseDateArg(value$1) {
return parse$1(filterDateSchema, value$1);
}
const sharedArgs = {
since: {
type: "custom",
short: "s",
description: "Filter from date (YYYYMMDD format)",
parse: parseDateArg
},
until: {
type: "custom",
short: "u",
description: "Filter until date (YYYYMMDD format)",
parse: parseDateArg
},
json: {
type: "boolean",
short: "j",
description: "Output in JSON format",
default: false
},
mode: {
type: "enum",
short: "m",
description: "Cost calculation mode: auto (use costUSD if exists, otherwise calculate), calculate (always calculate), display (always use