@winston.wan/burn-your-money 2.0.4 → 2.1.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/README.md +71 -113
- package/bash.exe.stackdump +28 -0
- package/bin/burn-your-money +40 -20
- package/docs/ARCHITECTURE.md +58 -0
- package/docs/images/architecture_sketch.png +0 -0
- package/fix-git-bash.ps1 +154 -0
- package/install.js +254 -25
- package/package.json +3 -2
- package/src/statusline.sh +250 -205
- package/src/token-history.sh +268 -238
- package/uninstall.js +94 -0
package/README.md
CHANGED
|
@@ -1,42 +1,55 @@
|
|
|
1
1
|
# 💸 Burn Your Money
|
|
2
2
|
|
|
3
|
-
> **"
|
|
3
|
+
> **"Watch your bank account drain in real-time."**
|
|
4
|
+
> **"看着你的存款实时归零。"**
|
|
4
5
|
|
|
5
|
-

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
A **Claude Code** status line plugin that displays your token usage and costs in real-time. Because awareness is the first step towards pain.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
一个为 **Claude Code** 准备的状态栏插件。它能让你实时看到每一秒花了多少钱——因为知情是痛苦的第一步。
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 🔥 The "Why" (English)
|
|
18
|
+
|
|
19
|
+
Using Claude Code feels like coding with superpowers. It also feels like standing in front of a cash incinerator.
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
21
|
+
This plugin adds a simple, Anxiety-Inducing™ meter to your terminal:
|
|
22
|
+
- **Real-time Burn Rate**: See exactly how many tokens/sec you are wasting.
|
|
23
|
+
- **Session Cost**: Watch the dollars tick up while you debug that `undefined` error.
|
|
24
|
+
- **Total Damage**: A cumulative record of your poor financial decisions.
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
### 📸 Preview
|
|
21
27
|
|
|
22
28
|
```
|
|
23
|
-
[
|
|
29
|
+
[Claude 3.5 Sonnet] Today: 78.2K $0.47 🔥1.2K tok/s | Total: 285.1M $20.12
|
|
24
30
|
```
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- 💰 **今日费用** - 今天花了多少钱
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🔥 为什么要用?(Chinese)
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
Claude Code 很好用,就像在你的命令行里装了一个核动力引擎。但是每次它思考的时候,我都仿佛听到了碎钞机的声音。
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
这就诞生了 **Burn Your Money**。它能在你的状态栏显示:
|
|
39
|
+
- **实时烧钱速度**:精准显示每秒烧掉多少 token,让你的每一次回车都充满罪恶感。
|
|
40
|
+
- **今日战绩**:看看今天又给 Anthropic 贡献了几杯咖啡。
|
|
41
|
+
- **历史总计**:累计伤害。建议心脏不好的人不要开启此功能。
|
|
34
42
|
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 🚀 Installation / 安装
|
|
46
|
+
|
|
47
|
+
### Option 1: NPM (Recommended / 推荐)
|
|
35
48
|
```bash
|
|
36
49
|
npm install -g "@winston.wan/burn-your-money"
|
|
37
50
|
```
|
|
38
51
|
|
|
39
|
-
###
|
|
52
|
+
### Option 2: Script (Old School / 脚本党)
|
|
40
53
|
|
|
41
54
|
**Linux / macOS / Git Bash**
|
|
42
55
|
```bash
|
|
@@ -45,126 +58,71 @@ curl -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main
|
|
|
45
58
|
|
|
46
59
|
**Windows PowerShell**
|
|
47
60
|
```powershell
|
|
48
|
-
# PowerShell 使用分号分隔命令
|
|
49
61
|
curl.exe -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main/install.sh -o install.sh; bash install.sh
|
|
50
62
|
```
|
|
51
63
|
|
|
52
|
-
|
|
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
|
-
## 📋 系统要求
|
|
64
|
-
|
|
65
|
-
- ✅ Claude Code 2.1.6 或更高版本
|
|
66
|
-
- ✅ `jq` - JSON 解析工具
|
|
67
|
-
- ✅ Bash 4.0 或更高版本
|
|
64
|
+
---
|
|
68
65
|
|
|
69
|
-
|
|
66
|
+
## 🛠️ Performance / 性能
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
# Ubuntu/Debian
|
|
73
|
-
sudo apt-get install jq
|
|
68
|
+
**Global**: "We know API calls are expensive. That's why this plugin makes **ZERO** network requests. All data is calculated locally using basic math. It burns your wallet, not your CPU."
|
|
74
69
|
|
|
75
|
-
|
|
76
|
-
brew install jq
|
|
70
|
+
**中文**: "我们深知现在的 API 有多贵。所以本插件**绝不**发起任何网络请求。所有数据纯本地计算。"
|
|
77
71
|
|
|
78
|
-
|
|
79
|
-
sudo pacman -S jq
|
|
80
|
-
```
|
|
72
|
+
---
|
|
81
73
|
|
|
82
|
-
##
|
|
74
|
+
## ⚙️ Configuration / 配置
|
|
83
75
|
|
|
84
|
-
|
|
76
|
+
Edit `~/.claude/burn-your-money-config.json` to customize your pain level.
|
|
77
|
+
修改配置文件来自定义你的痛苦程度。
|
|
85
78
|
|
|
86
79
|
```json
|
|
87
80
|
{
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
81
|
+
"theme": "fire", // themes: fire, ocean, forest, golden
|
|
82
|
+
"alert_daily": 10.0, // Daily budget (USD). Turns RED when exceeded. / 每日预警金额
|
|
83
|
+
"show_burn_rate": true // Show tokens/sec? / 是否显示燃烧速度
|
|
92
84
|
}
|
|
93
85
|
```
|
|
94
86
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
## 🎯 自定义
|
|
98
|
-
|
|
99
|
-
### 修改颜色方案
|
|
100
|
-
|
|
101
|
-
编辑 `~/.claude/statusline.sh`,找到颜色定义部分:
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
# 修改你喜欢的颜色
|
|
105
|
-
today_color="\\033[0;31m" # 红色(代表燃烧)
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### 调整显示内容
|
|
109
|
-
|
|
110
|
-
注释掉你不需要的部分:
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
# 不显示总计?注释掉这几行:
|
|
114
|
-
# output+="| \\033[0;90m总计:${total_display}\\033[0m "
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## 📊 数据来源
|
|
118
|
-
|
|
119
|
-
插件从 Claude Code 的内置数据源获取信息:
|
|
120
|
-
|
|
121
|
-
- **当前会话**: 从 statusline JSON 的 `context_window` 字段
|
|
122
|
-
- **历史统计**: 从 `~/.claude/stats-cache.json`
|
|
123
|
-
|
|
124
|
-
不需要额外的 API 调用!
|
|
125
|
-
|
|
126
|
-
## 🐛 故障排除
|
|
127
|
-
|
|
128
|
-
### 状态栏没有显示?
|
|
129
|
-
|
|
130
|
-
1. 检查脚本权限:`chmod +x ~/.claude/statusline.sh`
|
|
131
|
-
2. 手动测试:`echo '{}' | ~/.claude/statusline.sh`
|
|
132
|
-
3. 检查 Claude Code 版本:`claude --version`(需要 2.1.6+)
|
|
133
|
-
|
|
134
|
-
### 费用显示不准确?
|
|
87
|
+
---
|
|
135
88
|
|
|
136
|
-
|
|
137
|
-
- Input: $3.0 / 1M tokens
|
|
138
|
-
- Output: $15.0 / 1M tokens
|
|
139
|
-
- Cache Read: $0.30 / 1M tokens(90% 折扣)
|
|
89
|
+
## 📊 Known Issues / 已知问题
|
|
140
90
|
|
|
141
|
-
|
|
91
|
+
1. **Token Count Difference / Token 统计差异**:
|
|
92
|
+
This plugin includes **all token types** (input, output, and cache-read tokens) in its statistics. Claude Code's built-in `/stats` command may only display "full-price" tokens (input + output), excluding cache-read tokens which receive a 90% discount.
|
|
142
93
|
|
|
143
|
-
|
|
94
|
+
本插件统计**包含所有类型的 token**(输入、输出、缓存读取)。Claude Code 内置的 `/stats` 命令可能只显示"完整价格"的 tokens(输入 + 输出),不包含享受 90% 折扣的缓存读取 tokens。
|
|
144
95
|
|
|
145
|
-
|
|
146
|
-
-
|
|
147
|
-
-
|
|
148
|
-
- Bug 修复
|
|
96
|
+
Example / 示例:
|
|
97
|
+
- This plugin / 本插件: `3.93B tokens` (includes cache-read / 包含缓存)
|
|
98
|
+
- `/stats` command: `188M tokens` (excludes cache-read / 不含缓存)
|
|
149
99
|
|
|
150
|
-
|
|
100
|
+
2. **Historical Cost Accuracy / 历史费用准确性**:
|
|
101
|
+
The *historical* cost calculation (in `Total` and `History`) uses a fixed rate estimate (based on Sonnet 3.5). If you frequently switch between Haiku/Opus, the historical dollar amount might be slightly off. (Real-time session cost is always accurate though!)
|
|
102
|
+
*历史*费用统计基于固定费率估算。如果你经常切换不同模型,历史总金额可能不完全准确。(但当前会话的实时扣费是绝对准的!)
|
|
151
103
|
|
|
152
|
-
|
|
104
|
+
3. **Blame Game / 甩锅声明**:
|
|
105
|
+
This entire plugin was written by **Claude Code**. If you find a bug, it's not my fault—it's the AI's fault. Please complain to the next Claude model you talk to.
|
|
106
|
+
本插件的所有代码均由 **Claude Code** 编写。如果你发现了 Bug,那不是我的错,是 AI 的错。请在下一次对话时找 Claude 算账。
|
|
153
107
|
|
|
154
|
-
|
|
108
|
+
---
|
|
155
109
|
|
|
156
|
-
|
|
110
|
+
## �🗑️ Uninstall / 卸载
|
|
157
111
|
|
|
158
|
-
|
|
112
|
+
If the truth is too painful:
|
|
113
|
+
如果现实太过沉重:
|
|
159
114
|
|
|
160
|
-
|
|
115
|
+
```bash
|
|
116
|
+
npm uninstall -g @winston.wan/burn-your-money
|
|
117
|
+
# Then restart Claude Code / 然后重启 Claude Code
|
|
118
|
+
```
|
|
161
119
|
|
|
162
120
|
---
|
|
163
121
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
**P.P.S.** 如果你想省钱,试试少用点 `extended thinking` 或者...多写代码少提问?
|
|
122
|
+
## 😄 Disclaimer / 免责声明
|
|
167
123
|
|
|
168
|
-
|
|
124
|
+
This plugin does not actually reduce your token usage. It only increases your blood pressure.
|
|
125
|
+
本插件并不能通过任何技术手段减少你的 Token 消耗,它只能(显著地)升高你的血压。
|
|
169
126
|
|
|
170
|
-
**
|
|
127
|
+
**Enjoy the burn. 🔥**
|
|
128
|
+
**享受燃烧的感觉吧。🔥**
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Stack trace:
|
|
2
|
+
Frame Function Args
|
|
3
|
+
0007FFFFBF30 00021005FE8E (000210285F68, 00021026AB6E, 000000000000, 0007FFFFAE30) msys-2.0.dll+0x1FE8E
|
|
4
|
+
0007FFFFBF30 0002100467F9 (000000000000, 000000000000, 000000000000, 0007FFFFC208) msys-2.0.dll+0x67F9
|
|
5
|
+
0007FFFFBF30 000210046832 (000210286019, 0007FFFFBDE8, 000000000000, 000000000000) msys-2.0.dll+0x6832
|
|
6
|
+
0007FFFFBF30 000210068CF6 (000000000000, 000000000000, 000000000000, 000000000000) msys-2.0.dll+0x28CF6
|
|
7
|
+
0007FFFFBF30 000210068E24 (0007FFFFBF40, 000000000000, 000000000000, 000000000000) msys-2.0.dll+0x28E24
|
|
8
|
+
0007FFFFC210 00021006A225 (0007FFFFBF40, 000000000000, 000000000000, 000000000000) msys-2.0.dll+0x2A225
|
|
9
|
+
End of stack trace
|
|
10
|
+
Loaded modules:
|
|
11
|
+
000100400000 bash.exe
|
|
12
|
+
7FFAC83A0000 ntdll.dll
|
|
13
|
+
7FFAC7620000 KERNEL32.DLL
|
|
14
|
+
7FFAC57F0000 KERNELBASE.dll
|
|
15
|
+
7FFAC7C30000 USER32.dll
|
|
16
|
+
7FFAC54F0000 win32u.dll
|
|
17
|
+
000210040000 msys-2.0.dll
|
|
18
|
+
7FFAC74C0000 GDI32.dll
|
|
19
|
+
7FFAC5EA0000 gdi32full.dll
|
|
20
|
+
7FFAC5CA0000 msvcp_win.dll
|
|
21
|
+
7FFAC5D50000 ucrtbase.dll
|
|
22
|
+
7FFAC7070000 advapi32.dll
|
|
23
|
+
7FFAC7570000 msvcrt.dll
|
|
24
|
+
7FFAC6140000 sechost.dll
|
|
25
|
+
7FFAC69C0000 RPCRT4.dll
|
|
26
|
+
7FFAC4AF0000 CRYPTBASE.DLL
|
|
27
|
+
7FFAC5BF0000 bcryptPrimitives.dll
|
|
28
|
+
7FFAC7E00000 IMM32.DLL
|
package/bin/burn-your-money
CHANGED
|
@@ -4,6 +4,26 @@
|
|
|
4
4
|
VERSION="2.0.0"
|
|
5
5
|
CONFIG_FILE="$HOME/.claude/burn-your-money-config.json"
|
|
6
6
|
|
|
7
|
+
# 设置 jq 命令路径(支持自定义安装的 jq)
|
|
8
|
+
if [ -n "$JQ_PATH" ]; then
|
|
9
|
+
JQ_CMD="$JQ_PATH"
|
|
10
|
+
elif [ -f "$HOME/.claude/bin/jq.exe" ]; then
|
|
11
|
+
JQ_CMD="$HOME/.claude/bin/jq.exe"
|
|
12
|
+
elif [ -f "$HOME/.claude/bin/jq" ]; then
|
|
13
|
+
JQ_CMD="$HOME/.claude/bin/jq"
|
|
14
|
+
else
|
|
15
|
+
JQ_CMD="jq"
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# 验证 jq 是否可用
|
|
19
|
+
if ! command -v "$JQ_CMD" >/dev/null 2>&1; then
|
|
20
|
+
echo "Error: jq not found. Please install jq first:"
|
|
21
|
+
echo " Windows: npm install -g @winston.wan/burn-your-money"
|
|
22
|
+
echo " macOS: brew install jq"
|
|
23
|
+
echo " Linux: sudo apt-get install jq"
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
7
27
|
# 颜色定义
|
|
8
28
|
RED='\033[0;31m'
|
|
9
29
|
GREEN='\033[0;32m'
|
|
@@ -72,9 +92,9 @@ cmd_status() {
|
|
|
72
92
|
# 显示配置
|
|
73
93
|
if [ -f "$CONFIG_FILE" ]; then
|
|
74
94
|
echo "配置:"
|
|
75
|
-
local theme=$(
|
|
76
|
-
local alert=$(
|
|
77
|
-
local show_rate=$(
|
|
95
|
+
local theme=$($JQ_CMD -r '.theme // "fire"' "$CONFIG_FILE")
|
|
96
|
+
local alert=$($JQ_CMD -r '.alert_daily // 10' "$CONFIG_FILE")
|
|
97
|
+
local show_rate=$($JQ_CMD -r '.show_burn_rate // true' "$CONFIG_FILE")
|
|
78
98
|
echo " 主题: $theme"
|
|
79
99
|
echo " 每日警报: \$$alert"
|
|
80
100
|
echo " 燃烧速度: $show_rate"
|
|
@@ -84,12 +104,12 @@ cmd_status() {
|
|
|
84
104
|
# 显示统计数据
|
|
85
105
|
local cache="$HOME/.claude/cache/history-cache.json"
|
|
86
106
|
if [ -f "$cache" ]; then
|
|
87
|
-
local today_t=$(
|
|
88
|
-
local today_c=$(
|
|
89
|
-
local week_t=$(
|
|
90
|
-
local week_c=$(
|
|
91
|
-
local total_t=$(
|
|
92
|
-
local total_c=$(
|
|
107
|
+
local today_t=$($JQ_CMD -r '.today_tokens // 0' "$cache")
|
|
108
|
+
local today_c=$($JQ_CMD -r '.today_cost // 0' "$cache")
|
|
109
|
+
local week_t=$($JQ_CMD -r '.week_tokens // 0' "$cache")
|
|
110
|
+
local week_c=$($JQ_CMD -r '.week_cost // 0' "$cache")
|
|
111
|
+
local total_t=$($JQ_CMD -r '.total_tokens_all // 0' "$cache")
|
|
112
|
+
local total_c=$($JQ_CMD -r '.total_cost // 0' "$cache")
|
|
93
113
|
echo "统计数据:"
|
|
94
114
|
echo -e " ${CYAN}今日${NC}: Token $today_t | 费用 \$$today_c"
|
|
95
115
|
echo -e " ${CYAN}本周${NC}: Token $week_t | 费用 \$$week_c"
|
|
@@ -109,7 +129,7 @@ cmd_theme() {
|
|
|
109
129
|
|
|
110
130
|
if [ -z "$new_theme" ]; then
|
|
111
131
|
if [ -f "$CONFIG_FILE" ]; then
|
|
112
|
-
local current=$(
|
|
132
|
+
local current=$($JQ_CMD -r '.theme // "fire"' "$CONFIG_FILE")
|
|
113
133
|
echo "当前主题: $current"
|
|
114
134
|
else
|
|
115
135
|
echo "当前主题: fire (默认)"
|
|
@@ -134,10 +154,10 @@ cmd_theme() {
|
|
|
134
154
|
# 更新配置
|
|
135
155
|
mkdir -p "$(dirname "$CONFIG_FILE")"
|
|
136
156
|
if [ -f "$CONFIG_FILE" ]; then
|
|
137
|
-
|
|
157
|
+
$JQ_CMD --arg theme "$new_theme" '.theme = $theme' "$CONFIG_FILE" > "$CONFIG_FILE.tmp"
|
|
138
158
|
mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
|
139
159
|
else
|
|
140
|
-
|
|
160
|
+
$JQ_CMD -n --arg theme "$new_theme" '{theme: $theme}' > "$CONFIG_FILE"
|
|
141
161
|
fi
|
|
142
162
|
|
|
143
163
|
echo -e "${GREEN}主题已切换到: $new_theme${NC}"
|
|
@@ -150,7 +170,7 @@ cmd_alert() {
|
|
|
150
170
|
|
|
151
171
|
if [ -z "$amount" ]; then
|
|
152
172
|
if [ -f "$CONFIG_FILE" ]; then
|
|
153
|
-
local current=$(
|
|
173
|
+
local current=$($JQ_CMD -r '.alert_daily // 10' "$CONFIG_FILE")
|
|
154
174
|
echo "当前每日警报: \$$current"
|
|
155
175
|
else
|
|
156
176
|
echo "当前每日警报: \$10 (默认)"
|
|
@@ -170,10 +190,10 @@ cmd_alert() {
|
|
|
170
190
|
# 更新配置
|
|
171
191
|
mkdir -p "$(dirname "$CONFIG_FILE")"
|
|
172
192
|
if [ -f "$CONFIG_FILE" ]; then
|
|
173
|
-
|
|
193
|
+
$JQ_CMD --arg amount "$amount" '.alert_daily = ($amount | tonumber)' "$CONFIG_FILE" > "$CONFIG_FILE.tmp"
|
|
174
194
|
mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
|
175
195
|
else
|
|
176
|
-
|
|
196
|
+
$JQ_CMD -n --arg amount "$amount" '{alert_daily: ($amount | tonumber)}' > "$CONFIG_FILE"
|
|
177
197
|
fi
|
|
178
198
|
|
|
179
199
|
echo -e "${GREEN}每日警报已设置: \$$amount${NC}"
|
|
@@ -185,7 +205,7 @@ cmd_show_rate() {
|
|
|
185
205
|
|
|
186
206
|
if [ -z "$value" ]; then
|
|
187
207
|
if [ -f "$CONFIG_FILE" ]; then
|
|
188
|
-
local current=$(
|
|
208
|
+
local current=$($JQ_CMD -r '.show_burn_rate // true' "$CONFIG_FILE")
|
|
189
209
|
echo "燃烧速度显示: $current"
|
|
190
210
|
else
|
|
191
211
|
echo "燃烧速度显示: true (默认)"
|
|
@@ -204,10 +224,10 @@ cmd_show_rate() {
|
|
|
204
224
|
|
|
205
225
|
mkdir -p "$(dirname "$CONFIG_FILE")"
|
|
206
226
|
if [ -f "$CONFIG_FILE" ]; then
|
|
207
|
-
|
|
227
|
+
$JQ_CMD --arg val "$bool_value" '.show_burn_rate = ($val | tonumber or ($val == "true"))' "$CONFIG_FILE" > "$CONFIG_FILE.tmp"
|
|
208
228
|
mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
|
209
229
|
else
|
|
210
|
-
|
|
230
|
+
$JQ_CMD -n --arg val "$bool_value" '{show_burn_rate: ($val == "true")}' > "$CONFIG_FILE"
|
|
211
231
|
fi
|
|
212
232
|
|
|
213
233
|
echo -e "${GREEN}燃烧速度显示: $bool_value${NC}"
|
|
@@ -279,8 +299,8 @@ cmd_total() {
|
|
|
279
299
|
if [ -f "$HOME/.claude/scripts/token-history.sh" ]; then
|
|
280
300
|
local data=$($HOME/.claude/scripts/token-history.sh summary)
|
|
281
301
|
echo -e "${YELLOW}💀 总计统计:${NC}"
|
|
282
|
-
echo " Token: $(echo "$data" |
|
|
283
|
-
echo " 费用: \$(echo "$data" |
|
|
302
|
+
echo " Token: $(echo "$data" | $JQ_CMD -r '.total_tokens_all // 0')"
|
|
303
|
+
echo " 费用: \$(echo "$data" | $JQ_CMD -r '.total_cost // 0')"
|
|
284
304
|
else
|
|
285
305
|
echo -e "${RED}✗ Burn Your Money 未安装${NC}"
|
|
286
306
|
exit 1
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Plugin Architecture - "Burn Your Money"
|
|
2
|
+
|
|
3
|
+
Here is a visual breakdown of how the plugin works. It's designed to be lightweight, local, and purely driven by the data provided by Claude Code itself.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## The Data Flow (Technical View)
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
graph LR
|
|
11
|
+
%% Styles
|
|
12
|
+
classDef claude fill:#e1f5fe,stroke:#01579b,stroke-width:2px;
|
|
13
|
+
classDef script fill:#fff9c4,stroke:#fbc02d,stroke-width:2px,stroke-dasharray: 5 5;
|
|
14
|
+
classDef store fill:#f3e5f5,stroke:#8e24aa,stroke-width:2px;
|
|
15
|
+
classDef term fill:#212121,stroke:#000,stroke-width:2px,color:#fff;
|
|
16
|
+
|
|
17
|
+
subgraph "Local Execution Environment"
|
|
18
|
+
CC[Claude Code CLI]:::claude
|
|
19
|
+
|
|
20
|
+
subgraph "Plugin Logic (Bash + jq)"
|
|
21
|
+
Script[statusline.sh]:::script
|
|
22
|
+
Calc((Cost Calculator)):::script
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subgraph "File System (Cache)"
|
|
26
|
+
Today[(today-state.json)]:::store
|
|
27
|
+
History[(history-cache.json)]:::store
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Term[Terminal Output]:::term
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
%% Flow
|
|
34
|
+
CC -- "1. JSON Stream (stdin)" --> Script
|
|
35
|
+
Script -- "2. Parse & Extract" --> Calc
|
|
36
|
+
|
|
37
|
+
Calc -- "3. Read/Write (Atomic)" --> Today
|
|
38
|
+
Calc -- "4. Read Only" --> History
|
|
39
|
+
|
|
40
|
+
Calc -- "5. Format ANSI String" --> Script
|
|
41
|
+
Script -- "6. Render Status Bar" --> Term
|
|
42
|
+
|
|
43
|
+
%% Notes
|
|
44
|
+
click Script "Main entry point triggered by Claude on every context change"
|
|
45
|
+
click Today "Stores today's accumulated cost across sessions"
|
|
46
|
+
click History "Stores historical data (updated every 30s)"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Key Components
|
|
50
|
+
|
|
51
|
+
1. **Claude Code CLI**: The "Boss". It triggers our script whenever something happens (e.g., new token usage) and pipes the current session data (JSON) into standard input.
|
|
52
|
+
2. **`statusline.sh`**: The "Worker". This is the script you installed.
|
|
53
|
+
* It uses `jq` to parse the incoming JSON stream.
|
|
54
|
+
* It calculates the cost based on the input/output tokens.
|
|
55
|
+
3. **Local Cache**: The "Memory".
|
|
56
|
+
* `today-state.json`: Remembers what you spent earlier today, so the counter doesn't reset when you restart Claude. (Uses atomic writes to prevent data corruption).
|
|
57
|
+
* `history-cache.json`: Stores long-term stats (updated less frequently to save performance).
|
|
58
|
+
4. **Terminal**: The "Stage". Displays the final formatted string with colors and emojis.
|
|
Binary file
|
package/fix-git-bash.ps1
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env pwsh
|
|
2
|
+
<#
|
|
3
|
+
.SYNOPSIS
|
|
4
|
+
Fix Git Bash fork issues by adding exclusions to Windows Defender
|
|
5
|
+
|
|
6
|
+
.DESCRIPTION
|
|
7
|
+
This script adds Git Bash and Claude Code directories to Windows Defender
|
|
8
|
+
exclusion list to prevent fork() timeout errors.
|
|
9
|
+
|
|
10
|
+
.REQUIREMENTS
|
|
11
|
+
- Run as Administrator
|
|
12
|
+
- Windows 10/11 with Windows Defender
|
|
13
|
+
#>
|
|
14
|
+
|
|
15
|
+
Write-Host "`n=== Fix Git Bash Fork Issues ===" -ForegroundColor Cyan
|
|
16
|
+
Write-Host ""
|
|
17
|
+
|
|
18
|
+
# Check if running as Administrator
|
|
19
|
+
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
20
|
+
if (-not $isAdmin) {
|
|
21
|
+
Write-Host "ERROR: This script must be run as Administrator." -ForegroundColor Red
|
|
22
|
+
Write-Host ""
|
|
23
|
+
Write-Host "Please right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow
|
|
24
|
+
Write-Host "Then run: .\fix-git-bash.ps1" -ForegroundColor Yellow
|
|
25
|
+
exit 1
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Write-Host "[1/4] Detecting paths..." -ForegroundColor Cyan
|
|
29
|
+
|
|
30
|
+
# Detect Git installation path
|
|
31
|
+
$gitPaths = @(
|
|
32
|
+
"C:\Program Files\Git",
|
|
33
|
+
"C:\Program Files (x86)\Git",
|
|
34
|
+
"${env:ProgramFiles}\Git",
|
|
35
|
+
"${env:ProgramFiles(x86)}\Git"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
$gitPath = $null
|
|
39
|
+
foreach ($path in $gitPaths) {
|
|
40
|
+
if (Test-Path $path) {
|
|
41
|
+
$gitPath = $path
|
|
42
|
+
break
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (-not $gitPath) {
|
|
47
|
+
Write-Host " WARNING: Git installation not found in standard locations" -ForegroundColor Yellow
|
|
48
|
+
Write-Host " You may need to manually add your Git path" -ForegroundColor Yellow
|
|
49
|
+
} else {
|
|
50
|
+
Write-Host " Found Git at: $gitPath" -ForegroundColor Green
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Detect Claude Code directory
|
|
54
|
+
$claudePath = "$env:USERPROFILE\.claude"
|
|
55
|
+
if (Test-Path $claudePath) {
|
|
56
|
+
Write-Host " Found Claude config at: $claudePath" -ForegroundColor Green
|
|
57
|
+
} else {
|
|
58
|
+
Write-Host " Claude config directory will be created at: $claudePath" -ForegroundColor Yellow
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
Write-Host ""
|
|
62
|
+
Write-Host "[2/4] Checking existing exclusions..." -ForegroundColor Cyan
|
|
63
|
+
|
|
64
|
+
# Get current exclusions
|
|
65
|
+
try {
|
|
66
|
+
$exclusions = Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
|
|
67
|
+
Write-Host " Current exclusions count: $($exclusions.Count)" -ForegroundColor Gray
|
|
68
|
+
} catch {
|
|
69
|
+
Write-Host " WARNING: Could not retrieve current exclusions" -ForegroundColor Yellow
|
|
70
|
+
$exclusions = @()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Write-Host ""
|
|
74
|
+
Write-Host "[3/4] Adding exclusions to Windows Defender..." -ForegroundColor Cyan
|
|
75
|
+
|
|
76
|
+
$added = 0
|
|
77
|
+
|
|
78
|
+
# Add Git path
|
|
79
|
+
if ($gitPath) {
|
|
80
|
+
if ($gitPath -notin $exclusions) {
|
|
81
|
+
try {
|
|
82
|
+
Add-MpPreference -ExclusionPath $gitPath -Force
|
|
83
|
+
Write-Host " Added: $gitPath" -ForegroundColor Green
|
|
84
|
+
$added++
|
|
85
|
+
} catch {
|
|
86
|
+
Write-Host " Failed to add: $gitPath" -ForegroundColor Red
|
|
87
|
+
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Gray
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
Write-Host " Already excluded: $gitPath" -ForegroundColor Gray
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Add Claude Code directory
|
|
95
|
+
if ($claudePath -notin $exclusions) {
|
|
96
|
+
try {
|
|
97
|
+
Add-MpPreference -ExclusionPath $claudePath -Force
|
|
98
|
+
Write-Host " Added: $claudePath" -ForegroundColor Green
|
|
99
|
+
$added++
|
|
100
|
+
} catch {
|
|
101
|
+
Write-Host " Failed to add: $claudePath" -ForegroundColor Red
|
|
102
|
+
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Gray
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
Write-Host " Already excluded: $claudePath" -ForegroundColor Gray
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Optionally add temp directory (bash creates temp files)
|
|
109
|
+
$tempPath = $env:TEMP
|
|
110
|
+
if ($tempPath -notin $exclusions) {
|
|
111
|
+
try {
|
|
112
|
+
Add-MpPreference -ExclusionPath $tempPath -Force
|
|
113
|
+
Write-Host " Added: $tempPath" -ForegroundColor Green
|
|
114
|
+
$added++
|
|
115
|
+
} catch {
|
|
116
|
+
Write-Host " Failed to add: $tempPath" -ForegroundColor Red
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
Write-Host " Already excluded: $tempPath" -ForegroundColor Gray
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
Write-Host ""
|
|
123
|
+
Write-Host "[4/4] Cleanup..." -ForegroundColor Cyan
|
|
124
|
+
|
|
125
|
+
# Remove stackdump files if exist
|
|
126
|
+
$stackDump = Join-Path $PWD "bash.exe.stackdump"
|
|
127
|
+
if (Test-Path $stackDump) {
|
|
128
|
+
Remove-Item $stackDump -Force
|
|
129
|
+
Write-Host " Removed: bash.exe.stackdump" -ForegroundColor Green
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
Write-Host ""
|
|
133
|
+
Write-Host "=== Summary ===" -ForegroundColor Cyan
|
|
134
|
+
Write-Host " Exclusions added: $added" -ForegroundColor $(if ($added -gt 0) { "Green" } else { "Yellow" })
|
|
135
|
+
Write-Host ""
|
|
136
|
+
|
|
137
|
+
if ($added -gt 0) {
|
|
138
|
+
Write-Host "SUCCESS: Exclusions have been added to Windows Defender." -ForegroundColor Green
|
|
139
|
+
Write-Host ""
|
|
140
|
+
Write-Host "Next steps:" -ForegroundColor Yellow
|
|
141
|
+
Write-Host " 1. Restart Claude Code" -ForegroundColor White
|
|
142
|
+
Write-Host " 2. If issues persist, restart your computer" -ForegroundColor White
|
|
143
|
+
} else {
|
|
144
|
+
Write-Host "INFO: All paths were already excluded." -ForegroundColor Yellow
|
|
145
|
+
Write-Host ""
|
|
146
|
+
Write-Host "If you still see fork errors, try:" -ForegroundColor Yellow
|
|
147
|
+
Write-Host " 1. Restart your computer" -ForegroundColor White
|
|
148
|
+
Write-Host " 2. Temporarily disable Real-time protection to test" -ForegroundColor White
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
Write-Host ""
|
|
152
|
+
Write-Host "To verify exclusions, run:" -ForegroundColor Gray
|
|
153
|
+
Write-Host " Get-MpPreference | Select-Object -ExpandProperty ExclusionPath" -ForegroundColor White
|
|
154
|
+
Write-Host ""
|