ccusage 16.1.1 → 16.2.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/config-schema.json +24 -0
- package/dist/{_types-BbEk8t2a.js → _types-DIdtMJ6V.js} +31 -3
- package/dist/calculate-cost.d.ts +1 -1
- package/dist/calculate-cost.js +1 -1
- package/dist/{data-loader-BR0q3F1S.js → data-loader-C7KK9Yu0.js} +4 -21
- package/dist/{data-loader--Ga8BPdt.d.ts → data-loader-DewcQaMm.d.ts} +1 -11
- package/dist/data-loader.d.ts +2 -2
- package/dist/data-loader.js +5 -5
- package/dist/{debug-eBOoUv_j.js → debug-BOv8jTQu.js} +3 -3
- package/dist/debug.js +5 -5
- package/dist/index.js +249 -85
- package/dist/{logger-4mOJMzU6.js → logger-DKCIi_ai.js} +1 -1
- package/dist/logger.js +1 -1
- package/dist/{mcp-BsLzYwL8.js → mcp-DDHqWuGb.js} +4 -4
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +5 -5
- package/dist/{pricing-fetcher-_0Pbb-06.js → pricing-fetcher-CoBMgxFA.js} +7 -7
- package/dist/pricing-fetcher.js +3 -3
- package/package.json +1 -1
package/config-schema.json
CHANGED
|
@@ -721,6 +721,18 @@
|
|
|
721
721
|
"markdownDescription": "Controls the visualization of the burn rate status",
|
|
722
722
|
"default": "off"
|
|
723
723
|
},
|
|
724
|
+
"costSource": {
|
|
725
|
+
"type": "string",
|
|
726
|
+
"enum": [
|
|
727
|
+
"auto",
|
|
728
|
+
"ccusage",
|
|
729
|
+
"cc",
|
|
730
|
+
"both"
|
|
731
|
+
],
|
|
732
|
+
"description": "Session cost source: auto (prefer CC then ccusage), ccusage (always calculate), cc (always use Claude Code cost), both (show both costs)",
|
|
733
|
+
"markdownDescription": "Session cost source: auto (prefer CC then ccusage), ccusage (always calculate), cc (always use Claude Code cost), both (show both costs)",
|
|
734
|
+
"default": "auto"
|
|
735
|
+
},
|
|
724
736
|
"cache": {
|
|
725
737
|
"type": "boolean",
|
|
726
738
|
"description": "Enable cache for status line output (default: true)",
|
|
@@ -733,6 +745,18 @@
|
|
|
733
745
|
"markdownDescription": "Refresh interval in seconds for cache expiry (default: 1)",
|
|
734
746
|
"default": 1
|
|
735
747
|
},
|
|
748
|
+
"contextLowThreshold": {
|
|
749
|
+
"type": "string",
|
|
750
|
+
"description": "Context usage percentage below which status is shown in green (0-100)",
|
|
751
|
+
"markdownDescription": "Context usage percentage below which status is shown in green (0-100)",
|
|
752
|
+
"default": 50
|
|
753
|
+
},
|
|
754
|
+
"contextMediumThreshold": {
|
|
755
|
+
"type": "string",
|
|
756
|
+
"description": "Context usage percentage below which status is shown in yellow (0-100)",
|
|
757
|
+
"markdownDescription": "Context usage percentage below which status is shown in yellow (0-100)",
|
|
758
|
+
"default": 80
|
|
759
|
+
},
|
|
736
760
|
"debug": {
|
|
737
761
|
"type": "boolean",
|
|
738
762
|
"description": "Show pricing mismatch information for debugging",
|
|
@@ -3015,7 +3015,28 @@ var ZodFirstPartyTypeKind;
|
|
|
3015
3015
|
(function(ZodFirstPartyTypeKind$1) {
|
|
3016
3016
|
ZodFirstPartyTypeKind$1["ZodString"] = "ZodString", ZodFirstPartyTypeKind$1["ZodNumber"] = "ZodNumber", ZodFirstPartyTypeKind$1["ZodNaN"] = "ZodNaN", ZodFirstPartyTypeKind$1["ZodBigInt"] = "ZodBigInt", ZodFirstPartyTypeKind$1["ZodBoolean"] = "ZodBoolean", ZodFirstPartyTypeKind$1["ZodDate"] = "ZodDate", ZodFirstPartyTypeKind$1["ZodSymbol"] = "ZodSymbol", ZodFirstPartyTypeKind$1["ZodUndefined"] = "ZodUndefined", ZodFirstPartyTypeKind$1["ZodNull"] = "ZodNull", ZodFirstPartyTypeKind$1["ZodAny"] = "ZodAny", ZodFirstPartyTypeKind$1["ZodUnknown"] = "ZodUnknown", ZodFirstPartyTypeKind$1["ZodNever"] = "ZodNever", ZodFirstPartyTypeKind$1["ZodVoid"] = "ZodVoid", ZodFirstPartyTypeKind$1["ZodArray"] = "ZodArray", ZodFirstPartyTypeKind$1["ZodObject"] = "ZodObject", ZodFirstPartyTypeKind$1["ZodUnion"] = "ZodUnion", ZodFirstPartyTypeKind$1["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion", ZodFirstPartyTypeKind$1["ZodIntersection"] = "ZodIntersection", ZodFirstPartyTypeKind$1["ZodTuple"] = "ZodTuple", ZodFirstPartyTypeKind$1["ZodRecord"] = "ZodRecord", ZodFirstPartyTypeKind$1["ZodMap"] = "ZodMap", ZodFirstPartyTypeKind$1["ZodSet"] = "ZodSet", ZodFirstPartyTypeKind$1["ZodFunction"] = "ZodFunction", ZodFirstPartyTypeKind$1["ZodLazy"] = "ZodLazy", ZodFirstPartyTypeKind$1["ZodLiteral"] = "ZodLiteral", ZodFirstPartyTypeKind$1["ZodEnum"] = "ZodEnum", ZodFirstPartyTypeKind$1["ZodEffects"] = "ZodEffects", ZodFirstPartyTypeKind$1["ZodNativeEnum"] = "ZodNativeEnum", ZodFirstPartyTypeKind$1["ZodOptional"] = "ZodOptional", ZodFirstPartyTypeKind$1["ZodNullable"] = "ZodNullable", ZodFirstPartyTypeKind$1["ZodDefault"] = "ZodDefault", ZodFirstPartyTypeKind$1["ZodCatch"] = "ZodCatch", ZodFirstPartyTypeKind$1["ZodPromise"] = "ZodPromise", ZodFirstPartyTypeKind$1["ZodBranded"] = "ZodBranded", ZodFirstPartyTypeKind$1["ZodPipeline"] = "ZodPipeline", ZodFirstPartyTypeKind$1["ZodReadonly"] = "ZodReadonly";
|
|
3017
3017
|
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
|
|
3018
|
-
const stringType = ZodString.create, numberType = ZodNumber.create, nanType = ZodNaN.create, bigIntType = ZodBigInt.create, booleanType = ZodBoolean.create, dateType = ZodDate.create, symbolType = ZodSymbol.create, undefinedType = ZodUndefined.create, nullType = ZodNull.create, anyType = ZodAny.create, unknownType = ZodUnknown.create, neverType = ZodNever.create, voidType = ZodVoid.create, arrayType = ZodArray.create, objectType = ZodObject.create, strictObjectType = ZodObject.strictCreate, unionType = ZodUnion.create, discriminatedUnionType = ZodDiscriminatedUnion.create, intersectionType = ZodIntersection.create, tupleType = ZodTuple.create, recordType = ZodRecord.create, mapType = ZodMap.create, setType = ZodSet.create, functionType = ZodFunction.create, lazyType = ZodLazy.create, literalType = ZodLiteral.create, enumType = ZodEnum.create, nativeEnumType = ZodNativeEnum.create, promiseType = ZodPromise.create, effectsType = ZodEffects.create, optionalType = ZodOptional.create, nullableType = ZodNullable.create, preprocessType = ZodEffects.createWithPreprocess, pipelineType = ZodPipeline.create,
|
|
3018
|
+
const stringType = ZodString.create, numberType = ZodNumber.create, nanType = ZodNaN.create, bigIntType = ZodBigInt.create, booleanType = ZodBoolean.create, dateType = ZodDate.create, symbolType = ZodSymbol.create, undefinedType = ZodUndefined.create, nullType = ZodNull.create, anyType = ZodAny.create, unknownType = ZodUnknown.create, neverType = ZodNever.create, voidType = ZodVoid.create, arrayType = ZodArray.create, objectType = ZodObject.create, strictObjectType = ZodObject.strictCreate, unionType = ZodUnion.create, discriminatedUnionType = ZodDiscriminatedUnion.create, intersectionType = ZodIntersection.create, tupleType = ZodTuple.create, recordType = ZodRecord.create, mapType = ZodMap.create, setType = ZodSet.create, functionType = ZodFunction.create, lazyType = ZodLazy.create, literalType = ZodLiteral.create, enumType = ZodEnum.create, nativeEnumType = ZodNativeEnum.create, promiseType = ZodPromise.create, effectsType = ZodEffects.create, optionalType = ZodOptional.create, nullableType = ZodNullable.create, preprocessType = ZodEffects.createWithPreprocess, pipelineType = ZodPipeline.create, coerce = {
|
|
3019
|
+
string: ((arg) => ZodString.create({
|
|
3020
|
+
...arg,
|
|
3021
|
+
coerce: true
|
|
3022
|
+
})),
|
|
3023
|
+
number: ((arg) => ZodNumber.create({
|
|
3024
|
+
...arg,
|
|
3025
|
+
coerce: true
|
|
3026
|
+
})),
|
|
3027
|
+
boolean: ((arg) => ZodBoolean.create({
|
|
3028
|
+
...arg,
|
|
3029
|
+
coerce: true
|
|
3030
|
+
})),
|
|
3031
|
+
bigint: ((arg) => ZodBigInt.create({
|
|
3032
|
+
...arg,
|
|
3033
|
+
coerce: true
|
|
3034
|
+
})),
|
|
3035
|
+
date: ((arg) => ZodDate.create({
|
|
3036
|
+
...arg,
|
|
3037
|
+
coerce: true
|
|
3038
|
+
}))
|
|
3039
|
+
}, modelNameSchema = stringType().min(1, "Model name cannot be empty").brand(), sessionIdSchema = stringType().min(1, "Session ID cannot be empty").brand(), requestIdSchema = stringType().min(1, "Request ID cannot be empty").brand(), messageIdSchema = stringType().min(1, "Message ID cannot be empty").brand(), isoTimestampSchema = stringType().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/, "Invalid ISO timestamp").brand(), dailyDateSchema = stringType().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").brand(), activityDateSchema = stringType().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").brand(), monthlyDateSchema = stringType().regex(/^\d{4}-\d{2}$/, "Date must be in YYYY-MM format").brand(), weeklyDateSchema = stringType().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").brand(), filterDateSchema = stringType().regex(/^\d{8}$/, "Date must be in YYYYMMDD format").brand(), projectPathSchema = stringType().min(1, "Project path cannot be empty").brand(), versionSchema = stringType().regex(/^\d+\.\d+\.\d+/, "Invalid version format").brand(), createSessionId = (value) => sessionIdSchema.parse(value), createDailyDate = (value) => dailyDateSchema.parse(value), createMonthlyDate = (value) => monthlyDateSchema.parse(value), createWeeklyDate = (value) => weeklyDateSchema.parse(value), createProjectPath = (value) => projectPathSchema.parse(value);
|
|
3019
3040
|
function createBucket(value) {
|
|
3020
3041
|
return weeklyDateSchema.safeParse(value).success ? createWeeklyDate(value) : createMonthlyDate(value);
|
|
3021
3042
|
}
|
|
@@ -3043,6 +3064,13 @@ const CostModes = [
|
|
|
3043
3064
|
current_dir: stringType(),
|
|
3044
3065
|
project_dir: stringType()
|
|
3045
3066
|
}),
|
|
3046
|
-
version: stringType().optional()
|
|
3067
|
+
version: stringType().optional(),
|
|
3068
|
+
cost: objectType({
|
|
3069
|
+
total_cost_usd: numberType(),
|
|
3070
|
+
total_duration_ms: numberType().optional(),
|
|
3071
|
+
total_api_duration_ms: numberType().optional(),
|
|
3072
|
+
total_lines_added: numberType().optional(),
|
|
3073
|
+
total_lines_removed: numberType().optional()
|
|
3074
|
+
}).optional()
|
|
3047
3075
|
});
|
|
3048
|
-
export { CostModes, SortOrders, ZodFirstPartyTypeKind, ZodOptional, ZodType, activityDateSchema, arrayType, booleanType, createBucket, createDailyDate, createMonthlyDate, createProjectPath, createSessionId, createWeeklyDate, dailyDateSchema, discriminatedUnionType, enumType, filterDateSchema, isoTimestampSchema, literalType, messageIdSchema, modelNameSchema, modelPricingSchema, monthlyDateSchema, numberType, objectType, optionalType, projectPathSchema, recordType, requestIdSchema, sessionIdSchema, statuslineHookJsonSchema, stringType, unionType, unknownType, versionSchema, weeklyDateSchema };
|
|
3076
|
+
export { CostModes, SortOrders, ZodFirstPartyTypeKind, ZodOptional, ZodType, activityDateSchema, arrayType, booleanType, coerce, createBucket, createDailyDate, createMonthlyDate, createProjectPath, createSessionId, createWeeklyDate, dailyDateSchema, discriminatedUnionType, enumType, filterDateSchema, isoTimestampSchema, literalType, messageIdSchema, modelNameSchema, modelPricingSchema, monthlyDateSchema, numberType, objectType, optionalType, projectPathSchema, recordType, requestIdSchema, sessionIdSchema, statuslineHookJsonSchema, stringType, unionType, unknownType, versionSchema, weeklyDateSchema };
|
package/dist/calculate-cost.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./pricing-fetcher-BgDfBZ05.js";
|
|
2
|
-
import { DailyUsage, MonthlyUsage, SessionUsage, WeeklyUsage } from "./data-loader
|
|
2
|
+
import { DailyUsage, MonthlyUsage, SessionUsage, WeeklyUsage } from "./data-loader-DewcQaMm.js";
|
|
3
3
|
|
|
4
4
|
//#region src/_token-utils.d.ts
|
|
5
5
|
|
package/dist/calculate-cost.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
2
|
-
import "./_types-
|
|
2
|
+
import "./_types-DIdtMJ6V.js";
|
|
3
3
|
import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
|
|
4
4
|
export { calculateTotals, createTotalsObject, getTotalTokens };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME,
|
|
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, isSuccess, require_usingCtx } from "./pricing-fetcher-CoBMgxFA.js";
|
|
2
2
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
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-
|
|
4
|
-
import { logger } from "./logger-
|
|
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-DIdtMJ6V.js";
|
|
4
|
+
import { logger } from "./logger-DKCIi_ai.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";
|
|
@@ -2201,23 +2201,6 @@ function getClaudePaths() {
|
|
|
2201
2201
|
- Or set ${CLAUDE_CONFIG_DIR_ENV} environment variable to valid directory path(s) containing a '${CLAUDE_PROJECTS_DIR_NAME}' subdirectory`.trim());
|
|
2202
2202
|
return paths;
|
|
2203
2203
|
}
|
|
2204
|
-
function getContextUsageThresholds() {
|
|
2205
|
-
const lowThresholdStr = process$1.env[CONTEXT_LOW_THRESHOLD_ENV], mediumThresholdStr = process$1.env[CONTEXT_MEDIUM_THRESHOLD_ENV];
|
|
2206
|
-
let lowThreshold = DEFAULT_CONTEXT_USAGE_THRESHOLDS.LOW, mediumThreshold = DEFAULT_CONTEXT_USAGE_THRESHOLDS.MEDIUM;
|
|
2207
|
-
if (lowThresholdStr != null) {
|
|
2208
|
-
const parsed = Number.parseInt(lowThresholdStr, 10);
|
|
2209
|
-
if (!Number.isNaN(parsed)) lowThreshold = Math.max(0, Math.min(100, parsed));
|
|
2210
|
-
}
|
|
2211
|
-
if (mediumThresholdStr != null) {
|
|
2212
|
-
const parsed = Number.parseInt(mediumThresholdStr, 10);
|
|
2213
|
-
if (!Number.isNaN(parsed)) mediumThreshold = Math.max(0, Math.min(100, parsed));
|
|
2214
|
-
}
|
|
2215
|
-
if (lowThreshold >= mediumThreshold) lowThreshold = DEFAULT_CONTEXT_USAGE_THRESHOLDS.LOW, mediumThreshold = DEFAULT_CONTEXT_USAGE_THRESHOLDS.MEDIUM;
|
|
2216
|
-
return {
|
|
2217
|
-
LOW: lowThreshold,
|
|
2218
|
-
MEDIUM: mediumThreshold
|
|
2219
|
-
};
|
|
2220
|
-
}
|
|
2221
2204
|
function extractProjectFromPath(jsonlPath) {
|
|
2222
2205
|
const normalizedPath = jsonlPath.replace(/[/\\]/g, path.sep), segments = normalizedPath.split(path.sep), projectsIndex = segments.findIndex((segment) => segment === CLAUDE_PROJECTS_DIR_NAME);
|
|
2223
2206
|
if (projectsIndex === -1 || projectsIndex + 1 >= segments.length) return "unknown";
|
|
@@ -2761,4 +2744,4 @@ async function loadSessionBlockData(options) {
|
|
|
2761
2744
|
_usingCtx6.d();
|
|
2762
2745
|
}
|
|
2763
2746
|
}
|
|
2764
|
-
export { DEFAULT_SESSION_DURATION_HOURS, bucketUsageSchema, calculateBurnRate, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, filterRecentBlocks, formatDate, formatDateCompact, getClaudePaths,
|
|
2747
|
+
export { DEFAULT_SESSION_DURATION_HOURS, bucketUsageSchema, calculateBurnRate, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, filterRecentBlocks, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, glob, globUsageFiles, identifySessionBlocks, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, projectBlockUsage, sessionUsageSchema, sortFilesByTimestamp, toArray, transcriptMessageSchema, transcriptUsageSchema, uniq, unwrap, usageDataSchema, weeklyUsageSchema };
|
|
@@ -66,16 +66,6 @@ type SessionBlock = {
|
|
|
66
66
|
* @returns Array of valid Claude data directory paths
|
|
67
67
|
*/
|
|
68
68
|
declare function getClaudePaths(): string[];
|
|
69
|
-
/**
|
|
70
|
-
* Get context usage percentage thresholds for color coding
|
|
71
|
-
* Can be configured via environment variables or uses defaults
|
|
72
|
-
* Validates and clamps values to 0-100 range and enforces LOW < MEDIUM ordering
|
|
73
|
-
* @returns Context usage thresholds with LOW and MEDIUM percentages
|
|
74
|
-
*/
|
|
75
|
-
declare function getContextUsageThresholds(): {
|
|
76
|
-
readonly LOW: number;
|
|
77
|
-
readonly MEDIUM: number;
|
|
78
|
-
};
|
|
79
69
|
/**
|
|
80
70
|
* Extract project name from Claude JSONL file path
|
|
81
71
|
* @param jsonlPath - Absolute path to JSONL file
|
|
@@ -806,4 +796,4 @@ declare function calculateContextTokens(transcriptPath: string, modelId?: string
|
|
|
806
796
|
*/
|
|
807
797
|
declare function loadSessionBlockData(options?: LoadOptions): Promise<SessionBlock[]>;
|
|
808
798
|
//#endregion
|
|
809
|
-
export { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths,
|
|
799
|
+
export { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema };
|
package/dist/data-loader.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import "./pricing-fetcher-BgDfBZ05.js";
|
|
2
|
-
import { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths,
|
|
3
|
-
export { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths,
|
|
2
|
+
import { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema } from "./data-loader-DewcQaMm.js";
|
|
3
|
+
export { BucketUsage, DailyUsage, DateFilter, GlobResult, LoadOptions, ModelBreakdown, MonthlyUsage, SessionUsage, UsageData, WeeklyUsage, bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema };
|
package/dist/data-loader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-CoBMgxFA.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
|
-
import "./_types-
|
|
4
|
-
import { bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths,
|
|
5
|
-
import "./logger-
|
|
6
|
-
export { bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths,
|
|
3
|
+
import "./_types-DIdtMJ6V.js";
|
|
4
|
+
import { bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, usageDataSchema, weeklyUsageSchema } from "./data-loader-C7KK9Yu0.js";
|
|
5
|
+
import "./logger-DKCIi_ai.js";
|
|
6
|
+
export { bucketUsageSchema, calculateContextTokens, calculateCostForEntry, createUniqueHash, dailyUsageSchema, extractProjectFromPath, formatDate, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, loadBucketUsageData, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, modelBreakdownSchema, monthlyUsageSchema, sessionUsageSchema, sortFilesByTimestamp, transcriptMessageSchema, transcriptUsageSchema, 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-
|
|
2
|
-
import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-
|
|
3
|
-
import { logger } from "./logger-
|
|
1
|
+
import { CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, PricingFetcher, USAGE_DATA_GLOB_PATTERN, __toESM, isFailure, require_usingCtx, try_ } from "./pricing-fetcher-CoBMgxFA.js";
|
|
2
|
+
import { getClaudePaths, glob, unwrap, usageDataSchema } from "./data-loader-C7KK9Yu0.js";
|
|
3
|
+
import { logger } from "./logger-DKCIi_ai.js";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
var import_usingCtx = /* @__PURE__ */ __toESM(require_usingCtx(), 1);
|
package/dist/debug.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-CoBMgxFA.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
|
-
import "./_types-
|
|
4
|
-
import "./data-loader-
|
|
5
|
-
import "./logger-
|
|
6
|
-
import { detectMismatches, printMismatchReport } from "./debug-
|
|
3
|
+
import "./_types-DIdtMJ6V.js";
|
|
4
|
+
import "./data-loader-C7KK9Yu0.js";
|
|
5
|
+
import "./logger-DKCIi_ai.js";
|
|
6
|
+
import { detectMismatches, printMismatchReport } from "./debug-BOv8jTQu.js";
|
|
7
7
|
export { detectMismatches, printMismatchReport };
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CONFIG_FILE_NAME, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PricingFetcher, WEEK_DAYS, __commonJSMin, __require, __toESM, inspect, inspectError, isFailure, isSuccess, map, pipe, require_usingCtx, succeed, try_ } from "./pricing-fetcher-
|
|
2
|
+
import { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CONFIG_FILE_NAME, DEFAULT_CONTEXT_USAGE_THRESHOLDS, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PricingFetcher, WEEK_DAYS, __commonJSMin, __require, __toESM, andThen, fail, inspect, inspectError, isFailure, isSuccess, map, pipe, require_usingCtx, succeed, try_ } from "./pricing-fetcher-CoBMgxFA.js";
|
|
3
3
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
4
|
-
import { CostModes, SortOrders, filterDateSchema, statuslineHookJsonSchema } from "./_types-
|
|
4
|
+
import { CostModes, SortOrders, coerce, filterDateSchema, statuslineHookJsonSchema } from "./_types-DIdtMJ6V.js";
|
|
5
5
|
import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
|
|
6
|
-
import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateContextTokens, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths,
|
|
7
|
-
import { description, log, logger, name, version } from "./logger-
|
|
8
|
-
import { detectMismatches, printMismatchReport } from "./debug-
|
|
9
|
-
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-
|
|
6
|
+
import { DEFAULT_SESSION_DURATION_HOURS, calculateBurnRate, calculateContextTokens, calculateCostForEntry, createUniqueHash, filterRecentBlocks, formatDateCompact, getClaudePaths, getEarliestTimestamp, getUsageLimitResetTime, globUsageFiles, identifySessionBlocks, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData, loadSessionUsageById, loadWeeklyUsageData, projectBlockUsage, sortFilesByTimestamp, toArray, uniq, unwrap, usageDataSchema } from "./data-loader-C7KK9Yu0.js";
|
|
7
|
+
import { description, log, logger, name, version } from "./logger-DKCIi_ai.js";
|
|
8
|
+
import { detectMismatches, printMismatchReport } from "./debug-BOv8jTQu.js";
|
|
9
|
+
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-DDHqWuGb.js";
|
|
10
10
|
import a, { readFile, stat } from "node:fs/promises";
|
|
11
11
|
import path, { join } from "node:path";
|
|
12
12
|
import process$1 from "node:process";
|
|
@@ -817,7 +817,7 @@ var require_picocolors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
817
817
|
};
|
|
818
818
|
};
|
|
819
819
|
module.exports = createColors(), module.exports.createColors = createColors;
|
|
820
|
-
})), import_picocolors$8 = /* @__PURE__ */ __toESM(require_picocolors(), 1), import_usingCtx$
|
|
820
|
+
})), import_picocolors$8 = /* @__PURE__ */ __toESM(require_picocolors(), 1), import_usingCtx$4 = /* @__PURE__ */ __toESM(require_usingCtx(), 1);
|
|
821
821
|
function extractExplicitArgs(tokens) {
|
|
822
822
|
const explicit = {};
|
|
823
823
|
for (const token of tokens) if (typeof token === "object" && token !== null) {
|
|
@@ -2467,7 +2467,7 @@ function stringWidth(string, options = {}) {
|
|
|
2467
2467
|
}
|
|
2468
2468
|
return width;
|
|
2469
2469
|
}
|
|
2470
|
-
var import_usingCtx$
|
|
2470
|
+
var import_usingCtx$3 = /* @__PURE__ */ __toESM(require_usingCtx(), 1), ResponsiveTable = class {
|
|
2471
2471
|
head;
|
|
2472
2472
|
rows = [];
|
|
2473
2473
|
colAligns;
|
|
@@ -2603,62 +2603,173 @@ async function getFileModifiedTime(filePath) {
|
|
|
2603
2603
|
catch: (error) => error
|
|
2604
2604
|
}), map((stats) => stats.mtime.getTime()), unwrap(0));
|
|
2605
2605
|
}
|
|
2606
|
-
var
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2606
|
+
var Node = class {
|
|
2607
|
+
value;
|
|
2608
|
+
next;
|
|
2609
|
+
constructor(value$1) {
|
|
2610
|
+
this.value = value$1;
|
|
2611
|
+
}
|
|
2612
|
+
}, Queue = class {
|
|
2613
|
+
#head;
|
|
2614
|
+
#tail;
|
|
2615
|
+
#size;
|
|
2616
|
+
constructor() {
|
|
2617
|
+
this.clear();
|
|
2618
|
+
}
|
|
2619
|
+
enqueue(value$1) {
|
|
2620
|
+
const node = new Node(value$1);
|
|
2621
|
+
if (this.#head) this.#tail.next = node, this.#tail = node;
|
|
2622
|
+
else this.#head = node, this.#tail = node;
|
|
2623
|
+
this.#size++;
|
|
2624
|
+
}
|
|
2625
|
+
dequeue() {
|
|
2626
|
+
const current = this.#head;
|
|
2627
|
+
if (current) return this.#head = this.#head.next, this.#size--, current.value;
|
|
2628
|
+
}
|
|
2629
|
+
peek() {
|
|
2630
|
+
if (this.#head) return this.#head.value;
|
|
2631
|
+
}
|
|
2632
|
+
clear() {
|
|
2633
|
+
this.#head = void 0, this.#tail = void 0, this.#size = 0;
|
|
2634
|
+
}
|
|
2635
|
+
get size() {
|
|
2636
|
+
return this.#size;
|
|
2637
|
+
}
|
|
2638
|
+
*[Symbol.iterator]() {
|
|
2639
|
+
let current = this.#head;
|
|
2640
|
+
while (current) yield current.value, current = current.next;
|
|
2641
|
+
}
|
|
2642
|
+
*drain() {
|
|
2643
|
+
while (this.#head) yield this.dequeue();
|
|
2644
|
+
}
|
|
2645
|
+
};
|
|
2646
|
+
function pLimit(concurrency) {
|
|
2647
|
+
validateConcurrency(concurrency);
|
|
2648
|
+
const queue = new Queue();
|
|
2649
|
+
let activeCount = 0;
|
|
2650
|
+
const resumeNext = () => {
|
|
2651
|
+
if (activeCount < concurrency && queue.size > 0) activeCount++, queue.dequeue()();
|
|
2652
|
+
}, next = () => {
|
|
2653
|
+
activeCount--, resumeNext();
|
|
2654
|
+
}, run$1 = async (function_, resolve, arguments_) => {
|
|
2655
|
+
const result = (async () => function_(...arguments_))();
|
|
2656
|
+
resolve(result);
|
|
2657
|
+
try {
|
|
2658
|
+
await result;
|
|
2659
|
+
} catch {}
|
|
2660
|
+
next();
|
|
2661
|
+
}, enqueue = (function_, resolve, arguments_) => {
|
|
2662
|
+
if (new Promise((internalResolve) => {
|
|
2663
|
+
queue.enqueue(internalResolve);
|
|
2664
|
+
}).then(run$1.bind(void 0, function_, resolve, arguments_)), activeCount < concurrency) resumeNext();
|
|
2665
|
+
}, generator = (function_, ...arguments_) => new Promise((resolve) => {
|
|
2666
|
+
enqueue(function_, resolve, arguments_);
|
|
2667
|
+
});
|
|
2668
|
+
return Object.defineProperties(generator, {
|
|
2669
|
+
activeCount: { get: () => activeCount },
|
|
2670
|
+
pendingCount: { get: () => queue.size },
|
|
2671
|
+
clearQueue: { value() {
|
|
2672
|
+
queue.clear();
|
|
2673
|
+
} },
|
|
2674
|
+
concurrency: {
|
|
2675
|
+
get: () => concurrency,
|
|
2676
|
+
set(newConcurrency) {
|
|
2677
|
+
validateConcurrency(newConcurrency), concurrency = newConcurrency, queueMicrotask(() => {
|
|
2678
|
+
while (activeCount < concurrency && queue.size > 0) resumeNext();
|
|
2679
|
+
});
|
|
2653
2680
|
}
|
|
2681
|
+
},
|
|
2682
|
+
map: { async value(array, function_) {
|
|
2683
|
+
const promises = array.map((value$1, index) => this(function_, value$1, index));
|
|
2684
|
+
return Promise.all(promises);
|
|
2685
|
+
} }
|
|
2686
|
+
}), generator;
|
|
2687
|
+
}
|
|
2688
|
+
function validateConcurrency(concurrency) {
|
|
2689
|
+
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
2690
|
+
}
|
|
2691
|
+
var import_usingCtx$2 = /* @__PURE__ */ __toESM(require_usingCtx(), 1);
|
|
2692
|
+
const RETENTION_HOURS = 24, FILE_CONCURRENCY = 5;
|
|
2693
|
+
async function isRecentFile(filePath, cutoffTime) {
|
|
2694
|
+
return pipe(try_({
|
|
2695
|
+
try: stat(filePath),
|
|
2696
|
+
catch: (error) => error
|
|
2697
|
+
}), map((fileStats) => fileStats.mtime >= cutoffTime), unwrap(false));
|
|
2698
|
+
}
|
|
2699
|
+
function createLiveMonitorState(config) {
|
|
2700
|
+
const fetcher = config.mode !== "display" ? new PricingFetcher() : null;
|
|
2701
|
+
return {
|
|
2702
|
+
fetcher,
|
|
2703
|
+
lastFileTimestamps: /* @__PURE__ */ new Map(),
|
|
2704
|
+
processedHashes: /* @__PURE__ */ new Set(),
|
|
2705
|
+
allEntries: [],
|
|
2706
|
+
[Symbol.dispose]() {
|
|
2707
|
+
fetcher?.[Symbol.dispose]();
|
|
2654
2708
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2709
|
+
};
|
|
2710
|
+
}
|
|
2711
|
+
function clearLiveMonitorCache(state) {
|
|
2712
|
+
state.lastFileTimestamps.clear(), state.processedHashes.clear(), state.allEntries = [];
|
|
2713
|
+
}
|
|
2714
|
+
function cleanupOldEntries(state, cutoffTime) {
|
|
2715
|
+
const initialCount = state.allEntries.length;
|
|
2716
|
+
if (state.allEntries = state.allEntries.filter((entry) => entry.timestamp >= cutoffTime), initialCount - state.allEntries.length > 100) state.processedHashes.clear();
|
|
2717
|
+
}
|
|
2718
|
+
async function processFileContent(state, config, content, cutoffTime) {
|
|
2719
|
+
const lines = content.trim().split("\n").filter((line) => line.length > 0);
|
|
2720
|
+
for (const line of lines) {
|
|
2721
|
+
const dataResult = pipe(try_({
|
|
2722
|
+
try: () => JSON.parse(line),
|
|
2723
|
+
catch: (error) => error
|
|
2724
|
+
})(), andThen((data$1) => {
|
|
2725
|
+
const parseResult = usageDataSchema.safeParse(data$1);
|
|
2726
|
+
return parseResult.success ? succeed(parseResult.data) : fail(parseResult.error);
|
|
2727
|
+
}));
|
|
2728
|
+
if (isFailure(dataResult)) continue;
|
|
2729
|
+
const data = unwrap(dataResult), entryTime = new Date(data.timestamp);
|
|
2730
|
+
if (entryTime < cutoffTime) continue;
|
|
2731
|
+
const uniqueHash = createUniqueHash(data);
|
|
2732
|
+
if (uniqueHash != null && state.processedHashes.has(uniqueHash)) continue;
|
|
2733
|
+
if (uniqueHash != null) state.processedHashes.add(uniqueHash);
|
|
2734
|
+
const costUSD = await (config.mode === "display" ? Promise.resolve(data.costUSD ?? 0) : calculateCostForEntry(data, config.mode, state.fetcher)), usageLimitResetTime = getUsageLimitResetTime(data);
|
|
2735
|
+
state.allEntries.push({
|
|
2736
|
+
timestamp: entryTime,
|
|
2737
|
+
usage: {
|
|
2738
|
+
inputTokens: data.message.usage.input_tokens ?? 0,
|
|
2739
|
+
outputTokens: data.message.usage.output_tokens ?? 0,
|
|
2740
|
+
cacheCreationInputTokens: data.message.usage.cache_creation_input_tokens ?? 0,
|
|
2741
|
+
cacheReadInputTokens: data.message.usage.cache_read_input_tokens ?? 0
|
|
2742
|
+
},
|
|
2743
|
+
costUSD,
|
|
2744
|
+
model: data.message.model ?? "<synthetic>",
|
|
2745
|
+
version: data.version,
|
|
2746
|
+
usageLimitResetTime: usageLimitResetTime ?? void 0
|
|
2747
|
+
});
|
|
2657
2748
|
}
|
|
2658
|
-
|
|
2659
|
-
|
|
2749
|
+
}
|
|
2750
|
+
async function getActiveBlock(state, config) {
|
|
2751
|
+
const cutoffTime = /* @__PURE__ */ new Date(Date.now() - RETENTION_HOURS * 60 * 60 * 1e3), results = await globUsageFiles(config.claudePaths), allFiles = results.map((r) => r.file);
|
|
2752
|
+
if (allFiles.length === 0) return null;
|
|
2753
|
+
const candidateFiles = [];
|
|
2754
|
+
for (const file of allFiles) if (await isRecentFile(file, cutoffTime)) candidateFiles.push(file);
|
|
2755
|
+
const filesToRead = [];
|
|
2756
|
+
for (const file of candidateFiles) {
|
|
2757
|
+
const timestamp$1 = await getEarliestTimestamp(file), lastTimestamp = state.lastFileTimestamps.get(file);
|
|
2758
|
+
if (timestamp$1 != null && (lastTimestamp == null || timestamp$1.getTime() > lastTimestamp)) filesToRead.push(file), state.lastFileTimestamps.set(file, timestamp$1.getTime());
|
|
2660
2759
|
}
|
|
2661
|
-
|
|
2760
|
+
if (cleanupOldEntries(state, cutoffTime), filesToRead.length > 0) {
|
|
2761
|
+
const sortedFiles = await sortFilesByTimestamp(filesToRead), fileLimit = pLimit(FILE_CONCURRENCY), fileResults = await Promise.allSettled(sortedFiles.map(async (file) => fileLimit(async () => ({
|
|
2762
|
+
file,
|
|
2763
|
+
content: await readFile(file, "utf-8")
|
|
2764
|
+
}))));
|
|
2765
|
+
for (const result of fileResults) if (result.status === "fulfilled") {
|
|
2766
|
+
const { content } = result.value;
|
|
2767
|
+
await processFileContent(state, config, content, cutoffTime);
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
const blocks = identifySessionBlocks(state.allEntries, config.sessionDurationHours), sortedBlocks = config.order === "asc" ? blocks : blocks.reverse();
|
|
2771
|
+
return sortedBlocks.find((block) => block.isActive) ?? null;
|
|
2772
|
+
}
|
|
2662
2773
|
function delay(ms, options = {}) {
|
|
2663
2774
|
const { signal, persistent = true } = options;
|
|
2664
2775
|
return signal?.aborted ? Promise.reject(signal.reason) : new Promise((resolve, reject) => {
|
|
@@ -3044,16 +3155,16 @@ async function startLiveMonitoring(config) {
|
|
|
3044
3155
|
var _usingCtx = (0, import_usingCtx$1.default)();
|
|
3045
3156
|
const terminal = new TerminalManager(), abortController = new AbortController();
|
|
3046
3157
|
let lastRenderTime = 0;
|
|
3047
|
-
const
|
|
3048
|
-
if (abortController.abort(), terminal.cleanup(), terminal.clearScreen(), logger.info("Live monitoring stopped."), process$1.exitCode == null) process$1.exit(0);
|
|
3049
|
-
};
|
|
3050
|
-
process$1.on("SIGINT", cleanup), process$1.on("SIGTERM", cleanup), terminal.enterAlternateScreen(), terminal.enableSyncMode(), terminal.clearScreen(), terminal.hideCursor();
|
|
3051
|
-
const monitor = _usingCtx.u(new LiveMonitor({
|
|
3158
|
+
const monitorConfig = {
|
|
3052
3159
|
claudePaths: config.claudePaths,
|
|
3053
3160
|
sessionDurationHours: config.sessionDurationHours,
|
|
3054
3161
|
mode: config.mode,
|
|
3055
3162
|
order: config.order
|
|
3056
|
-
})),
|
|
3163
|
+
}, monitorState = _usingCtx.u(createLiveMonitorState(monitorConfig)), cleanup = () => {
|
|
3164
|
+
if (abortController.abort(), terminal.cleanup(), terminal.clearScreen(), logger.info("Live monitoring stopped."), process$1.exitCode == null) process$1.exit(0);
|
|
3165
|
+
};
|
|
3166
|
+
process$1.on("SIGINT", cleanup), process$1.on("SIGTERM", cleanup), terminal.enterAlternateScreen(), terminal.enableSyncMode(), terminal.clearScreen(), terminal.hideCursor();
|
|
3167
|
+
const monitoringResult = await try_({
|
|
3057
3168
|
try: async () => {
|
|
3058
3169
|
while (!abortController.signal.aborted) {
|
|
3059
3170
|
const now = Date.now(), timeSinceLastRender = now - lastRenderTime;
|
|
@@ -3061,8 +3172,8 @@ async function startLiveMonitoring(config) {
|
|
|
3061
3172
|
await delayWithAbort(MIN_RENDER_INTERVAL_MS - timeSinceLastRender, abortController.signal);
|
|
3062
3173
|
continue;
|
|
3063
3174
|
}
|
|
3064
|
-
const activeBlock = await
|
|
3065
|
-
if (
|
|
3175
|
+
const activeBlock = await getActiveBlock(monitorState, monitorConfig);
|
|
3176
|
+
if (clearLiveMonitorCache(monitorState), activeBlock == null) {
|
|
3066
3177
|
await renderWaitingState(terminal, config, abortController.signal);
|
|
3067
3178
|
continue;
|
|
3068
3179
|
}
|
|
@@ -5214,7 +5325,12 @@ const visualBurnRateChoices = [
|
|
|
5214
5325
|
"emoji",
|
|
5215
5326
|
"text",
|
|
5216
5327
|
"emoji-text"
|
|
5217
|
-
],
|
|
5328
|
+
], costSourceChoices = [
|
|
5329
|
+
"auto",
|
|
5330
|
+
"ccusage",
|
|
5331
|
+
"cc",
|
|
5332
|
+
"both"
|
|
5333
|
+
], contextThresholdSchema = coerce.number().int().min(0, "Context threshold must be at least 0").max(100, "Context threshold must be at most 100"), statuslineCommand = define({
|
|
5218
5334
|
name: "statusline",
|
|
5219
5335
|
description: "Display compact status line for Claude Code hooks with hybrid time+file caching (Beta)",
|
|
5220
5336
|
toKebab: true,
|
|
@@ -5232,6 +5348,14 @@ const visualBurnRateChoices = [
|
|
|
5232
5348
|
negatable: false,
|
|
5233
5349
|
toKebab: true
|
|
5234
5350
|
},
|
|
5351
|
+
costSource: {
|
|
5352
|
+
type: "enum",
|
|
5353
|
+
choices: costSourceChoices,
|
|
5354
|
+
description: "Session cost source: auto (prefer CC then ccusage), ccusage (always calculate), cc (always use Claude Code cost), both (show both costs)",
|
|
5355
|
+
default: "auto",
|
|
5356
|
+
negatable: false,
|
|
5357
|
+
toKebab: true
|
|
5358
|
+
},
|
|
5235
5359
|
cache: {
|
|
5236
5360
|
type: "boolean",
|
|
5237
5361
|
description: "Enable cache for status line output (default: true)",
|
|
@@ -5242,11 +5366,23 @@ const visualBurnRateChoices = [
|
|
|
5242
5366
|
description: `Refresh interval in seconds for cache expiry (default: ${DEFAULT_REFRESH_INTERVAL_SECONDS})`,
|
|
5243
5367
|
default: DEFAULT_REFRESH_INTERVAL_SECONDS
|
|
5244
5368
|
},
|
|
5369
|
+
contextLowThreshold: {
|
|
5370
|
+
type: "custom",
|
|
5371
|
+
description: "Context usage percentage below which status is shown in green (0-100)",
|
|
5372
|
+
parse: (value$1) => contextThresholdSchema.parse(value$1),
|
|
5373
|
+
default: DEFAULT_CONTEXT_USAGE_THRESHOLDS.LOW
|
|
5374
|
+
},
|
|
5375
|
+
contextMediumThreshold: {
|
|
5376
|
+
type: "custom",
|
|
5377
|
+
description: "Context usage percentage below which status is shown in yellow (0-100)",
|
|
5378
|
+
parse: (value$1) => contextThresholdSchema.parse(value$1),
|
|
5379
|
+
default: DEFAULT_CONTEXT_USAGE_THRESHOLDS.MEDIUM
|
|
5380
|
+
},
|
|
5245
5381
|
config: sharedArgs.config,
|
|
5246
5382
|
debug: sharedArgs.debug
|
|
5247
5383
|
},
|
|
5248
5384
|
async run(ctx) {
|
|
5249
|
-
logger.level = 0;
|
|
5385
|
+
if (logger.level = 0, ctx.values.contextLowThreshold >= ctx.values.contextMediumThreshold) throw new Error(`Context low threshold (${ctx.values.contextLowThreshold}) must be less than medium threshold (${ctx.values.contextMediumThreshold})`);
|
|
5250
5386
|
const config = loadConfig(ctx.values.config, ctx.values.debug), mergedOptions = mergeConfigWithArgs(ctx, config, ctx.values.debug), refreshInterval = mergedOptions.refreshInterval, stdin$2 = await getStdin();
|
|
5251
5387
|
if (stdin$2.length === 0) log("❌ No input provided"), process$1.exit(1);
|
|
5252
5388
|
const hookDataJson = JSON.parse(stdin$2.trim()), hookDataParseResult = statuslineHookJsonSchema.safeParse(hookDataJson);
|
|
@@ -5299,33 +5435,55 @@ const visualBurnRateChoices = [
|
|
|
5299
5435
|
}
|
|
5300
5436
|
const mainProcessingResult = pipe(await try_({
|
|
5301
5437
|
try: async () => {
|
|
5302
|
-
const sessionCost = await
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5438
|
+
const { sessionCost, ccCost, ccusageCost } = await (async () => {
|
|
5439
|
+
const costSource = ctx.values.costSource, getCcusageCost = async () => {
|
|
5440
|
+
return pipe(try_({
|
|
5441
|
+
try: async () => loadSessionUsageById(sessionId, {
|
|
5442
|
+
mode: "auto",
|
|
5443
|
+
offline: mergedOptions.offline
|
|
5444
|
+
}),
|
|
5445
|
+
catch: (error) => error
|
|
5446
|
+
})(), map((sessionCost$1) => sessionCost$1?.totalCost), inspectError((error) => logger.error("Failed to load session data:", error)), unwrap(void 0));
|
|
5447
|
+
};
|
|
5448
|
+
if (costSource === "both") {
|
|
5449
|
+
const ccCost$1 = hookData.cost?.total_cost_usd, ccusageCost$1 = await getCcusageCost();
|
|
5450
|
+
return {
|
|
5451
|
+
ccCost: ccCost$1,
|
|
5452
|
+
ccusageCost: ccusageCost$1
|
|
5453
|
+
};
|
|
5454
|
+
}
|
|
5455
|
+
if (costSource === "cc") return { sessionCost: hookData.cost?.total_cost_usd };
|
|
5456
|
+
if (costSource === "ccusage") {
|
|
5457
|
+
const cost = await getCcusageCost();
|
|
5458
|
+
return { sessionCost: cost };
|
|
5459
|
+
}
|
|
5460
|
+
if (costSource === "auto") {
|
|
5461
|
+
if (hookData.cost?.total_cost_usd != null) return { sessionCost: hookData.cost.total_cost_usd };
|
|
5462
|
+
const cost = await getCcusageCost();
|
|
5463
|
+
return { sessionCost: cost };
|
|
5464
|
+
}
|
|
5465
|
+
return {};
|
|
5466
|
+
})(), today = /* @__PURE__ */ new Date(), todayStr = today.toISOString().split("T")[0]?.replace(/-/g, "") ?? "", todayCost = await pipe(try_({
|
|
5467
|
+
try: async () => loadDailyUsageData({
|
|
5310
5468
|
since: todayStr,
|
|
5311
5469
|
until: todayStr,
|
|
5312
5470
|
mode: "auto",
|
|
5313
5471
|
offline: mergedOptions.offline
|
|
5314
5472
|
}),
|
|
5315
5473
|
catch: (error) => error
|
|
5316
|
-
}), map((dailyData) => {
|
|
5474
|
+
})(), map((dailyData) => {
|
|
5317
5475
|
if (dailyData.length > 0) {
|
|
5318
5476
|
const totals = calculateTotals(dailyData);
|
|
5319
5477
|
return totals.totalCost;
|
|
5320
5478
|
}
|
|
5321
5479
|
return 0;
|
|
5322
5480
|
}), inspectError((error) => logger.error("Failed to load daily data:", error)), unwrap(0)), { blockInfo, burnRateInfo } = await pipe(try_({
|
|
5323
|
-
try: loadSessionBlockData({
|
|
5481
|
+
try: async () => loadSessionBlockData({
|
|
5324
5482
|
mode: "auto",
|
|
5325
5483
|
offline: mergedOptions.offline
|
|
5326
5484
|
}),
|
|
5327
5485
|
catch: (error) => error
|
|
5328
|
-
}), map((blocks) => {
|
|
5486
|
+
})(), map((blocks) => {
|
|
5329
5487
|
if (blocks.length === 0) return {
|
|
5330
5488
|
blockInfo: "No active block",
|
|
5331
5489
|
burnRateInfo: ""
|
|
@@ -5371,11 +5529,17 @@ const visualBurnRateChoices = [
|
|
|
5371
5529
|
})), contextInfo = await pipe(try_({
|
|
5372
5530
|
try: calculateContextTokens(hookData.transcript_path, hookData.model.id, mergedOptions.offline),
|
|
5373
5531
|
catch: (error) => error
|
|
5374
|
-
}), inspectError((error) => logger.debug(`Failed to calculate context tokens: ${error instanceof Error ? error.message : String(error)}`)), map((
|
|
5375
|
-
if (
|
|
5376
|
-
const
|
|
5532
|
+
}), inspectError((error) => logger.debug(`Failed to calculate context tokens: ${error instanceof Error ? error.message : String(error)}`)), map((contextResult) => {
|
|
5533
|
+
if (contextResult == null) return void 0;
|
|
5534
|
+
const color = contextResult.percentage < ctx.values.contextLowThreshold ? import_picocolors$1.default.green : contextResult.percentage < ctx.values.contextMediumThreshold ? import_picocolors$1.default.yellow : import_picocolors$1.default.red, coloredPercentage = color(`${contextResult.percentage}%`), tokenDisplay = contextResult.inputTokens.toLocaleString();
|
|
5377
5535
|
return `${tokenDisplay} (${coloredPercentage})`;
|
|
5378
|
-
}), unwrap(void 0)), modelName = hookData.model.display_name, sessionDisplay =
|
|
5536
|
+
}), unwrap(void 0)), modelName = hookData.model.display_name, sessionDisplay = (() => {
|
|
5537
|
+
if (ccCost != null || ccusageCost != null) {
|
|
5538
|
+
const ccDisplay = ccCost != null ? formatCurrency(ccCost) : "N/A", ccusageDisplay = ccusageCost != null ? formatCurrency(ccusageCost) : "N/A";
|
|
5539
|
+
return `(${ccDisplay} cc / ${ccusageDisplay} ccusage)`;
|
|
5540
|
+
}
|
|
5541
|
+
return sessionCost != null ? formatCurrency(sessionCost) : "N/A";
|
|
5542
|
+
})(), statusLine = `🤖 ${modelName} | 💰 ${sessionDisplay} session / ${formatCurrency(todayCost)} today / ${blockInfo}${burnRateInfo} | 🧠 ${contextInfo ?? "N/A"}`;
|
|
5379
5543
|
return statusLine;
|
|
5380
5544
|
},
|
|
5381
5545
|
catch: (error) => error
|
|
@@ -761,7 +761,7 @@ function _getDefaultLogLevel() {
|
|
|
761
761
|
return g ? LogLevels.debug : R ? LogLevels.warn : LogLevels.info;
|
|
762
762
|
}
|
|
763
763
|
const consola = createConsola$1();
|
|
764
|
-
var name = "ccusage", version = "16.
|
|
764
|
+
var name = "ccusage", version = "16.2.0", description = "Usage analysis tool for Claude Code";
|
|
765
765
|
const logger = consola.withTag(name);
|
|
766
766
|
if (process$1.env.LOG_LEVEL != null) {
|
|
767
767
|
const level = Number.parseInt(process$1.env.LOG_LEVEL, 10);
|
package/dist/logger.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { log, logger } from "./logger-
|
|
1
|
+
import { log, logger } from "./logger-DKCIi_ai.js";
|
|
2
2
|
export { log, logger };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-
|
|
1
|
+
import { __commonJSMin, __toESM, require_usingCtx } from "./pricing-fetcher-CoBMgxFA.js";
|
|
2
2
|
import { getTotalTokens } from "./_token-utils-WjkbrjKv.js";
|
|
3
|
-
import { ZodFirstPartyTypeKind, ZodOptional, ZodType, arrayType, booleanType, discriminatedUnionType, enumType, filterDateSchema, literalType, numberType, objectType, optionalType, recordType, stringType, unionType, unknownType } from "./_types-
|
|
3
|
+
import { ZodFirstPartyTypeKind, ZodOptional, ZodType, arrayType, booleanType, discriminatedUnionType, enumType, filterDateSchema, literalType, numberType, objectType, optionalType, recordType, stringType, unionType, unknownType } from "./_types-DIdtMJ6V.js";
|
|
4
4
|
import { calculateTotals, createTotalsObject } from "./calculate-cost-BDqO4yWA.js";
|
|
5
|
-
import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-
|
|
6
|
-
import { name, version } from "./logger-
|
|
5
|
+
import { getClaudePaths, loadDailyUsageData, loadMonthlyUsageData, loadSessionBlockData, loadSessionData } from "./data-loader-C7KK9Yu0.js";
|
|
6
|
+
import { name, version } from "./logger-DKCIi_ai.js";
|
|
7
7
|
import process from "node:process";
|
|
8
8
|
const LATEST_PROTOCOL_VERSION = "2025-06-18", SUPPORTED_PROTOCOL_VERSIONS = [
|
|
9
9
|
LATEST_PROTOCOL_VERSION,
|
package/dist/mcp.d.ts
CHANGED
package/dist/mcp.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./pricing-fetcher-
|
|
1
|
+
import "./pricing-fetcher-CoBMgxFA.js";
|
|
2
2
|
import "./_token-utils-WjkbrjKv.js";
|
|
3
|
-
import "./_types-
|
|
3
|
+
import "./_types-DIdtMJ6V.js";
|
|
4
4
|
import "./calculate-cost-BDqO4yWA.js";
|
|
5
|
-
import "./data-loader-
|
|
6
|
-
import "./logger-
|
|
7
|
-
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-
|
|
5
|
+
import "./data-loader-C7KK9Yu0.js";
|
|
6
|
+
import "./logger-DKCIi_ai.js";
|
|
7
|
+
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-DDHqWuGb.js";
|
|
8
8
|
export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { modelPricingSchema } from "./_types-
|
|
2
|
-
import { logger } from "./logger-
|
|
1
|
+
import { modelPricingSchema } from "./_types-DIdtMJ6V.js";
|
|
2
|
+
import { logger } from "./logger-DKCIi_ai.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import F, { homedir } from "node:os";
|
|
@@ -99,7 +99,7 @@ const LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/m
|
|
|
99
99
|
}, DEFAULT_CONTEXT_USAGE_THRESHOLDS = {
|
|
100
100
|
LOW: 50,
|
|
101
101
|
MEDIUM: 80
|
|
102
|
-
},
|
|
102
|
+
}, WEEK_DAYS = [
|
|
103
103
|
"sunday",
|
|
104
104
|
"monday",
|
|
105
105
|
"tuesday",
|
|
@@ -292,9 +292,9 @@ var require_usingCtx = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
292
292
|
"output_cost_per_token": 15e-6,
|
|
293
293
|
"cache_creation_input_token_cost": 375e-8,
|
|
294
294
|
"cache_read_input_token_cost": 3e-7,
|
|
295
|
-
"max_tokens":
|
|
296
|
-
"max_input_tokens":
|
|
297
|
-
"max_output_tokens":
|
|
295
|
+
"max_tokens": 1e6,
|
|
296
|
+
"max_input_tokens": 1e6,
|
|
297
|
+
"max_output_tokens": 1e6
|
|
298
298
|
},
|
|
299
299
|
"claude-3-7-sonnet-latest": {
|
|
300
300
|
"input_cost_per_token": 3e-6,
|
|
@@ -399,4 +399,4 @@ var require_usingCtx = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
399
399
|
return cost;
|
|
400
400
|
}
|
|
401
401
|
};
|
|
402
|
-
export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, CONFIG_FILE_NAME,
|
|
402
|
+
export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, CONFIG_FILE_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_CONTEXT_USAGE_THRESHOLDS, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, WEEK_DAYS, __commonJSMin, __require, __toESM, andThen, fail, inspect, inspectError, isFailure, isPromise, isSuccess, map, pipe, require_usingCtx, succeed, try_ };
|
package/dist/pricing-fetcher.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PricingFetcher } from "./pricing-fetcher-
|
|
2
|
-
import "./_types-
|
|
3
|
-
import "./logger-
|
|
1
|
+
import { PricingFetcher } from "./pricing-fetcher-CoBMgxFA.js";
|
|
2
|
+
import "./_types-DIdtMJ6V.js";
|
|
3
|
+
import "./logger-DKCIi_ai.js";
|
|
4
4
|
export { PricingFetcher };
|