@winston.wan/burn-your-money 2.0.1

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Token Paranoid Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # 💸 Burn Your Money
2
+
3
+ > **"看着我的钱包燃烧"** - Claude Code 用户的真实写照
4
+
5
+ ![GitHub](https://img.shields.io/github/license/winston-wwzhen/burn-your-money)
6
+ ![Shell](https://img.shields.io/badge/shell-bash-blue)
7
+ ![Claude Code](https://img.shields.io/badge/Claude%20Code-2.1.7+-purple)
8
+
9
+ 一个 **为烧钱党准备** 的 Claude Code 状态栏插件,实时看着你的 tokens(钱)燃烧——因为知情是痛苦的第一步。
10
+
11
+ ## 🔥 为什么要用?
12
+
13
+ Claude Code 会默默地烧掉你的钱,而你甚至感觉不到...
14
+
15
+ - 💸 **实时烧钱速度** - 看着当前会话费用增长
16
+ - 📊 **已烧多少?** - Token 使用量一目了然
17
+ - 📈 **今日战绩** - 历史统计,不再糊涂
18
+ - 💀 **总计伤害** - 累计花费,刺激你的神经
19
+
20
+ ## ✨ 功能展示
21
+
22
+ ```
23
+ [glm-4.7] 今日:78.2K $0.47 | 总计:285.1M $20.12
24
+ ```
25
+
26
+ - 🔥 **今日 Token** - 今天烧掉的 tokens
27
+ - 🔤 **模型名称** - 当前在烧哪个模型
28
+ - 📊 **总计 Token** - 历史累计 tokens
29
+ - 💰 **今日费用** - 今天花了多少钱
30
+
31
+ ## 🚀 快速安装
32
+
33
+ ### Windows
34
+
35
+ **方法 1: PowerShell**
36
+ ```powershell
37
+ # PowerShell 使用分号分隔命令
38
+ curl.exe -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main/install.sh -o install.sh; bash install.sh
39
+ ```
40
+
41
+ **方法 2: Git Bash(推荐)**
42
+ ```bash
43
+ curl -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main/install.sh | bash
44
+ ```
45
+
46
+ ### Linux/macOS/Git Bash
47
+
48
+ ```bash
49
+ curl -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main/install.sh | bash
50
+ ```
51
+
52
+ ### 方法 2: 手动安装
53
+
54
+ ```bash
55
+ # 克隆仓库
56
+ git clone https://github.com/winston-wwzhen/burn-your-money.git
57
+ cd burn-your-money
58
+
59
+ # 运行安装脚本
60
+ ./install.sh
61
+ ```
62
+
63
+ ### 方法 3: NPM 安装
64
+
65
+ ```bash
66
+ npm install -g @winston.wan/burn-your-money
67
+ ```
68
+
69
+ ## 📋 系统要求
70
+
71
+ - ✅ Claude Code 2.1.6 或更高版本
72
+ - ✅ `jq` - JSON 解析工具
73
+ - ✅ Bash 4.0 或更高版本
74
+
75
+ ### 安装依赖
76
+
77
+ ```bash
78
+ # Ubuntu/Debian
79
+ sudo apt-get install jq
80
+
81
+ # macOS
82
+ brew install jq
83
+
84
+ # Arch Linux
85
+ sudo pacman -S jq
86
+ ```
87
+
88
+ ## 🛠️ 配置
89
+
90
+ 安装后,插件会自动配置 `~/.claude/settings.json`:
91
+
92
+ ```json
93
+ {
94
+ "statusLine": {
95
+ "type": "command",
96
+ "command": "~/.claude/statusline.sh"
97
+ }
98
+ }
99
+ ```
100
+
101
+ 重启 Claude Code 即可看到效果!
102
+
103
+ ## 🎯 自定义
104
+
105
+ ### 修改颜色方案
106
+
107
+ 编辑 `~/.claude/statusline.sh`,找到颜色定义部分:
108
+
109
+ ```bash
110
+ # 修改你喜欢的颜色
111
+ today_color="\\033[0;31m" # 红色(代表燃烧)
112
+ ```
113
+
114
+ ### 调整显示内容
115
+
116
+ 注释掉你不需要的部分:
117
+
118
+ ```bash
119
+ # 不显示总计?注释掉这几行:
120
+ # output+="| \\033[0;90m总计:${total_display}\\033[0m "
121
+ ```
122
+
123
+ ## 📊 数据来源
124
+
125
+ 插件从 Claude Code 的内置数据源获取信息:
126
+
127
+ - **当前会话**: 从 statusline JSON 的 `context_window` 字段
128
+ - **历史统计**: 从 `~/.claude/stats-cache.json`
129
+
130
+ 不需要额外的 API 调用!
131
+
132
+ ## 🐛 故障排除
133
+
134
+ ### 状态栏没有显示?
135
+
136
+ 1. 检查脚本权限:`chmod +x ~/.claude/statusline.sh`
137
+ 2. 手动测试:`echo '{}' | ~/.claude/statusline.sh`
138
+ 3. 检查 Claude Code 版本:`claude --version`(需要 2.1.6+)
139
+
140
+ ### 费用显示不准确?
141
+
142
+ 插件使用以下定价估算(Sonnet 4/4.5):
143
+ - Input: $3.0 / 1M tokens
144
+ - Output: $15.0 / 1M tokens
145
+ - Cache Read: $0.30 / 1M tokens(90% 折扣)
146
+
147
+ 实际费用可能因供应商而异。
148
+
149
+ ## 🤝 贡献
150
+
151
+ 欢迎 PR!特别是:
152
+ - 更多主题/颜色方案
153
+ - 更多数据可视化
154
+ - Bug 修复
155
+
156
+ ## 📝 License
157
+
158
+ MIT License - 详见 [LICENSE](LICENSE)
159
+
160
+ ## 😄 为什么叫 Burn Your Money?
161
+
162
+ 因为每次看 Claude Code 账单,作者都会想:
163
+
164
+ > **"我是不是在烧钱?这玩意儿怎么这么贵?!"**
165
+
166
+ 如果你也有这种感觉...欢迎加入 **Burn Your Money** 俱乐部!🔥
167
+
168
+ ---
169
+
170
+ **P.S.** 这个插件不会减少你的 token 消耗,但至少让你知道钱是怎么烧光的。😅
171
+
172
+ **P.P.S.** 如果你想省钱,试试少用点 `extended thinking` 或者...多写代码少提问?
173
+
174
+ **P.P.P.S.** 开个玩笑,继续用 Claude Code 吧,它很棒!💜
175
+
176
+ **P.P.P.P.S.** 说真的,那些 tokens 烧起来真好看,不是吗?🔥💸
@@ -0,0 +1,382 @@
1
+ #!/bin/bash
2
+ # Burn Your Money CLI - 配置和查询工具
3
+
4
+ VERSION="2.0.0"
5
+ CONFIG_FILE="$HOME/.claude/burn-your-money-config.json"
6
+
7
+ # 颜色定义
8
+ RED='\033[0;31m'
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ BLUE='\033[0;34m'
12
+ PURPLE='\033[0;35m'
13
+ CYAN='\033[0;36m'
14
+ NC='\033[0m'
15
+
16
+ # 显示帮助
17
+ show_help() {
18
+ cat << EOF
19
+ 💸 Burn Your Money v${VERSION} - 看着你的钱包燃烧
20
+
21
+ 用法:
22
+ burn-your-money <command> [options]
23
+
24
+ 统计命令:
25
+ status 查看完整状态
26
+ today 查看今日统计
27
+ week 查看本周统计
28
+ month 查看本月统计
29
+ total 查看总计统计
30
+ chart 显示趋势图表
31
+
32
+ 配置命令:
33
+ theme <name> 切换主题 (fire|ocean|forest|golden)
34
+ alert <amount> 设置每日费用警报
35
+ show-rate <on|off> 显示/隐藏燃烧速度
36
+
37
+ 数据导出:
38
+ export csv 导出为 CSV 格式
39
+ export json 导出为 JSON 格式
40
+
41
+ 其他:
42
+ install 安装/更新插件
43
+ version 显示版本信息
44
+ help 显示此帮助信息
45
+
46
+ 示例:
47
+ burn-your-money status 查看完整状态
48
+ burn-your-money chart 显示趋势图
49
+ burn-your-money theme ocean 切换到海洋主题
50
+ burn-your-money alert 5.0 设置每日警报 $5
51
+ burn-your-money export csv > data.csv
52
+
53
+ GitHub: https://github.com/winston-wwzhen/burn-your-money
54
+ EOF
55
+ }
56
+
57
+ # 显示版本
58
+ show_version() {
59
+ echo "Burn Your Money v${VERSION}"
60
+ }
61
+
62
+ # 显示状态
63
+ cmd_status() {
64
+ echo -e "${PURPLE}💸 Burn Your Money 状态${NC}"
65
+ echo ""
66
+
67
+ # 检查安装状态
68
+ if [ -f "$HOME/.claude/statusline.sh" ]; then
69
+ echo -e "${GREEN}✓ 插件已安装${NC}"
70
+ echo ""
71
+
72
+ # 显示配置
73
+ if [ -f "$CONFIG_FILE" ]; then
74
+ echo "配置:"
75
+ local theme=$(jq -r '.theme // "fire"' "$CONFIG_FILE")
76
+ local alert=$(jq -r '.alert_daily // 10' "$CONFIG_FILE")
77
+ local show_rate=$(jq -r '.show_burn_rate // true' "$CONFIG_FILE")
78
+ echo " 主题: $theme"
79
+ echo " 每日警报: \$$alert"
80
+ echo " 燃烧速度: $show_rate"
81
+ echo ""
82
+ fi
83
+
84
+ # 显示统计数据
85
+ local cache="$HOME/.claude/cache/history-cache.json"
86
+ if [ -f "$cache" ]; then
87
+ local today_t=$(jq -r '.today_tokens // 0' "$cache")
88
+ local today_c=$(jq -r '.today_cost // 0' "$cache")
89
+ local week_t=$(jq -r '.week_tokens // 0' "$cache")
90
+ local week_c=$(jq -r '.week_cost // 0' "$cache")
91
+ local total_t=$(jq -r '.total_tokens_all // 0' "$cache")
92
+ local total_c=$(jq -r '.total_cost // 0' "$cache")
93
+ echo "统计数据:"
94
+ echo -e " ${CYAN}今日${NC}: Token $today_t | 费用 \$$today_c"
95
+ echo -e " ${CYAN}本周${NC}: Token $week_t | 费用 \$$week_c"
96
+ echo -e " ${CYAN}总计${NC}: Token $total_t | 费用 \$$total_c"
97
+ fi
98
+ else
99
+ echo -e "${RED}✗ 插件未安装${NC}"
100
+ echo ""
101
+ echo "运行以下命令安装:"
102
+ echo " curl -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main/install.sh | bash"
103
+ fi
104
+ }
105
+
106
+ # 切换主题
107
+ cmd_theme() {
108
+ local new_theme="$1"
109
+
110
+ if [ -z "$new_theme" ]; then
111
+ if [ -f "$CONFIG_FILE" ]; then
112
+ local current=$(jq -r '.theme // "fire"' "$CONFIG_FILE")
113
+ echo "当前主题: $current"
114
+ else
115
+ echo "当前主题: fire (默认)"
116
+ fi
117
+ echo ""
118
+ echo "可用主题:"
119
+ echo " fire - 🔥 火焰红 (默认)"
120
+ echo " ocean - 🌊 海洋蓝"
121
+ echo " forest - 🌲 森林绿"
122
+ echo " golden - 💰 土豪金"
123
+ return
124
+ fi
125
+
126
+ # 验证主题
127
+ if [[ ! "$new_theme" =~ ^(fire|ocean|forest|golden)$ ]]; then
128
+ echo -e "${RED}错误: 无效的主题 '$new_theme'${NC}"
129
+ echo ""
130
+ echo "可用主题: fire, ocean, forest, golden"
131
+ exit 1
132
+ fi
133
+
134
+ # 更新配置
135
+ mkdir -p "$(dirname "$CONFIG_FILE")"
136
+ if [ -f "$CONFIG_FILE" ]; then
137
+ jq --arg theme "$new_theme" '.theme = $theme' "$CONFIG_FILE" > "$CONFIG_FILE.tmp"
138
+ mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
139
+ else
140
+ jq -n --arg theme "$new_theme" '{theme: $theme}' > "$CONFIG_FILE"
141
+ fi
142
+
143
+ echo -e "${GREEN}主题已切换到: $new_theme${NC}"
144
+ echo "重启 Claude Code 后生效"
145
+ }
146
+
147
+ # 设置警报
148
+ cmd_alert() {
149
+ local amount="$1"
150
+
151
+ if [ -z "$amount" ]; then
152
+ if [ -f "$CONFIG_FILE" ]; then
153
+ local current=$(jq -r '.alert_daily // 10' "$CONFIG_FILE")
154
+ echo "当前每日警报: \$$current"
155
+ else
156
+ echo "当前每日警报: \$10 (默认)"
157
+ fi
158
+ echo ""
159
+ echo "用法: burn-your-money alert <金额>"
160
+ echo "示例: burn-your-money alert 5.0"
161
+ return
162
+ fi
163
+
164
+ # 验证金额
165
+ if ! awk "BEGIN {exit !($amount > 0)}"; then
166
+ echo -e "${RED}错误: 无效的金额 '$amount'${NC}"
167
+ exit 1
168
+ fi
169
+
170
+ # 更新配置
171
+ mkdir -p "$(dirname "$CONFIG_FILE")"
172
+ if [ -f "$CONFIG_FILE" ]; then
173
+ jq --arg amount "$amount" '.alert_daily = ($amount | tonumber)' "$CONFIG_FILE" > "$CONFIG_FILE.tmp"
174
+ mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
175
+ else
176
+ jq -n --arg amount "$amount" '{alert_daily: ($amount | tonumber)}' > "$CONFIG_FILE"
177
+ fi
178
+
179
+ echo -e "${GREEN}每日警报已设置: \$$amount${NC}"
180
+ }
181
+
182
+ # 切换燃烧速度显示
183
+ cmd_show_rate() {
184
+ local value="$1"
185
+
186
+ if [ -z "$value" ]; then
187
+ if [ -f "$CONFIG_FILE" ]; then
188
+ local current=$(jq -r '.show_burn_rate // true' "$CONFIG_FILE")
189
+ echo "燃烧速度显示: $current"
190
+ else
191
+ echo "燃烧速度显示: true (默认)"
192
+ fi
193
+ return
194
+ fi
195
+
196
+ if [[ "$value" != "true" && "$value" != "false" && "$value" != "on" && "$value" != "off" ]]; then
197
+ echo -e "${RED}错误: 请使用 true/false 或 on/off${NC}"
198
+ exit 1
199
+ fi
200
+
201
+ local bool_value="$value"
202
+ [[ "$value" == "on" ]] && bool_value="true"
203
+ [[ "$value" == "off" ]] && bool_value="false"
204
+
205
+ mkdir -p "$(dirname "$CONFIG_FILE")"
206
+ if [ -f "$CONFIG_FILE" ]; then
207
+ jq --arg val "$bool_value" '.show_burn_rate = ($val | tonumber or ($val == "true"))' "$CONFIG_FILE" > "$CONFIG_FILE.tmp"
208
+ mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
209
+ else
210
+ jq -n --arg val "$bool_value" '{show_burn_rate: ($val == "true")}' > "$CONFIG_FILE"
211
+ fi
212
+
213
+ echo -e "${GREEN}燃烧速度显示: $bool_value${NC}"
214
+ }
215
+
216
+ # 显示今日统计
217
+ cmd_today() {
218
+ if [ -f "$HOME/.claude/scripts/token-history.sh" ]; then
219
+ echo -e "${RED}🔥 今日统计:${NC}"
220
+ local tokens=$($HOME/.claude/scripts/token-history.sh today_tokens)
221
+ local cost=$($HOME/.claude/scripts/token-history.sh today_cost)
222
+ echo " Token: $tokens"
223
+ echo " 费用: \$$cost"
224
+ else
225
+ echo -e "${RED}✗ Burn Your Money 未安装${NC}"
226
+ exit 1
227
+ fi
228
+ }
229
+
230
+ # 显示本周统计
231
+ cmd_week() {
232
+ if [ -f "$HOME/.claude/scripts/token-history.sh" ]; then
233
+ echo -e "${BLUE}📊 本周统计:${NC}"
234
+ local tokens=$($HOME/.claude/scripts/token-history.sh week_tokens)
235
+ local cost=$($HOME/.claude/scripts/token-history.sh week_cost)
236
+ echo " Token: $tokens"
237
+ echo " 费用: \$$cost"
238
+ else
239
+ echo -e "${RED}✗ Burn Your Money 未安装${NC}"
240
+ exit 1
241
+ fi
242
+ }
243
+
244
+ # 显示本月统计
245
+ cmd_month() {
246
+ if [ -f "$HOME/.claude/scripts/token-history.sh" ]; then
247
+ echo -e "${PURPLE}📅 本月统计:${NC}"
248
+ local tokens=$($HOME/.claude/scripts/token-history.sh month_tokens)
249
+ local cost=$($HOME/.claude/scripts/token-history.sh month_cost)
250
+ echo " Token: $tokens"
251
+ echo " 费用: \$$cost"
252
+ echo ""
253
+
254
+ local last_tokens=$($HOME/.claude/scripts/token-history.sh last_month_tokens)
255
+ local last_cost=$($HOME/.claude/scripts/token-history.sh last_month_cost)
256
+ echo -e "${CYAN}上月统计:${NC}"
257
+ echo " Token: $last_tokens"
258
+ echo " 费用: \$$last_cost"
259
+
260
+ # 对比
261
+ if [ "$last_tokens" -gt 0 ]; then
262
+ local change=$(awk "BEGIN {printf \"%.1f\", ($tokens - $last_tokens) / $last_tokens * 100}")
263
+ if awk "BEGIN {exit !($tokens > $last_tokens)}"; then
264
+ echo -e " ${RED}↑ 增加 ${change}%${NC}"
265
+ elif awk "BEGIN {exit !($tokens < $last_tokens)}"; then
266
+ echo -e " ${GREEN}↓ 减少 ${change}%${NC}"
267
+ else
268
+ echo " → 持平"
269
+ fi
270
+ fi
271
+ else
272
+ echo -e "${RED}✗ Burn Your Money 未安装${NC}"
273
+ exit 1
274
+ fi
275
+ }
276
+
277
+ # 显示总计统计
278
+ cmd_total() {
279
+ if [ -f "$HOME/.claude/scripts/token-history.sh" ]; then
280
+ local data=$($HOME/.claude/scripts/token-history.sh summary)
281
+ echo -e "${YELLOW}💀 总计统计:${NC}"
282
+ echo " Token: $(echo "$data" | jq -r '.total_tokens_all // 0')"
283
+ echo " 费用: \$(echo "$data" | jq -r '.total_cost // 0')"
284
+ else
285
+ echo -e "${RED}✗ Burn Your Money 未安装${NC}"
286
+ exit 1
287
+ fi
288
+ }
289
+
290
+ # 显示图表
291
+ cmd_chart() {
292
+ if [ -f "$HOME/.claude/scripts/token-history.sh" ]; then
293
+ $HOME/.claude/scripts/token-history.sh chart
294
+ else
295
+ echo -e "${RED}✗ Burn Your Money 未安装${NC}"
296
+ exit 1
297
+ fi
298
+ }
299
+
300
+ # 导出数据
301
+ cmd_export() {
302
+ local format="$1"
303
+
304
+ if [ -z "$format" ]; then
305
+ echo "用法: burn-your-money export <csv|json>"
306
+ exit 1
307
+ fi
308
+
309
+ if [ -f "$HOME/.claude/scripts/token-history.sh" ]; then
310
+ $HOME/.claude/scripts/token-history.sh export "$format"
311
+ else
312
+ echo -e "${RED}✗ Burn Your Money 未安装${NC}"
313
+ exit 1
314
+ fi
315
+ }
316
+
317
+ # 安装插件
318
+ cmd_install() {
319
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
320
+ if [ -f "$SCRIPT_DIR/../install.sh" ]; then
321
+ bash "$SCRIPT_DIR/../install.sh"
322
+ else
323
+ echo "找不到安装脚本"
324
+ exit 1
325
+ fi
326
+ }
327
+
328
+ # 主函数
329
+ main() {
330
+ local command="${1:-help}"
331
+ local arg="$2"
332
+
333
+ case "$command" in
334
+ status)
335
+ cmd_status
336
+ ;;
337
+ today)
338
+ cmd_today
339
+ ;;
340
+ week)
341
+ cmd_week
342
+ ;;
343
+ month)
344
+ cmd_month
345
+ ;;
346
+ total)
347
+ cmd_total
348
+ ;;
349
+ chart)
350
+ cmd_chart
351
+ ;;
352
+ theme)
353
+ cmd_theme "$arg"
354
+ ;;
355
+ alert)
356
+ cmd_alert "$arg"
357
+ ;;
358
+ show-rate)
359
+ cmd_show_rate "$arg"
360
+ ;;
361
+ export)
362
+ cmd_export "$arg"
363
+ ;;
364
+ install)
365
+ cmd_install
366
+ ;;
367
+ version|--version|-v)
368
+ show_version
369
+ ;;
370
+ help|--help|-h)
371
+ show_help
372
+ ;;
373
+ *)
374
+ echo -e "${RED}未知命令: $command${NC}"
375
+ echo ""
376
+ show_help
377
+ exit 1
378
+ ;;
379
+ esac
380
+ }
381
+
382
+ main "$@"
package/install.sh ADDED
@@ -0,0 +1,271 @@
1
+ #!/bin/bash
2
+ # Burn Your Money - 一键安装脚本
3
+ # 用法: curl -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main/install.sh | bash
4
+
5
+ set -e
6
+
7
+ # 颜色定义
8
+ RED='\033[0;31m'
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ BLUE='\033[0;34m'
12
+ PURPLE='\033[0;35m'
13
+ CYAN='\033[0;36m'
14
+ NC='\033[0m' # No Color
15
+
16
+ # 打印带颜色的消息
17
+ print_header() {
18
+ echo ""
19
+ echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
20
+ echo -e "${PURPLE} $1${NC}"
21
+ echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
22
+ echo ""
23
+ }
24
+
25
+ print_step() {
26
+ echo -e "${CYAN}▶ $1${NC}"
27
+ }
28
+
29
+ print_success() {
30
+ echo -e "${GREEN}✓ $1${NC}"
31
+ }
32
+
33
+ print_warning() {
34
+ echo -e "${YELLOW}⚠ $1${NC}"
35
+ }
36
+
37
+ print_error() {
38
+ echo -e "${RED}✗ $1${NC}"
39
+ }
40
+
41
+ # 显示 Logo
42
+ show_logo() {
43
+ echo ""
44
+ echo -e "${RED}"
45
+ echo " ██╗ ██╗███████╗██████╗ ██████╗ ███████╗██████╗ ██████╗ "
46
+ echo " ██║ ██║██╔════╝██╔══██╗██╔═══██╗██╔════╝██╔══██╗██╔══██╗"
47
+ echo " ██║ █╗ ██║█████╗ ██████╔╝██║ ██║█████╗ ██████╔╝██║ ██║"
48
+ echo " ██║███╗██║██╔══╝ ██╔══██╗██║ ██║██╔══╝ ██╔══██╗██║ ██║"
49
+ echo " ╚███╔███╔╝███████╗██████╔╝╚██████╔╝███████╗██████╔╝██████╔╝"
50
+ echo " ╚══╝╚══╝ ╚══════╝╚═════╝ ╚═════╝ ╚══════╝╚═════╝ ╚═════╝ "
51
+ echo ""
52
+ echo -e "${CYAN} 💸 Burn Your Money - 看着你的钱包燃烧${NC}"
53
+ echo ""
54
+ }
55
+
56
+ # 检查依赖
57
+ check_dependencies() {
58
+ print_step "检查依赖..."
59
+
60
+ # 检查 jq
61
+ if ! command -v jq &> /dev/null; then
62
+ print_error "jq 未安装!"
63
+ echo ""
64
+ echo "请先安装 jq:"
65
+ echo " Ubuntu/Debian: sudo apt-get install jq"
66
+ echo " macOS: brew install jq"
67
+ echo " Arch: sudo pacman -S jq"
68
+ echo ""
69
+ exit 1
70
+ fi
71
+ print_success "jq 已安装"
72
+
73
+ # 检查 Claude Code
74
+ if ! command -v claude &> /dev/null; then
75
+ print_warning "Claude Code 未找到"
76
+ else
77
+ CLAUDE_VERSION=$(claude --version 2>/dev/null || echo "unknown")
78
+ print_success "Claude Code 版本: $CLAUDE_VERSION"
79
+ fi
80
+ }
81
+
82
+ # 创建目录结构
83
+ create_directories() {
84
+ print_step "创建目录结构..."
85
+
86
+ mkdir -p ~/.claude/scripts
87
+ mkdir -p ~/.claude/cache
88
+
89
+ print_success "目录已创建"
90
+ }
91
+
92
+ # 从 GitHub 下载文件
93
+ download_file() {
94
+ local url="$1"
95
+ local dest="$2"
96
+ local max_retries=3
97
+ local retry=0
98
+
99
+ while [ $retry -lt $max_retries ]; do
100
+ if curl -fsSL "$url" -o "$dest" 2>/dev/null; then
101
+ return 0
102
+ fi
103
+ retry=$((retry + 1))
104
+ if [ $retry -lt $max_retries ]; then
105
+ sleep 1
106
+ fi
107
+ done
108
+ return 1
109
+ }
110
+
111
+ # 安装脚本文件
112
+ install_scripts() {
113
+ print_step "安装脚本文件..."
114
+
115
+ # 获取脚本目录
116
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
117
+
118
+ # 检查本地文件是否存在
119
+ local use_remote=false
120
+ if [ ! -f "$SCRIPT_DIR/src/statusline.sh" ] || [ ! -f "$SCRIPT_DIR/src/token-history.sh" ]; then
121
+ print_warning "本地脚本文件不存在,从 GitHub 下载..."
122
+ use_remote=true
123
+ fi
124
+
125
+ # GitHub 原始文件 URL 基础路径
126
+ local BASE_URL="https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main"
127
+
128
+ # 安装 statusline.sh
129
+ if [ "$use_remote" = true ]; then
130
+ print_step "下载 statusline.sh..."
131
+ if download_file "$BASE_URL/src/statusline.sh" ~/.claude/statusline.sh; then
132
+ chmod +x ~/.claude/statusline.sh
133
+ print_success "statusline.sh 已下载并安装"
134
+ else
135
+ print_error "下载 statusline.sh 失败,请检查网络连接"
136
+ exit 1
137
+ fi
138
+ else
139
+ cp "$SCRIPT_DIR/src/statusline.sh" ~/.claude/statusline.sh
140
+ chmod +x ~/.claude/statusline.sh
141
+ print_success "statusline.sh 已安装"
142
+ fi
143
+
144
+ # 安装 token-history.sh
145
+ mkdir -p ~/.claude/scripts
146
+ if [ "$use_remote" = true ]; then
147
+ print_step "下载 token-history.sh..."
148
+ if download_file "$BASE_URL/src/token-history.sh" ~/.claude/scripts/token-history.sh; then
149
+ chmod +x ~/.claude/scripts/token-history.sh
150
+ print_success "token-history.sh 已下载并安装"
151
+ else
152
+ print_error "下载 token-history.sh 失败,请检查网络连接"
153
+ exit 1
154
+ fi
155
+ else
156
+ cp "$SCRIPT_DIR/src/token-history.sh" ~/.claude/scripts/token-history.sh
157
+ chmod +x ~/.claude/scripts/token-history.sh
158
+ print_success "token-history.sh 已安装"
159
+ fi
160
+ }
161
+
162
+ # 配置 settings.json
163
+ configure_settings() {
164
+ print_step "配置 Claude Code..."
165
+
166
+ SETTINGS_FILE="$HOME/.claude/settings.json"
167
+
168
+ # 如果文件不存在,创建一个
169
+ if [ ! -f "$SETTINGS_FILE" ]; then
170
+ echo "{}" > "$SETTINGS_FILE"
171
+ fi
172
+
173
+ # 使用 jq 添加 statusline 配置
174
+ if command -v jq &> /dev/null; then
175
+ tmp_file=$(mktemp)
176
+ jq '.statusLine = {"type": "command", "command": "~/.claude/statusline.sh"}' "$SETTINGS_FILE" > "$tmp_file"
177
+ mv "$tmp_file" "$SETTINGS_FILE"
178
+ print_success "settings.json 已更新"
179
+ else
180
+ print_warning "无法自动更新 settings.json,请手动添加:"
181
+ echo ""
182
+ echo '{
183
+ "statusLine": {
184
+ "type": "command",
185
+ "command": "~/.claude/statusline.sh"
186
+ }
187
+ }'
188
+ echo ""
189
+ fi
190
+ }
191
+
192
+ # 测试安装
193
+ test_installation() {
194
+ print_step "测试安装..."
195
+
196
+ # 测试 statusline 脚本
197
+ test_json='{
198
+ "model": {"display_name": "Test"},
199
+ "context_window": {
200
+ "total_input_tokens": 10000,
201
+ "total_output_tokens": 2000,
202
+ "context_window_size": 200000,
203
+ "used_percentage": 6,
204
+ "remaining_percentage": 94
205
+ },
206
+ "cost": {"total_cost_usd": 0.05}
207
+ }'
208
+
209
+ if output=$(echo "$test_json" | ~/.claude/statusline.sh 2>/dev/null); then
210
+ print_success "statusline 脚本工作正常"
211
+ echo " 输出: $output"
212
+ else
213
+ print_error "statusline 脚本测试失败"
214
+ return 1
215
+ fi
216
+
217
+ # 测试 token-history 脚本
218
+ if ~/.claude/scripts/token-history.sh summary > /dev/null 2>&1; then
219
+ print_success "token-history 脚本工作正常"
220
+ else
221
+ print_warning "token-history 脚本测试失败(可能没有历史数据)"
222
+ fi
223
+ }
224
+
225
+ # 显示完成信息
226
+ show_completion() {
227
+ print_header "安装完成!"
228
+
229
+ echo -e "${GREEN}Burn Your Money 已成功安装!${NC}"
230
+ echo ""
231
+ echo "📝 已安装的文件:"
232
+ echo " • ~/.claude/statusline.sh"
233
+ echo " • ~/.claude/scripts/token-history.sh"
234
+ echo ""
235
+ echo "🔧 已更新配置:"
236
+ echo " • ~/.claude/settings.json"
237
+ echo ""
238
+ echo -e "${YELLOW}下一步:${NC}"
239
+ echo " 1. 重启 Claude Code"
240
+ echo " 2. 观察状态栏是否显示 Token 信息"
241
+ echo ""
242
+ echo -e "${CYAN}如果状态栏没有显示,请检查:${NC}"
243
+ echo " • Claude Code 版本是否 >= 2.1.6"
244
+ echo " • 运行: claude --version"
245
+ echo ""
246
+ echo -e "${PURPLE}反馈与支持:${NC}"
247
+ echo " • GitHub: https://github.com/winston-wwzhen/burn-your-money"
248
+ echo " • Issues: https://github.com/winston-wwzhen/burn-your-money/issues"
249
+ echo ""
250
+ }
251
+
252
+ # 主函数
253
+ main() {
254
+ show_logo
255
+
256
+ print_header "开始安装 Burn Your Money..."
257
+
258
+ check_dependencies
259
+ create_directories
260
+ install_scripts
261
+ configure_settings
262
+ test_installation
263
+
264
+ show_completion
265
+
266
+ echo -e "${GREEN}开始烧钱吧!🔥💸${NC}"
267
+ echo ""
268
+ }
269
+
270
+ # 运行主函数
271
+ main
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@winston.wan/burn-your-money",
3
+ "version": "2.0.1",
4
+ "description": "💸 Burn Your Money - 实时显示 Claude Code 的 token 消耗,看着你的钱包燃烧!",
5
+ "main": "src/statusline.sh",
6
+ "bin": {
7
+ "burn-your-money": "./bin/burn-your-money"
8
+ },
9
+ "scripts": {
10
+ "install": "bash ./install.sh",
11
+ "test": "bash ./test.sh"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/winston-wwzhen/burn-your-money.git"
16
+ },
17
+ "keywords": [
18
+ "claude-code",
19
+ "token-monitor",
20
+ "statusline",
21
+ "claude",
22
+ "ai",
23
+ "cost-tracker",
24
+ "burn-money"
25
+ ],
26
+ "author": "winston-wwzhen",
27
+ "license": "MIT",
28
+ "bugs": {
29
+ "url": "https://github.com/winston-wwzhen/burn-your-money/issues"
30
+ },
31
+ "homepage": "https://github.com/winston-wwzhen/burn-your-money#readme"
32
+ }
@@ -0,0 +1,205 @@
1
+ #!/bin/bash
2
+ # Burn Your Money - Claude Code 状态栏脚本
3
+ # 格式:[模型] 今日:token 费用 🔥速度 | 总计:token 费用
4
+
5
+ # 配置文件
6
+ CONFIG_FILE="$HOME/.claude/burn-your-money-config.json"
7
+ SESSION_STATE="$HOME/.claude/cache/session-state.json"
8
+
9
+ # 初始化配置
10
+ init_config() {
11
+ if [ ! -f "$CONFIG_FILE" ]; then
12
+ jq -n '{
13
+ theme: "fire",
14
+ alert_daily: 10.0,
15
+ alert_weekly: 50.0,
16
+ show_burn_rate: true,
17
+ show_eta: true,
18
+ show_trend: false
19
+ }' > "$CONFIG_FILE"
20
+ fi
21
+ }
22
+
23
+ # 读取配置
24
+ init_config
25
+ THEME=$(jq -r '.theme // "fire"' "$CONFIG_FILE")
26
+ ALERT_DAILY=$(jq -r '.alert_daily // 10' "$CONFIG_FILE")
27
+ SHOW_BURN_RATE=$(jq -r '.show_burn_rate // true' "$CONFIG_FILE")
28
+ SHOW_ETA=$(jq -r '.show_eta // true' "$CONFIG_FILE")
29
+
30
+ # 主题颜色定义
31
+ case "$THEME" in
32
+ fire)
33
+ TODAY_COLOR="0;31" # 红色
34
+ COST_COLOR="0;31" # 红色
35
+ BURN_COLOR="0;31" # 红色
36
+ ;;
37
+ ocean)
38
+ TODAY_COLOR="0;34" # 蓝色
39
+ COST_COLOR="0;36" # 青色
40
+ BURN_COLOR="0;36" # 青色
41
+ ;;
42
+ forest)
43
+ TODAY_COLOR="0;32" # 绿色
44
+ COST_COLOR="0;33" # 黄色
45
+ BURN_COLOR="0;32" # 绿色
46
+ ;;
47
+ golden)
48
+ TODAY_COLOR="0;33" # 黄色
49
+ COST_COLOR="0;33" # 黄色
50
+ BURN_COLOR="1;33" # 亮黄色
51
+ ;;
52
+ *)
53
+ TODAY_COLOR="0;36" # 默认青色
54
+ COST_COLOR="0;34" # 默认蓝色
55
+ BURN_COLOR="0;31" # 默认红色
56
+ ;;
57
+ esac
58
+
59
+ # 格式化数字(添加 K/M 后缀)
60
+ format_number() {
61
+ local num=$1
62
+ if [ "$num" -ge 1000000000 ]; then
63
+ awk "BEGIN {printf \"%.1fB\", $num/1000000000}"
64
+ elif [ "$num" -ge 1000000 ]; then
65
+ awk "BEGIN {printf \"%.1fM\", $num/1000000}"
66
+ elif [ "$num" -ge 1000 ]; then
67
+ awk "BEGIN {printf \"%.1fK\", $num/1000}"
68
+ else
69
+ echo "$num"
70
+ fi
71
+ }
72
+
73
+ # 格式化费用
74
+ format_cost() {
75
+ local cost=$1
76
+ awk "BEGIN {printf \"\$%.2f\", $cost}"
77
+ }
78
+
79
+ # 格式化燃烧速度
80
+ format_burn_rate() {
81
+ local rate=$1
82
+ if [ "$rate" -ge 1000 ]; then
83
+ awk "BEGIN {printf \"%.1fK tok/s\", $rate/1000}"
84
+ else
85
+ awk "BEGIN {printf \"%.0f tok/s\", $rate}"
86
+ fi
87
+ }
88
+
89
+ # 获取或创建会话状态
90
+ get_session_start_time() {
91
+ local session_id=$(jq -r '.session_id // "default"' "$TEMP_JSON" 2>/dev/null || echo "default")
92
+ local now=$(date +%s)
93
+
94
+ if [ -f "$SESSION_STATE" ]; then
95
+ local cached_id=$(jq -r '.session_id // ""' "$SESSION_STATE" 2>/dev/null || echo "")
96
+ local cached_time=$(jq -r '.start_time // 0' "$SESSION_STATE" 2>/dev/null || echo "0")
97
+
98
+ if [ "$cached_id" = "$session_id" ] && [ "$cached_time" -gt 0 ]; then
99
+ echo "$cached_time"
100
+ return
101
+ fi
102
+ fi
103
+
104
+ # 新会话,记录开始时间
105
+ echo "$now"
106
+ jq -n --arg id "$session_id" --arg time "$now" '{session_id: $id, start_time: ($time | tonumber)}' > "$SESSION_STATE"
107
+ echo "$now"
108
+ }
109
+
110
+ # 主逻辑:使用临时文件存储 stdin
111
+ TEMP_JSON=$(mktemp)
112
+ trap "rm -f $TEMP_JSON" EXIT
113
+ cat > "$TEMP_JSON"
114
+
115
+ # 读取模型名称
116
+ model=$(jq -r '.model.display_name // "Unknown"' "$TEMP_JSON" 2>/dev/null || echo "Unknown")
117
+
118
+ # 读取当前会话的 token 数据(从 context_window)
119
+ current_input=$(jq -r '.context_window.total_input_tokens // 0' "$TEMP_JSON" 2>/dev/null || echo "0")
120
+ current_output=$(jq -r '.context_window.total_output_tokens // 0' "$TEMP_JSON" 2>/dev/null || echo "0")
121
+ current_session_tokens=$((current_input + current_output))
122
+
123
+ # 计算燃烧速度
124
+ session_start=$(get_session_start_time)
125
+ current_time=$(date +%s)
126
+ elapsed=$((current_time - session_start))
127
+
128
+ if [ "$elapsed" -gt 0 ] && [ "$current_session_tokens" -gt 0 ]; then
129
+ burn_rate=$(awk "BEGIN {printf \"%.0f\", ${current_session_tokens} / ${elapsed}}")
130
+ else
131
+ burn_rate=0
132
+ fi
133
+
134
+ # 获取历史数据(缓存 30 秒)
135
+ history_cache="$HOME/.claude/cache/history-cache.json"
136
+ now=$(date +%s)
137
+ cache_age=999999
138
+ if [ -f "$history_cache" ]; then
139
+ cache_time=$(stat -c %Y "$history_cache" 2>/dev/null || stat -f %m "$history_cache" 2>/dev/null || echo "0")
140
+ cache_age=$((now - cache_time))
141
+ fi
142
+
143
+ if [ $cache_age -gt 30 ]; then
144
+ ~/.claude/scripts/token-history.sh summary > "$history_cache" 2>/dev/null || echo '{}' > "$history_cache"
145
+ fi
146
+
147
+ # 读取历史数据并加上当前会话
148
+ history_today_tokens=$(jq -r '.today_tokens // 0' "$history_cache" 2>/dev/null || echo "0")
149
+ history_today_cost=$(jq -r '.today_cost // 0' "$history_cache" 2>/dev/null || echo "0")
150
+
151
+ # 今日数据 = 历史数据 + 当前会话
152
+ today_tokens=$((history_today_tokens + current_session_tokens))
153
+ # 简单估算今日费用(按比例)
154
+ if [ "$history_today_tokens" -gt 0 ] && [ "$history_today_cost" != "0" ]; then
155
+ today_cost=$(awk "BEGIN {printf \"%.2f\", ${history_today_cost} / ${history_today_tokens} * ${today_tokens}}")
156
+ elif [ "$today_tokens" -gt 0 ]; then
157
+ # 如果没有历史费用数据,用平均价格估算
158
+ today_cost=$(awk "BEGIN {printf \"%.2f\", ${today_tokens} * 0.000006}")
159
+ else
160
+ today_cost="0.00"
161
+ fi
162
+
163
+ total_tokens_all=$(jq -r '.total_tokens_all // 0' "$history_cache" 2>/dev/null || echo "0")
164
+ total_cost=$(jq -r '.week_cost // 0' "$history_cache" 2>/dev/null || echo "0")
165
+
166
+ # 检查费用警报
167
+ alert_needed=false
168
+ if awk "BEGIN {exit !($today_cost >= $ALERT_DAILY)}"; then
169
+ alert_needed=true
170
+ fi
171
+
172
+ # 构建输出
173
+ output=""
174
+
175
+ # 模型名称
176
+ if [ "$alert_needed" = true ]; then
177
+ output+="\\033[1;31m[$model]\\033[0m " # 红色闪烁
178
+ else
179
+ output+="\\033[0;90m[$model]\\033[0m "
180
+ fi
181
+
182
+ # 今日数据
183
+ today_display=$(format_number $today_tokens)
184
+ today_cost_display=$(format_cost $today_cost)
185
+ if [ "$today_tokens" -gt 0 ] || awk "BEGIN {exit !($today_cost > 0)}"; then
186
+ output+="\\033[${TODAY_COLOR}m今日:${today_display}\\033[0m "
187
+ output+="\\033[${COST_COLOR}m${today_cost_display}\\033[0m "
188
+ else
189
+ output+="\\033[0;90m今日:0\\033[0m "
190
+ output+="\\033[0;90m\$0.00\\033[0m "
191
+ fi
192
+
193
+ # 燃烧速度
194
+ if [ "$SHOW_BURN_RATE" = true ] && [ "$burn_rate" -gt 0 ]; then
195
+ burn_display=$(format_burn_rate $burn_rate)
196
+ output+="\\033[${BURN_COLOR}m🔥${burn_display}\\033[0m "
197
+ fi
198
+
199
+ # 总计数据
200
+ total_display=$(format_number $total_tokens_all)
201
+ total_cost_display=$(format_cost $total_cost)
202
+ output+="| \\033[0;90m总计:${total_display}\\033[0m "
203
+ output+="\\033[0;90m${total_cost_display}\\033[0m "
204
+
205
+ printf "%b" "$output"
@@ -0,0 +1,238 @@
1
+ #!/bin/bash
2
+ # Burn Your Money - Token 历史统计脚本
3
+ # 从 stats-cache.json 读取历史数据,返回今日/本周/本月统计
4
+
5
+ set -e
6
+
7
+ # 文件路径
8
+ STATS_CACHE="$HOME/.claude/stats-cache.json"
9
+ TODAY=$(date +%Y-%m-%d)
10
+ CURRENT_MONTH=$(date +%Y-%m)
11
+ LAST_MONTH=$(date -d "1 month ago" +%Y-%m 2>/dev/null || python3 -c "from datetime import datetime; print((datetime.now().replace(day=1) - __import__('datetime').timedelta(days=1)).strftime('%Y-%m'))")
12
+
13
+ # 获取本周一的日期
14
+ get_week_start() {
15
+ local day_of_week=$(date +%u) # 1=Monday, 7=Sunday
16
+ local days_to_subtract=$((day_of_week - 1))
17
+ date -d "$days_to_subtract days ago" +%Y-%m-%d 2>/dev/null || \
18
+ python3 -c "from datetime import datetime, timedelta; d = datetime.now() - timedelta(days=$(date +%u) - 1); print(d.strftime('%Y-%m-%d'))"
19
+ }
20
+
21
+ # 获取本月第一天
22
+ get_month_start() {
23
+ date +%Y-%m-01
24
+ }
25
+
26
+ WEEK_START=$(get_week_start)
27
+ MONTH_START=$(get_month_start)
28
+ LAST_MONTH_START=$(date -d "$LAST_MONTH-01" +%Y-%m-%d 2>/dev/null || echo "$LAST_MONTH-01")
29
+
30
+ # 从 stats-cache.json 读取统计数据
31
+ read_stats() {
32
+ if [ ! -f "$STATS_CACHE" ]; then
33
+ jq -n '{
34
+ today_tokens:0,today_cost:0,
35
+ week_tokens:0,week_cost:0,
36
+ month_tokens:0,month_cost:0,
37
+ last_month_tokens:0,last_month_cost:0,
38
+ total_tokens_all:0,total_cost:0,
39
+ daily_data: []
40
+ }'
41
+ return
42
+ fi
43
+
44
+ # 定价
45
+ local cost_per_m_input=3.0
46
+ local cost_per_m_output=15.0
47
+
48
+ # 获取今日 token:总计 - 历史每日总和(排除今天)
49
+ local total_io_tokens=$(jq -r '[.modelUsage["glm-4.7"].inputTokens, .modelUsage["glm-4.7"].outputTokens] | add // 0' "$STATS_CACHE" 2>/dev/null || echo "0")
50
+ local history_sum=$(jq -r "[.dailyModelTokens[] | select(.date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" "$STATS_CACHE" 2>/dev/null || echo "0")
51
+ local today_data=$((total_io_tokens - history_sum))
52
+ [ "$today_data" -lt 0 ] && today_data=0
53
+
54
+ # 本周 token(排除今天,用上面的 today_data)
55
+ local week_tokens=$(jq -r "[.dailyModelTokens[] | select(.date >= \"$WEEK_START\" and .date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" "$STATS_CACHE" 2>/dev/null || echo "0")
56
+ week_tokens=$((week_tokens + today_data))
57
+
58
+ # 本月 token
59
+ local month_tokens=$(jq -r "[.dailyModelTokens[] | select(.date >= \"$MONTH_START\" and .date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" "$STATS_CACHE" 2>/dev/null || echo "0")
60
+ month_tokens=$((month_tokens + today_data))
61
+
62
+ # 上月 token
63
+ local last_month_tokens=$(jq -r "[.dailyModelTokens[] | select(.date >= \"$LAST_MONTH_START\" and .date < \"$MONTH_START\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" "$STATS_CACHE" 2>/dev/null || echo "0")
64
+
65
+ # 计算全部历史费用
66
+ local total_input=$(jq -r '.modelUsage["glm-4.7"].inputTokens // 0' "$STATS_CACHE" 2>/dev/null || echo "0")
67
+ local total_output=$(jq -r '.modelUsage["glm-4.7"].outputTokens // 0' "$STATS_CACHE" 2>/dev/null || echo "0")
68
+ local total_cache_read=$(jq -r '.modelUsage["glm-4.7"].cacheReadInputTokens // 0' "$STATS_CACHE" 2>/dev/null || echo "0")
69
+ local total_cost=$(awk "BEGIN {input_cost = ${total_input} / 1000000 * ${cost_per_m_input}; output_cost = ${total_output} / 1000000 * ${cost_per_m_output}; cache_cost = ${total_cache_read} / 1000000 * ${cost_per_m_input} * 0.1; printf \"%.2f\", input_cost + output_cost + cache_cost}")
70
+
71
+ # 总 token 数量(包含 cache)
72
+ local total_tokens_all=$((total_input + total_output + total_cache_read))
73
+
74
+ # 计算各周期费用(按比例分摊)
75
+ local week_cost="0.00"
76
+ local month_cost="0.00"
77
+ local last_month_cost="0.00"
78
+ local today_cost="0.00"
79
+
80
+ if [ "$total_io_tokens" != "0" ] && [ "$total_io_tokens" != "" ]; then
81
+ week_cost=$(awk "BEGIN {printf \"%.2f\", ${week_tokens} / ${total_io_tokens} * ${total_cost}}")
82
+ month_cost=$(awk "BEGIN {printf \"%.2f\", ${month_tokens} / ${total_io_tokens} * ${total_cost}}")
83
+ if [ "$last_month_tokens" -gt 0 ]; then
84
+ last_month_cost=$(awk "BEGIN {printf \"%.2f\", ${last_month_tokens} / ${total_io_tokens} * ${total_cost}}")
85
+ fi
86
+ else
87
+ week_cost=$total_cost
88
+ month_cost=$total_cost
89
+ fi
90
+
91
+ if [ "$week_tokens" != "0" ] && [ "$week_tokens" != "" ]; then
92
+ today_cost=$(awk "BEGIN {printf \"%.2f\", ${today_data} / ${week_tokens} * ${week_cost}}")
93
+ fi
94
+
95
+ # 获取每日数据(用于趋势图)
96
+ local daily_data=$(jq -c "[.dailyModelTokens[-7:][] | {date: .date, tokens: (.tokensByModel[\"glm-4.7\"] // 0)}]" "$STATS_CACHE" 2>/dev/null || echo "[]")
97
+
98
+ # 输出 JSON
99
+ jq -n \
100
+ --arg today_tokens "$today_data" \
101
+ --arg today_cost "$today_cost" \
102
+ --arg week_tokens "$week_tokens" \
103
+ --arg week_cost "$week_cost" \
104
+ --arg month_tokens "$month_tokens" \
105
+ --arg month_cost "$month_cost" \
106
+ --arg last_month_tokens "$last_month_tokens" \
107
+ --arg last_month_cost "$last_month_cost" \
108
+ --arg total_tokens_all "$total_tokens_all" \
109
+ --arg total_cost "$total_cost" \
110
+ --argjson daily_data "$daily_data" \
111
+ '{
112
+ today_tokens: ($today_tokens | tonumber),
113
+ today_cost: ($today_cost | tonumber),
114
+ week_tokens: ($week_tokens | tonumber),
115
+ week_cost: ($week_cost | tonumber),
116
+ month_tokens: ($month_tokens | tonumber),
117
+ month_cost: ($month_cost | tonumber),
118
+ last_month_tokens: ($last_month_tokens | tonumber),
119
+ last_month_cost: ($last_month_cost | tonumber),
120
+ total_tokens_all: ($total_tokens_all | tonumber),
121
+ total_cost: ($total_cost | tonumber),
122
+ daily_data: $daily_data
123
+ }'
124
+ }
125
+
126
+ # 生成 ASCII 趋势图
127
+ generate_trend() {
128
+ local data="$1"
129
+ local max_tokens=0
130
+
131
+ # 找到最大值
132
+ for row in $(echo "$data" | jq -r '.[].tokens'); do
133
+ if [ "$row" -gt "$max_tokens" ]; then
134
+ max_tokens=$row
135
+ fi
136
+ done
137
+
138
+ # 生成图表
139
+ echo ""
140
+ echo "📊 过去 7 天 Token 趋势:"
141
+ echo ""
142
+
143
+ local count=0
144
+ for entry in $(echo "$data" | jq -c '.[]'); do
145
+ local date=$(echo "$entry" | jq -r '.date' | cut -c 6-)
146
+ local tokens=$(echo "$entry" | jq -r '.tokens')
147
+
148
+ # 计算条形长度
149
+ if [ "$max_tokens" -gt 0 ]; then
150
+ local bars=$(awk "BEGIN {printf \"%.0f\", $tokens / $max_tokens * 20}")
151
+ else
152
+ local bars=0
153
+ fi
154
+
155
+ # 生成条形
156
+ local bar=""
157
+ for i in $(seq 1 20); do
158
+ if [ "$i" -le "$bars" ]; then
159
+ bar+="█"
160
+ else
161
+ bar+="░"
162
+ fi
163
+ done
164
+
165
+ # 格式化 token 数量
166
+ local tokens_display=$(echo "$tokens" | awk '{
167
+ if ($1 >= 1000000) printf "%.1fM", $1/1000000
168
+ else if ($1 >= 1000) printf "%.1fK", $1/1000
169
+ else printf "%d", $1
170
+ }')
171
+
172
+ printf " %s │ %s │ %s\n" "$date" "$bar" "$tokens_display"
173
+ count=$((count + 1))
174
+ done
175
+ echo ""
176
+ }
177
+
178
+ # 导出数据
179
+ export_data() {
180
+ local format="$1"
181
+ local stats=$(read_stats)
182
+
183
+ case "$format" in
184
+ csv)
185
+ echo "date,tokens,cost"
186
+ echo "$stats" | jq -r '.daily_data[] | "\(.date),\(.tokens),\(.tokens * 0.000006)"'
187
+ ;;
188
+ json)
189
+ echo "$stats" | jq '.'
190
+ ;;
191
+ *)
192
+ echo "支持的格式: csv, json"
193
+ exit 1
194
+ ;;
195
+ esac
196
+ }
197
+
198
+ # 根据 mode 返回不同数据
199
+ MODE=${1:-summary}
200
+
201
+ case "$MODE" in
202
+ today_tokens)
203
+ read_stats | jq -r '.today_tokens'
204
+ ;;
205
+ today_cost)
206
+ read_stats | jq -r '.today_cost'
207
+ ;;
208
+ week_tokens)
209
+ read_stats | jq -r '.week_tokens'
210
+ ;;
211
+ week_cost)
212
+ read_stats | jq -r '.week_cost'
213
+ ;;
214
+ month_tokens)
215
+ read_stats | jq -r '.month_tokens'
216
+ ;;
217
+ month_cost)
218
+ read_stats | jq -r '.month_cost'
219
+ ;;
220
+ last_month_tokens)
221
+ read_stats | jq -r '.last_month_tokens'
222
+ ;;
223
+ last_month_cost)
224
+ read_stats | jq -r '.last_month_cost'
225
+ ;;
226
+ trend)
227
+ read_stats | jq -r '.daily_data'
228
+ ;;
229
+ chart)
230
+ generate_trend "$(read_stats | jq -r '.daily_data')"
231
+ ;;
232
+ export)
233
+ export_data "$2"
234
+ ;;
235
+ summary|json|*)
236
+ read_stats
237
+ ;;
238
+ esac