@winston.wan/burn-your-money 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@winston.wan/burn-your-money",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "💸 Burn Your Money - 实时显示 Claude Code 的 token 消耗,看着你的钱包燃烧!",
5
5
  "main": "src/statusline.js",
6
6
  "scripts": {
package/src/statusline.js CHANGED
@@ -172,18 +172,63 @@ function main() {
172
172
  try {
173
173
  const { execSync } = require('child_process');
174
174
  const scriptPath = path.join(__dirname, 'token-history.js');
175
- const freshData = execSync(`node "${scriptPath}" summary`, { encoding: 'utf8' });
175
+ // 使用更兼容的方式执行脚本
176
+ const freshData = execSync(`node "${scriptPath}" summary`, {
177
+ encoding: 'utf8',
178
+ stdio: ['ignore', 'pipe', 'ignore']
179
+ });
176
180
  historyData = JSON.parse(freshData);
177
181
  historyData._cache_time = now;
178
182
  writeJsonFile(HISTORY_CACHE, historyData);
179
183
  } catch (e) {
180
- // 如果获取失败,使用旧缓存
184
+ // 如果获取失败,尝试直接读取 stats-cache.json 作为降级方案
185
+ try {
186
+ const statsCache = path.join(os.homedir(), '.claude', 'stats-cache.json');
187
+ const stats = JSON.parse(fs.readFileSync(statsCache, 'utf8'));
188
+
189
+ // 从 stats-cache.json 构建基本数据
190
+ const totalInput = Object.values(stats.modelUsage || {}).reduce((sum, m) => sum + (m.inputTokens || 0), 0);
191
+ const totalOutput = Object.values(stats.modelUsage || {}).reduce((sum, m) => sum + (m.outputTokens || 0), 0);
192
+ const totalCache = Object.values(stats.modelUsage || {}).reduce((sum, m) => sum + (m.cacheReadInputTokens || 0), 0);
193
+ const totalTokens = totalInput + totalOutput + totalCache;
194
+ const totalCost = (totalInput / 1000000 * 3) + (totalOutput / 1000000 * 15) + (totalCache / 1000000 * 0.3);
195
+
196
+ historyData = {
197
+ total_tokens_all: totalTokens,
198
+ total_cost: totalCost.toFixed(2),
199
+ today_tokens: 0,
200
+ today_cost: '0.00',
201
+ week_tokens: 0,
202
+ week_cost: '0.00',
203
+ month_tokens: 0,
204
+ month_cost: '0.00',
205
+ _cache_time: now
206
+ };
207
+ writeJsonFile(HISTORY_CACHE, historyData);
208
+ } catch (e2) {
209
+ // 如果降级方案也失败,使用旧缓存或默认值
210
+ if (!historyData || !historyData.total_tokens_all) {
211
+ historyData = {
212
+ total_tokens_all: 0,
213
+ total_cost: '0.00',
214
+ today_tokens: 0,
215
+ today_cost: '0.00',
216
+ _cache_time: now
217
+ };
218
+ }
219
+ }
181
220
  }
182
221
  }
183
222
 
184
223
  // 如果缓存不存在或无效,使用默认值(但保留已有数据)
185
224
  if (!historyData || typeof historyData !== 'object') {
186
- historyData = {};
225
+ historyData = {
226
+ total_tokens_all: 0,
227
+ total_cost: '0.00',
228
+ today_tokens: 0,
229
+ today_cost: '0.00',
230
+ _cache_time: now
231
+ };
187
232
  }
188
233
 
189
234
  // 确保 _cache_time 存在(如果是旧缓存,添加时间戳)
@@ -78,38 +78,18 @@ function readStats() {
78
78
  const totalOutputTokens = Object.values(data.modelUsage || {}).reduce((sum, model) => sum + (model.outputTokens || 0), 0);
79
79
  const totalCacheReadTokens = Object.values(data.modelUsage || {}).reduce((sum, model) => sum + (model.cacheReadInputTokens || 0), 0);
80
80
 
81
- // 获取今日 tokens
82
- // 注意:dailyModelTokens 不包含缓存 tokens,且可能更新不及时
83
- // 如果 lastComputedDate 不是今天,今日数据可能不准确
84
- const lastComputedDate = data.lastComputedDate || '';
81
+ // 计算今日 tokens(总计 - 历史每日总和,排除今天)
85
82
  const dailyTokens = data.dailyModelTokens || [];
83
+ let historySum = 0;
84
+ dailyTokens.forEach(day => {
85
+ if (day.date !== TODAY) {
86
+ const models = day.tokensByModel || {};
87
+ historySum += Object.values(models).reduce((sum, tokens) => sum + (tokens || 0), 0);
88
+ }
89
+ });
86
90
 
87
- const totalTokensAll = totalInputTokens + totalOutputTokens + totalCacheReadTokens;
88
-
89
- // 检查是否有今日的 dailyModelTokens 记录
90
- const todayEntry = dailyTokens.find(day => day.date === TODAY);
91
- let todayTokens = 0;
92
- if (todayEntry) {
93
- const models = todayEntry.tokensByModel || {};
94
- todayTokens = Object.values(models).reduce((sum, tokens) => sum + (tokens || 0), 0);
95
- // 补偿缓存 tokens(按比例估算)
96
- const cacheRatio = totalCacheReadTokens / (totalTokensAll || 1);
97
- todayTokens = Math.floor(todayTokens * (1 + cacheRatio));
98
- } else if (lastComputedDate !== TODAY) {
99
- // lastComputedDate 不是今天,无法准确计算今日 tokens
100
- todayTokens = 0;
101
- } else {
102
- // 尝试从总量推算(可能不准确)
103
- let historySum = 0;
104
- dailyTokens.forEach(day => {
105
- if (day.date !== TODAY) {
106
- const models = day.tokensByModel || {};
107
- historySum += Object.values(models).reduce((sum, tokens) => sum + (tokens || 0), 0);
108
- }
109
- });
110
- todayTokens = totalTokensAll - historySum;
111
- if (todayTokens < 0) todayTokens = 0;
112
- }
91
+ const todayTokens = totalInputTokens + totalOutputTokens - historySum;
92
+ if (todayTokens < 0) todayTokens = 0;
113
93
 
114
94
  // 本周 tokens(排除今天,用上面的 todayTokens)
115
95
  const WEEK_START = getWeekStart();
@@ -143,17 +123,18 @@ function readStats() {
143
123
  }
144
124
  });
145
125
 
146
- // 计算费用(按 3/15/0.3 规则:Input $3/M, Output $15/M, Cache $0.3/M)
126
+ // 计算费用(简化:按 3/15/0.3 规则)
147
127
  const totalCost = (totalInputTokens / 1000000 * 3) +
148
128
  (totalOutputTokens / 1000000 * 15) +
149
129
  (totalCacheReadTokens / 1000000 * 0.3);
150
130
 
151
- // 计算各周期费用(按 token 数量比例分摊)
152
- const totalTokensForRatio = totalTokensAll || 1;
153
- const todayCost = todayTokens > 0 ? (todayTokens / totalTokensForRatio * totalCost) : 0;
154
- const weekCost = weekTokens > 0 ? (weekTokens / totalTokensForRatio * totalCost) : 0;
155
- const monthCost = monthTokens > 0 ? (monthTokens / totalTokensForRatio * totalCost) : 0;
156
- const lastMonthCost = lastMonthTokens > 0 ? (lastMonthTokens / totalTokensForRatio * totalCost) : 0;
131
+ const totalTokensAll = totalInputTokens + totalOutputTokens + totalCacheReadTokens;
132
+
133
+ // 计算各周期费用(按比例分摊)
134
+ const todayCost = todayTokens > 0 ? (todayTokens / (totalInputTokens + totalOutputTokens) * totalCost) : 0;
135
+ const weekCost = weekTokens > 0 ? (weekTokens / (totalInputTokens + totalOutputTokens) * totalCost) : 0;
136
+ const monthCost = monthTokens > 0 ? (monthTokens / (totalInputTokens + totalOutputTokens) * totalCost) : 0;
137
+ const lastMonthCost = lastMonthTokens > 0 ? (lastMonthTokens / (totalInputTokens + totalOutputTokens) * totalCost) : 0;
157
138
 
158
139
  // 获取每日数据(用于趋势图)
159
140
  const dailyData = dailyTokens.slice(-7).map(day => ({
@@ -276,13 +257,6 @@ function main() {
276
257
  console.log('');
277
258
 
278
259
  // 统计数据
279
- console.log('💰 Token 价格说明');
280
- console.log('─'.repeat(40));
281
- console.log(' Input: $3.00 / 百万 tokens');
282
- console.log(' Output: $15.00 / 百万 tokens');
283
- console.log(' Cache: $0.30 / 百万 tokens (90% 折扣)');
284
- console.log('');
285
-
286
260
  console.log('📆 本周消费');
287
261
  console.log('─'.repeat(40));
288
262
  console.log(` Tokens: ${formatNumber(stats.week_tokens)}`);