claude-cost-cry 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.ko.md +173 -0
- package/README.md +174 -0
- package/bin/cli.js +333 -0
- package/dist/calculator.d.ts +8 -0
- package/dist/calculator.js +74 -0
- package/dist/calculator.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/display.d.ts +11 -0
- package/dist/display.js +204 -0
- package/dist/display.js.map +1 -0
- package/dist/exchange.d.ts +5 -0
- package/dist/exchange.js +104 -0
- package/dist/exchange.js.map +1 -0
- package/dist/history.d.ts +3 -0
- package/dist/history.js +176 -0
- package/dist/history.js.map +1 -0
- package/dist/i18n.d.ts +9 -0
- package/dist/i18n.js +34 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/dist/locales/en.d.ts +191 -0
- package/dist/locales/en.js +204 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/locales/ko.d.ts +191 -0
- package/dist/locales/ko.js +204 -0
- package/dist/locales/ko.js.map +1 -0
- package/dist/messages.d.ts +9 -0
- package/dist/messages.js +73 -0
- package/dist/messages.js.map +1 -0
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +21 -0
- package/dist/parser.js.map +1 -0
- package/dist/pricing.d.ts +6 -0
- package/dist/pricing.js +49 -0
- package/dist/pricing.js.map +1 -0
- package/dist/providers/claude.d.ts +3 -0
- package/dist/providers/claude.js +79 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/cursor.d.ts +9 -0
- package/dist/providers/cursor.js +217 -0
- package/dist/providers/cursor.js.map +1 -0
- package/dist/providers/google.d.ts +3 -0
- package/dist/providers/google.js +72 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.js +41 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +3 -0
- package/dist/providers/openai.js +90 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/report.d.ts +36 -0
- package/dist/report.js +203 -0
- package/dist/report.js.map +1 -0
- package/dist/types.d.ts +137 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/watcher.d.ts +12 -0
- package/dist/watcher.js +222 -0
- package/dist/watcher.js.map +1 -0
- package/electron/main.js +405 -0
- package/electron/overlay.html +1390 -0
- package/electron/package.json +1 -0
- package/electron/preload.js +15 -0
- package/package.json +65 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Usage, Config, EquivalentResult, SavingsNudge } from './types.js';
|
|
2
|
+
export declare function calculateCost(usage: Usage): number;
|
|
3
|
+
export declare function formatCost(cost: number): string;
|
|
4
|
+
export declare function formatCostShort(cost: number): string;
|
|
5
|
+
export declare function getAllEquivalents(config: Config): import("./types.js").EquivalentItem[];
|
|
6
|
+
export declare function toEquivalent(cost: number, config: Config): EquivalentResult | null;
|
|
7
|
+
export declare function formatTokenCount(n: number): string;
|
|
8
|
+
export declare function getSavingsNudge(usage: Usage, actualCost: number): SavingsNudge | null;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getPricing, getEquivalents, resolveEquivKey } from './pricing.js';
|
|
2
|
+
import { calculateCost as providerCalculateCost, getProvider } from './providers/index.js';
|
|
3
|
+
export function calculateCost(usage) {
|
|
4
|
+
if (usage.provider) {
|
|
5
|
+
return providerCalculateCost(usage);
|
|
6
|
+
}
|
|
7
|
+
const pricing = getPricing(usage.model);
|
|
8
|
+
return (usage.inputTokens / 1e6) * pricing.input
|
|
9
|
+
+ (usage.outputTokens / 1e6) * pricing.output
|
|
10
|
+
+ (usage.cacheCreationTokens / 1e6) * (pricing.cacheWrite || 0)
|
|
11
|
+
+ (usage.cacheReadTokens / 1e6) * (pricing.cacheRead || 0);
|
|
12
|
+
}
|
|
13
|
+
export function formatCost(cost) {
|
|
14
|
+
return `$${cost.toFixed(4)}`;
|
|
15
|
+
}
|
|
16
|
+
export function formatCostShort(cost) {
|
|
17
|
+
if (cost < 0.01)
|
|
18
|
+
return `$${cost.toFixed(4)}`;
|
|
19
|
+
if (cost < 1)
|
|
20
|
+
return `$${cost.toFixed(3)}`;
|
|
21
|
+
return `$${cost.toFixed(2)}`;
|
|
22
|
+
}
|
|
23
|
+
export function getAllEquivalents(config) {
|
|
24
|
+
const custom = config?.customEquivalents || [];
|
|
25
|
+
return [...custom, ...getEquivalents()];
|
|
26
|
+
}
|
|
27
|
+
export function toEquivalent(cost, config) {
|
|
28
|
+
if (cost < 0.01)
|
|
29
|
+
return null;
|
|
30
|
+
const allItems = getAllEquivalents(config);
|
|
31
|
+
const unit = config?.equivalentUnit || 'auto';
|
|
32
|
+
if (unit !== 'auto') {
|
|
33
|
+
const resolved = resolveEquivKey(unit);
|
|
34
|
+
const fixed = allItems.find(i => i.key === resolved || i.name === resolved);
|
|
35
|
+
if (fixed) {
|
|
36
|
+
return { ...fixed, count: Math.round((cost / fixed.price) * 10) / 10 };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
for (const item of allItems) {
|
|
40
|
+
const count = cost / item.price;
|
|
41
|
+
if (count >= 0.1) {
|
|
42
|
+
return { ...item, count: Math.round(count * 10) / 10 };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { ...allItems[0], count: Math.round((cost / allItems[0].price) * 10) / 10 };
|
|
46
|
+
}
|
|
47
|
+
export function formatTokenCount(n) {
|
|
48
|
+
if (n >= 1_000_000)
|
|
49
|
+
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
50
|
+
if (n >= 1_000)
|
|
51
|
+
return `${(n / 1_000).toFixed(1)}K`;
|
|
52
|
+
return String(n);
|
|
53
|
+
}
|
|
54
|
+
export function getSavingsNudge(usage, actualCost) {
|
|
55
|
+
const provider = usage.provider ? getProvider(usage.provider) : null;
|
|
56
|
+
if (!provider)
|
|
57
|
+
return null;
|
|
58
|
+
const models = provider.models;
|
|
59
|
+
const currentLabel = provider.getModelLabel(usage.model).toLowerCase();
|
|
60
|
+
let bestSaving = null;
|
|
61
|
+
for (const [, pricing] of Object.entries(models)) {
|
|
62
|
+
if (pricing.label.toLowerCase() === currentLabel)
|
|
63
|
+
continue;
|
|
64
|
+
const totalInput = usage.inputTokens + usage.cacheCreationTokens + usage.cacheReadTokens;
|
|
65
|
+
const altCost = (totalInput / 1e6) * pricing.input
|
|
66
|
+
+ (usage.outputTokens / 1e6) * pricing.output;
|
|
67
|
+
const saving = actualCost - altCost;
|
|
68
|
+
if (saving > 0.001 && (!bestSaving || saving > bestSaving.saving)) {
|
|
69
|
+
bestSaving = { model: pricing.label, cost: altCost, saving };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return bestSaving;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=calculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculator.js","sourceRoot":"","sources":["../src/calculator.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Config, BudgetStatus } from './types.js';
|
|
2
|
+
export declare function loadConfig(): Config;
|
|
3
|
+
export declare function saveConfig(config: Config): void;
|
|
4
|
+
export declare function updateConfig(updates: Partial<Config>): Config;
|
|
5
|
+
export declare function getBudgetStatus(cost: number, budget: number | null): BudgetStatus;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
const CONFIG_DIR = join(homedir(), '.claude-cost-cry');
|
|
5
|
+
const CONFIG_PATH = join(CONFIG_DIR, 'config.json');
|
|
6
|
+
const DEFAULTS = {
|
|
7
|
+
dailyBudget: null,
|
|
8
|
+
monthlyBudget: null,
|
|
9
|
+
currency: 'USD',
|
|
10
|
+
exchangeRate: null,
|
|
11
|
+
showNudge: true,
|
|
12
|
+
equivalentUnit: 'auto',
|
|
13
|
+
customEquivalents: [],
|
|
14
|
+
logSources: [],
|
|
15
|
+
language: 'en',
|
|
16
|
+
};
|
|
17
|
+
export function loadConfig() {
|
|
18
|
+
try {
|
|
19
|
+
const raw = readFileSync(CONFIG_PATH, 'utf-8');
|
|
20
|
+
return { ...DEFAULTS, ...JSON.parse(raw) };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { ...DEFAULTS };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function saveConfig(config) {
|
|
27
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
28
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
29
|
+
}
|
|
30
|
+
export function updateConfig(updates) {
|
|
31
|
+
const config = loadConfig();
|
|
32
|
+
Object.assign(config, updates);
|
|
33
|
+
saveConfig(config);
|
|
34
|
+
return config;
|
|
35
|
+
}
|
|
36
|
+
export function getBudgetStatus(cost, budget) {
|
|
37
|
+
if (!budget || budget <= 0)
|
|
38
|
+
return { ratio: 0, status: 'ok', budget: null };
|
|
39
|
+
const ratio = cost / budget;
|
|
40
|
+
let status = 'ok';
|
|
41
|
+
if (ratio >= 1)
|
|
42
|
+
status = 'exceeded';
|
|
43
|
+
else if (ratio >= 0.9)
|
|
44
|
+
status = 'danger';
|
|
45
|
+
else if (ratio >= 0.7)
|
|
46
|
+
status = 'warning';
|
|
47
|
+
return { ratio: Math.min(ratio, 1), status, budget, remaining: Math.max(0, budget - cost) };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACvD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,MAAM,QAAQ,GAAW;IACvB,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,IAAI;IACnB,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,IAAI;IAClB,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,MAAM;IACtB,iBAAiB,EAAE,EAAE;IACrB,UAAU,EAAE,EAAE;IACd,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAwB;IACnD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,MAAqB;IACjE,IAAI,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAE5E,MAAM,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC;IAE5B,IAAI,MAAM,GAA2B,IAAI,CAAC;IAC1C,IAAI,KAAK,IAAI,CAAC;QAAE,MAAM,GAAG,UAAU,CAAC;SAC/B,IAAI,KAAK,IAAI,GAAG;QAAE,MAAM,GAAG,QAAQ,CAAC;SACpC,IAAI,KAAK,IAAI,GAAG;QAAE,MAAM,GAAG,SAAS,CAAC;IAE1C,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;AAC9F,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Usage, Config, ExchangeInfo, BudgetStatus, TopRequest } from './types.js';
|
|
2
|
+
export declare function showBanner(): void;
|
|
3
|
+
export declare function showTodaySummary(totalCost: number, callCount: number, budgetStatus: BudgetStatus | null, config: Config, exchange: ExchangeInfo | null, costByProvider?: Record<string, number>): void;
|
|
4
|
+
export declare function showBudgetBar(totalCost: number, budgetStatus: BudgetStatus, exchange: ExchangeInfo | null): void;
|
|
5
|
+
export declare function showCostUpdate(usage: Usage, cost: number, totalCost: number, config: Config, exchange: ExchangeInfo | null): void;
|
|
6
|
+
export declare function showBudgetAlert(budgetStatus: BudgetStatus, exchange: ExchangeInfo | null): void;
|
|
7
|
+
export declare function showTopExpensive(topRequests: TopRequest[], exchange: ExchangeInfo | null): void;
|
|
8
|
+
export declare function showShutdown(sessionCost: number, totalCost: number, savingsTotal: number, topRequests: TopRequest[], config: Config, exchange: ExchangeInfo | null, costByProvider?: Record<string, number>): void;
|
|
9
|
+
export declare function showError(message: string): void;
|
|
10
|
+
export declare function showInfo(message: string): void;
|
|
11
|
+
export declare function showConfigUpdate(key: string, value: string | number): void;
|
package/dist/display.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { formatCostShort, formatTokenCount, toEquivalent, getSavingsNudge } from './calculator.js';
|
|
3
|
+
import { getMessage, getStartupMood } from './messages.js';
|
|
4
|
+
import { formatLocalCost } from './exchange.js';
|
|
5
|
+
import { getModelLabel as getProviderModelLabel, getProviderEmoji, getProviderDisplayName } from './providers/index.js';
|
|
6
|
+
import { t } from './i18n.js';
|
|
7
|
+
const VERSION = '0.3.0';
|
|
8
|
+
const DIVIDER = chalk.gray('─'.repeat(56));
|
|
9
|
+
function fc(cost, ex) {
|
|
10
|
+
return ex ? formatLocalCost(cost, ex) : formatCostShort(cost);
|
|
11
|
+
}
|
|
12
|
+
function resolveModelLabel(usage) {
|
|
13
|
+
if (usage.provider)
|
|
14
|
+
return getProviderModelLabel(usage);
|
|
15
|
+
return usage.model || 'Unknown';
|
|
16
|
+
}
|
|
17
|
+
function providerTag(providerName) {
|
|
18
|
+
if (!providerName)
|
|
19
|
+
return '';
|
|
20
|
+
const emoji = getProviderEmoji(providerName);
|
|
21
|
+
return `${emoji} `;
|
|
22
|
+
}
|
|
23
|
+
export function showBanner() {
|
|
24
|
+
console.log();
|
|
25
|
+
console.log(chalk.bold(` 🪙 claude-cost-cry v${VERSION}`));
|
|
26
|
+
console.log(chalk.gray(` ${t('display.tagline')}`));
|
|
27
|
+
console.log();
|
|
28
|
+
}
|
|
29
|
+
export function showTodaySummary(totalCost, callCount, budgetStatus, config, exchange, costByProvider) {
|
|
30
|
+
const mood = getStartupMood(totalCost);
|
|
31
|
+
const equiv = toEquivalent(totalCost, config);
|
|
32
|
+
const defaultUnit = t('display.defaultUnit');
|
|
33
|
+
const equivText = equiv
|
|
34
|
+
? chalk.gray(` (${equiv.emoji} ${equiv.name} ${equiv.count}${equiv.unit || defaultUnit})`)
|
|
35
|
+
: '';
|
|
36
|
+
console.log(` ${t('display.todayTotal')} ${chalk.bold.yellow(fc(totalCost, exchange))}${equivText}`);
|
|
37
|
+
if (callCount > 0) {
|
|
38
|
+
console.log(chalk.gray(` ${t('display.apiCalls', { count: callCount })}`));
|
|
39
|
+
}
|
|
40
|
+
if (costByProvider && Object.keys(costByProvider).length > 1) {
|
|
41
|
+
const breakdown = Object.entries(costByProvider)
|
|
42
|
+
.sort((a, b) => b[1] - a[1])
|
|
43
|
+
.map(([p, c]) => `${getProviderEmoji(p)} ${getProviderDisplayName(p)} ${fc(c, exchange)}`)
|
|
44
|
+
.join(' ');
|
|
45
|
+
console.log(chalk.gray(` ${breakdown}`));
|
|
46
|
+
}
|
|
47
|
+
console.log(chalk.gray(` ${mood}`));
|
|
48
|
+
if (exchange && exchange.currency !== 'USD') {
|
|
49
|
+
const src = exchange.source === 'manual' ? t('display.exchangeManual') : exchange.updatedAt || '';
|
|
50
|
+
console.log(chalk.gray(` 💱 1 USD = ${exchange.rate.toLocaleString()} ${exchange.currency} (${src})`));
|
|
51
|
+
}
|
|
52
|
+
if (budgetStatus?.budget) {
|
|
53
|
+
console.log();
|
|
54
|
+
showBudgetBar(totalCost, budgetStatus, exchange);
|
|
55
|
+
}
|
|
56
|
+
console.log();
|
|
57
|
+
console.log(DIVIDER);
|
|
58
|
+
console.log(chalk.gray(` ${t('display.watching')}`));
|
|
59
|
+
console.log(DIVIDER);
|
|
60
|
+
console.log();
|
|
61
|
+
}
|
|
62
|
+
export function showBudgetBar(totalCost, budgetStatus, exchange) {
|
|
63
|
+
const { ratio, status, budget, remaining } = budgetStatus;
|
|
64
|
+
const barWidth = 30;
|
|
65
|
+
const filled = Math.round(ratio * barWidth);
|
|
66
|
+
const empty = barWidth - filled;
|
|
67
|
+
let barColor;
|
|
68
|
+
let statusIcon;
|
|
69
|
+
if (status === 'exceeded') {
|
|
70
|
+
barColor = chalk.bgRed.white;
|
|
71
|
+
statusIcon = '🚫';
|
|
72
|
+
}
|
|
73
|
+
else if (status === 'danger') {
|
|
74
|
+
barColor = chalk.bgRedBright.black;
|
|
75
|
+
statusIcon = '🔴';
|
|
76
|
+
}
|
|
77
|
+
else if (status === 'warning') {
|
|
78
|
+
barColor = chalk.bgYellow.black;
|
|
79
|
+
statusIcon = '🟡';
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
barColor = chalk.bgGreen.black;
|
|
83
|
+
statusIcon = '🟢';
|
|
84
|
+
}
|
|
85
|
+
const bar = barColor('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
|
|
86
|
+
const pct = Math.round(ratio * 100);
|
|
87
|
+
console.log(` ${statusIcon} ${t('display.budget')} ${bar} ${pct}%`);
|
|
88
|
+
console.log(chalk.gray(` ${fc(totalCost, exchange)} / ${fc(budget, exchange)} (${t('display.budgetRemaining')} ${fc(remaining, exchange)})`));
|
|
89
|
+
if (status === 'exceeded') {
|
|
90
|
+
console.log(chalk.red.bold(` ${t('display.budgetExceeded')}`));
|
|
91
|
+
}
|
|
92
|
+
else if (status === 'danger') {
|
|
93
|
+
console.log(chalk.red(` ${t('display.budget90')}`));
|
|
94
|
+
}
|
|
95
|
+
else if (status === 'warning') {
|
|
96
|
+
console.log(chalk.yellow(` ${t('display.budget70')}`));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function showCostUpdate(usage, cost, totalCost, config, exchange) {
|
|
100
|
+
const now = new Date();
|
|
101
|
+
const timeStr = chalk.gray(`[${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}]`);
|
|
102
|
+
const modelLabel = resolveModelLabel(usage);
|
|
103
|
+
const pEmoji = providerTag(usage.provider);
|
|
104
|
+
const isCursor = usage.provider === 'cursor';
|
|
105
|
+
const modelColor = isCursor ? chalk.hex('#06b6d4')
|
|
106
|
+
: /opus/i.test(modelLabel) ? chalk.magenta
|
|
107
|
+
: /haiku/i.test(modelLabel) ? chalk.green
|
|
108
|
+
: /gpt/i.test(modelLabel) ? chalk.hex('#74aa9c')
|
|
109
|
+
: /gemini/i.test(modelLabel) ? chalk.hex('#4285f4')
|
|
110
|
+
: chalk.blue;
|
|
111
|
+
const modelStr = modelColor(`${pEmoji}${modelLabel}`);
|
|
112
|
+
const totalInputTokens = usage.inputTokens + usage.cacheCreationTokens + usage.cacheReadTokens;
|
|
113
|
+
const tokenInfo = chalk.gray(`📥 ${formatTokenCount(totalInputTokens)} 📤 ${formatTokenCount(usage.outputTokens)}`);
|
|
114
|
+
const { emoji, message } = getMessage(totalCost);
|
|
115
|
+
const costDelta = cost >= 0.01
|
|
116
|
+
? chalk.red(`+${fc(cost, exchange)}`)
|
|
117
|
+
: chalk.yellow(`+${fc(cost, exchange)}`);
|
|
118
|
+
const totalStr = chalk.bold.yellow(fc(totalCost, exchange));
|
|
119
|
+
const equiv = toEquivalent(totalCost, config);
|
|
120
|
+
const defaultUnit = t('display.defaultUnit');
|
|
121
|
+
const equivStr = equiv
|
|
122
|
+
? chalk.gray(` ${equiv.emoji} ${equiv.count}${equiv.unit || defaultUnit}`)
|
|
123
|
+
: '';
|
|
124
|
+
console.log(` ${timeStr} ${modelStr} ${tokenInfo}`);
|
|
125
|
+
console.log(` ${emoji} ${costDelta} → ${t('display.cumulative')} ${totalStr}${equivStr}`);
|
|
126
|
+
console.log(chalk.italic.gray(` "${message}"`));
|
|
127
|
+
if (config?.showNudge && cost > 0.01) {
|
|
128
|
+
const nudge = getSavingsNudge(usage, cost);
|
|
129
|
+
if (nudge && nudge.saving > 0.005) {
|
|
130
|
+
console.log(chalk.cyan(` ${t('display.nudge', { model: nudge.model, cost: fc(nudge.cost, exchange), saving: fc(nudge.saving, exchange) })}`));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
console.log();
|
|
134
|
+
}
|
|
135
|
+
export function showBudgetAlert(budgetStatus, exchange) {
|
|
136
|
+
const { status } = budgetStatus;
|
|
137
|
+
if (status === 'exceeded') {
|
|
138
|
+
console.log(chalk.bgRed.white.bold(` ${t('display.budgetExceededBanner')} `));
|
|
139
|
+
console.log();
|
|
140
|
+
}
|
|
141
|
+
else if (status === 'danger') {
|
|
142
|
+
console.log(chalk.red(` ${t('display.budget90Alert', { remaining: fc(budgetStatus.remaining, exchange) })}`));
|
|
143
|
+
console.log();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export function showTopExpensive(topRequests, exchange) {
|
|
147
|
+
if (!topRequests || topRequests.length === 0)
|
|
148
|
+
return;
|
|
149
|
+
console.log();
|
|
150
|
+
console.log(` 🏆 ${chalk.bold(t('display.topExpensive'))}`);
|
|
151
|
+
console.log();
|
|
152
|
+
topRequests.forEach((req, i) => {
|
|
153
|
+
const medal = ['🥇', '🥈', '🥉'][i];
|
|
154
|
+
const pEmoji = req.providerEmoji ? `${req.providerEmoji} ` : '';
|
|
155
|
+
const modelColor = req.provider === 'cursor' ? chalk.hex('#06b6d4')
|
|
156
|
+
: /opus/i.test(req.model) ? chalk.magenta
|
|
157
|
+
: /haiku/i.test(req.model) ? chalk.green
|
|
158
|
+
: /gpt/i.test(req.model) ? chalk.hex('#74aa9c')
|
|
159
|
+
: /gemini/i.test(req.model) ? chalk.hex('#4285f4')
|
|
160
|
+
: chalk.blue;
|
|
161
|
+
const timeStr = req.time || '';
|
|
162
|
+
console.log(` ${medal} ${chalk.bold.yellow(fc(req.cost, exchange))} ${pEmoji}${modelColor(req.model)} ${chalk.gray(timeStr)}`);
|
|
163
|
+
if (req.prompt) {
|
|
164
|
+
console.log(chalk.white(` 💬 "${req.prompt}"`));
|
|
165
|
+
}
|
|
166
|
+
console.log(chalk.gray(` 📥 ${formatTokenCount(req.inputTokens)} 📤 ${formatTokenCount(req.outputTokens)}`));
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
export function showShutdown(sessionCost, totalCost, savingsTotal, topRequests, config, exchange, costByProvider) {
|
|
170
|
+
console.log();
|
|
171
|
+
console.log(DIVIDER);
|
|
172
|
+
const equiv = toEquivalent(sessionCost, config);
|
|
173
|
+
const defaultUnit = t('display.defaultUnit');
|
|
174
|
+
const equivText = equiv
|
|
175
|
+
? ` (${equiv.emoji} ${equiv.name} ${equiv.count}${equiv.unit || defaultUnit})`
|
|
176
|
+
: '';
|
|
177
|
+
console.log(` ${t('display.sessionCost')} ${chalk.bold.yellow(fc(sessionCost, exchange))}${equivText}`);
|
|
178
|
+
console.log(` ${t('display.todayCost')} ${chalk.bold.yellow(fc(totalCost, exchange))}`);
|
|
179
|
+
if (costByProvider && Object.keys(costByProvider).length > 1) {
|
|
180
|
+
const breakdown = Object.entries(costByProvider)
|
|
181
|
+
.sort((a, b) => b[1] - a[1])
|
|
182
|
+
.map(([p, c]) => `${getProviderEmoji(p)} ${getProviderDisplayName(p)} ${fc(c, exchange)}`)
|
|
183
|
+
.join(' ');
|
|
184
|
+
console.log(chalk.gray(` ${breakdown}`));
|
|
185
|
+
}
|
|
186
|
+
if (savingsTotal > 0.01) {
|
|
187
|
+
console.log(chalk.cyan(` ${t('display.potentialSavings', { amount: fc(savingsTotal, exchange) })}`));
|
|
188
|
+
}
|
|
189
|
+
showTopExpensive(topRequests, exchange);
|
|
190
|
+
console.log();
|
|
191
|
+
console.log(chalk.gray(` ${t('display.goodbye')}`));
|
|
192
|
+
console.log(DIVIDER);
|
|
193
|
+
console.log();
|
|
194
|
+
}
|
|
195
|
+
export function showError(message) {
|
|
196
|
+
console.error(chalk.red(` ❌ ${message}`));
|
|
197
|
+
}
|
|
198
|
+
export function showInfo(message) {
|
|
199
|
+
console.log(chalk.gray(` ℹ️ ${message}`));
|
|
200
|
+
}
|
|
201
|
+
export function showConfigUpdate(key, value) {
|
|
202
|
+
console.log(chalk.green(` ✅ ${key} = ${value}`));
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=display.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Config, ExchangeInfo } from './types.js';
|
|
2
|
+
export declare function getExchangeRate(config: Config): Promise<ExchangeInfo>;
|
|
3
|
+
export declare function formatLocalCost(usdCost: number, exchangeInfo: ExchangeInfo): string;
|
|
4
|
+
export declare function getCurrencySymbol(currency: string): string;
|
|
5
|
+
export declare const SUPPORTED_CURRENCIES: string[];
|
package/dist/exchange.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { t, getLocale } from './i18n.js';
|
|
5
|
+
const CACHE_DIR = join(homedir(), '.claude-cost-cry');
|
|
6
|
+
const CACHE_PATH = join(CACHE_DIR, 'exchange-cache.json');
|
|
7
|
+
const API_URL = 'https://api.frankfurter.app/latest?from=USD';
|
|
8
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
9
|
+
const CURRENCY_SYMBOLS = {
|
|
10
|
+
USD: '$', KRW: '₩', JPY: '¥', EUR: '€', GBP: '£', CNY: '¥',
|
|
11
|
+
};
|
|
12
|
+
function loadCache() {
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(readFileSync(CACHE_PATH, 'utf-8'));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function saveCache(data) {
|
|
21
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
22
|
+
writeFileSync(CACHE_PATH, JSON.stringify(data, null, 2) + '\n', 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
async function fetchRates() {
|
|
25
|
+
try {
|
|
26
|
+
const res = await fetch(API_URL);
|
|
27
|
+
if (!res.ok)
|
|
28
|
+
return null;
|
|
29
|
+
const data = await res.json();
|
|
30
|
+
return data.rates || null;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function dateLocale() {
|
|
37
|
+
return getLocale() === 'ko' ? 'ko-KR' : 'en-US';
|
|
38
|
+
}
|
|
39
|
+
export async function getExchangeRate(config) {
|
|
40
|
+
const currency = config?.currency || 'USD';
|
|
41
|
+
if (currency === 'USD')
|
|
42
|
+
return { rate: 1, symbol: '$', currency: 'USD', source: 'base' };
|
|
43
|
+
if (config?.exchangeRate) {
|
|
44
|
+
return {
|
|
45
|
+
rate: config.exchangeRate,
|
|
46
|
+
symbol: CURRENCY_SYMBOLS[currency] || currency,
|
|
47
|
+
currency,
|
|
48
|
+
source: 'manual',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const cache = loadCache();
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
if (cache?.rates?.[currency] && cache.timestamp && (now - cache.timestamp < CACHE_TTL_MS)) {
|
|
54
|
+
return {
|
|
55
|
+
rate: cache.rates[currency],
|
|
56
|
+
symbol: CURRENCY_SYMBOLS[currency] || currency,
|
|
57
|
+
currency,
|
|
58
|
+
source: 'cache',
|
|
59
|
+
updatedAt: new Date(cache.timestamp).toLocaleDateString(dateLocale()),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const rates = await fetchRates();
|
|
63
|
+
if (rates && rates[currency]) {
|
|
64
|
+
const cacheData = { rates, timestamp: now };
|
|
65
|
+
saveCache(cacheData);
|
|
66
|
+
return {
|
|
67
|
+
rate: rates[currency],
|
|
68
|
+
symbol: CURRENCY_SYMBOLS[currency] || currency,
|
|
69
|
+
currency,
|
|
70
|
+
source: 'api',
|
|
71
|
+
updatedAt: new Date(now).toLocaleDateString(dateLocale()),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (cache?.rates?.[currency]) {
|
|
75
|
+
return {
|
|
76
|
+
rate: cache.rates[currency],
|
|
77
|
+
symbol: CURRENCY_SYMBOLS[currency] || currency,
|
|
78
|
+
currency,
|
|
79
|
+
source: 'stale-cache',
|
|
80
|
+
updatedAt: cache.timestamp ? new Date(cache.timestamp).toLocaleDateString(dateLocale()) : t('exchange.unknown'),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return { rate: 1, symbol: '$', currency: 'USD', source: 'fallback' };
|
|
84
|
+
}
|
|
85
|
+
export function formatLocalCost(usdCost, exchangeInfo) {
|
|
86
|
+
if (!exchangeInfo || exchangeInfo.currency === 'USD') {
|
|
87
|
+
if (usdCost < 0.01)
|
|
88
|
+
return `$${usdCost.toFixed(4)}`;
|
|
89
|
+
if (usdCost < 1)
|
|
90
|
+
return `$${usdCost.toFixed(3)}`;
|
|
91
|
+
return `$${usdCost.toFixed(2)}`;
|
|
92
|
+
}
|
|
93
|
+
const local = usdCost * exchangeInfo.rate;
|
|
94
|
+
const sym = exchangeInfo.symbol;
|
|
95
|
+
if (exchangeInfo.currency === 'KRW' || exchangeInfo.currency === 'JPY') {
|
|
96
|
+
return `${sym}${Math.round(local).toLocaleString()}`;
|
|
97
|
+
}
|
|
98
|
+
return `${sym}${local.toFixed(2)}`;
|
|
99
|
+
}
|
|
100
|
+
export function getCurrencySymbol(currency) {
|
|
101
|
+
return CURRENCY_SYMBOLS[currency] || currency;
|
|
102
|
+
}
|
|
103
|
+
export const SUPPORTED_CURRENCIES = Object.keys(CURRENCY_SYMBOLS);
|
|
104
|
+
//# sourceMappingURL=exchange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../src/exchange.ts"],"names":[],"mappings":"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"}
|