@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/src/token-history.sh
CHANGED
|
@@ -1,238 +1,268 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Burn Your Money - Token 历史统计脚本
|
|
3
|
-
# 从 stats-cache.json 读取历史数据,返回今日/本周/本月统计
|
|
4
|
-
|
|
5
|
-
set -e
|
|
6
|
-
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
[ "$
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
#
|
|
66
|
-
local
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
local
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
local
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
#
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
;;
|
|
235
|
-
|
|
236
|
-
read_stats
|
|
237
|
-
;;
|
|
238
|
-
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Burn Your Money - Token 历史统计脚本
|
|
3
|
+
# 从 stats-cache.json 读取历史数据,返回今日/本周/本月统计
|
|
4
|
+
|
|
5
|
+
set -e
|
|
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
|
+
|
|
27
|
+
# 文件路径
|
|
28
|
+
STATS_CACHE="$HOME/.claude/stats-cache.json"
|
|
29
|
+
TODAY=$(date +%Y-%m-%d)
|
|
30
|
+
CURRENT_MONTH=$(date +%Y-%m)
|
|
31
|
+
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'))")
|
|
32
|
+
|
|
33
|
+
# 获取本周一的日期
|
|
34
|
+
get_week_start() {
|
|
35
|
+
local day_of_week=$(date +%u) # 1=Monday, 7=Sunday
|
|
36
|
+
local days_to_subtract=$((day_of_week - 1))
|
|
37
|
+
date -d "$days_to_subtract days ago" +%Y-%m-%d 2>/dev/null || \
|
|
38
|
+
python3 -c "from datetime import datetime, timedelta; d = datetime.now() - timedelta(days=$(date +%u) - 1); print(d.strftime('%Y-%m-%d'))"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# 获取本月第一天
|
|
42
|
+
get_month_start() {
|
|
43
|
+
date +%Y-%m-01
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
WEEK_START=$(get_week_start)
|
|
47
|
+
MONTH_START=$(get_month_start)
|
|
48
|
+
LAST_MONTH_START=$(date -d "$LAST_MONTH-01" +%Y-%m-%d 2>/dev/null || echo "$LAST_MONTH-01")
|
|
49
|
+
|
|
50
|
+
# 从 stats-cache.json 读取统计数据
|
|
51
|
+
read_stats() {
|
|
52
|
+
if [ ! -f "$STATS_CACHE" ]; then
|
|
53
|
+
"$JQ_CMD" -n '{
|
|
54
|
+
today_tokens:0,today_cost:0,
|
|
55
|
+
week_tokens:0,week_cost:0,
|
|
56
|
+
month_tokens:0,month_cost:0,
|
|
57
|
+
last_month_tokens:0,last_month_cost:0,
|
|
58
|
+
total_tokens_all:0,total_cost:0,
|
|
59
|
+
daily_data: []
|
|
60
|
+
}'
|
|
61
|
+
return
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# 获取今日 token:总计 - 历史每日总和(排除今天)
|
|
65
|
+
# 修改:聚合所有模型的 input 和 output tokens
|
|
66
|
+
local total_io_tokens=$(cat "$STATS_CACHE" | $JQ_CMD -r '[.modelUsage[] | (.inputTokens + .outputTokens)] | add // 0' 2>/dev/null || echo "0")
|
|
67
|
+
|
|
68
|
+
# 修改:聚合每日数据中所有模型的 token
|
|
69
|
+
local history_sum=$(cat "$STATS_CACHE" | $JQ_CMD -r "[.dailyModelTokens[] | select(.date != \"$TODAY\") | (.tokensByModel[] // 0)] | add // 0" 2>/dev/null || echo "0")
|
|
70
|
+
local today_data=$((total_io_tokens - history_sum))
|
|
71
|
+
[ "$today_data" -lt 0 ] && today_data=0
|
|
72
|
+
|
|
73
|
+
# 本周 token(排除今天,用上面的 today_data)
|
|
74
|
+
local week_tokens=$(cat "$STATS_CACHE" | $JQ_CMD -r "[.dailyModelTokens[] | select(.date >= \"$WEEK_START\" and .date != \"$TODAY\") | (.tokensByModel[] // 0)] | add // 0" 2>/dev/null || echo "0")
|
|
75
|
+
week_tokens=$((week_tokens + today_data))
|
|
76
|
+
|
|
77
|
+
# 本月 token
|
|
78
|
+
local month_tokens=$(cat "$STATS_CACHE" | $JQ_CMD -r "[.dailyModelTokens[] | select(.date >= \"$MONTH_START\" and .date != \"$TODAY\") | (.tokensByModel[] // 0)] | add // 0" 2>/dev/null || echo "0")
|
|
79
|
+
month_tokens=$((month_tokens + today_data))
|
|
80
|
+
|
|
81
|
+
# 上月 token
|
|
82
|
+
local last_month_tokens=$(cat "$STATS_CACHE" | $JQ_CMD -r "[.dailyModelTokens[] | select(.date >= \"$LAST_MONTH_START\" and .date < \"$MONTH_START\") | (.tokensByModel[] // 0)] | add // 0" 2>/dev/null || echo "0")
|
|
83
|
+
|
|
84
|
+
# 计算全部历史费用(使用 jq 进行精确计算,避免 awk 大数字精度问题)
|
|
85
|
+
# 修改:聚合所有模型的 usage
|
|
86
|
+
local total_input=$(cat "$STATS_CACHE" | $JQ_CMD -r '[.modelUsage[].inputTokens // 0] | add // 0' 2>/dev/null || echo "0")
|
|
87
|
+
local total_output=$(cat "$STATS_CACHE" | $JQ_CMD -r '[.modelUsage[].outputTokens // 0] | add // 0' 2>/dev/null || echo "0")
|
|
88
|
+
local total_cache_read=$(cat "$STATS_CACHE" | $JQ_CMD -r '[.modelUsage[].cacheReadInputTokens // 0] | add // 0' 2>/dev/null || echo "0")
|
|
89
|
+
|
|
90
|
+
# 估算总费用 (简单按 3/15/0.3 规则,虽然不同模型费率不同,但作为估算足够)
|
|
91
|
+
# 如果要精确需针对模型 loop,这里简化为聚合
|
|
92
|
+
local total_cost=$(cat "$STATS_CACHE" | $JQ_CMD -r '
|
|
93
|
+
[.modelUsage[]] | map(
|
|
94
|
+
((.inputTokens // 0) / 1000000 * 3) +
|
|
95
|
+
((.outputTokens // 0) / 1000000 * 15) +
|
|
96
|
+
((.cacheReadInputTokens // 0) / 1000000 * 0.3)
|
|
97
|
+
) | add | floor * 100 / 100
|
|
98
|
+
' 2>/dev/null || echo "0")
|
|
99
|
+
|
|
100
|
+
# 总 token 数量(包含 cache)
|
|
101
|
+
local total_tokens_all=$((total_input + total_output + total_cache_read))
|
|
102
|
+
|
|
103
|
+
# 计算各周期费用(按比例分摊)
|
|
104
|
+
local week_cost="0.00"
|
|
105
|
+
local month_cost="0.00"
|
|
106
|
+
local last_month_cost="0.00"
|
|
107
|
+
local today_cost="0.00"
|
|
108
|
+
|
|
109
|
+
if [ "$total_io_tokens" != "0" ] && [ "$total_io_tokens" != "" ]; then
|
|
110
|
+
week_cost=$(awk "BEGIN {printf \"%.2f\", ${week_tokens} / ${total_io_tokens} * ${total_cost}}")
|
|
111
|
+
month_cost=$(awk "BEGIN {printf \"%.2f\", ${month_tokens} / ${total_io_tokens} * ${total_cost}}")
|
|
112
|
+
if [ "$last_month_tokens" -gt 0 ]; then
|
|
113
|
+
last_month_cost=$(awk "BEGIN {printf \"%.2f\", ${last_month_tokens} / ${total_io_tokens} * ${total_cost}}")
|
|
114
|
+
fi
|
|
115
|
+
else
|
|
116
|
+
week_cost=$total_cost
|
|
117
|
+
month_cost=$total_cost
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
if [ "$week_tokens" != "0" ] && [ "$week_tokens" != "" ]; then
|
|
121
|
+
today_cost=$(awk "BEGIN {printf \"%.2f\", ${today_data} / ${week_tokens} * ${week_cost}}")
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# 获取每日数据(用于趋势图)
|
|
125
|
+
# 修改:聚合每日所有模型的 tokens
|
|
126
|
+
local daily_data=$(cat "$STATS_CACHE" | $JQ_CMD -c "[.dailyModelTokens[-7:][] | {date: .date, tokens: ([.tokensByModel[]] | add // 0)}]" 2>/dev/null || echo "[]")
|
|
127
|
+
|
|
128
|
+
# 输出 JSON
|
|
129
|
+
"$JQ_CMD" -n \
|
|
130
|
+
--arg today_tokens "$today_data" \
|
|
131
|
+
--arg today_cost "$today_cost" \
|
|
132
|
+
--arg week_tokens "$week_tokens" \
|
|
133
|
+
--arg week_cost "$week_cost" \
|
|
134
|
+
--arg month_tokens "$month_tokens" \
|
|
135
|
+
--arg month_cost "$month_cost" \
|
|
136
|
+
--arg last_month_tokens "$last_month_tokens" \
|
|
137
|
+
--arg last_month_cost "$last_month_cost" \
|
|
138
|
+
--arg total_tokens_all "$total_tokens_all" \
|
|
139
|
+
--arg total_cost "$total_cost" \
|
|
140
|
+
--argjson daily_data "$daily_data" \
|
|
141
|
+
'{
|
|
142
|
+
today_tokens: ($today_tokens | tonumber),
|
|
143
|
+
today_cost: ($today_cost | tonumber),
|
|
144
|
+
week_tokens: ($week_tokens | tonumber),
|
|
145
|
+
week_cost: ($week_cost | tonumber),
|
|
146
|
+
month_tokens: ($month_tokens | tonumber),
|
|
147
|
+
month_cost: ($month_cost | tonumber),
|
|
148
|
+
last_month_tokens: ($last_month_tokens | tonumber),
|
|
149
|
+
last_month_cost: ($last_month_cost | tonumber),
|
|
150
|
+
total_tokens_all: ($total_tokens_all | tonumber),
|
|
151
|
+
total_cost: ($total_cost | tonumber),
|
|
152
|
+
daily_data: $daily_data
|
|
153
|
+
}'
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# 生成 ASCII 趋势图
|
|
157
|
+
generate_trend() {
|
|
158
|
+
local data="$1"
|
|
159
|
+
local max_tokens=0
|
|
160
|
+
|
|
161
|
+
# 找到最大值
|
|
162
|
+
for row in $(echo "$data" | $JQ_CMD -r '.[].tokens'); do
|
|
163
|
+
if [ "$row" -gt "$max_tokens" ]; then
|
|
164
|
+
max_tokens=$row
|
|
165
|
+
fi
|
|
166
|
+
done
|
|
167
|
+
|
|
168
|
+
# 生成图表
|
|
169
|
+
echo ""
|
|
170
|
+
echo "📊 过去 7 天 Token 趋势:"
|
|
171
|
+
echo ""
|
|
172
|
+
|
|
173
|
+
local count=0
|
|
174
|
+
for entry in $(echo "$data" | $JQ_CMD -c '.[]'); do
|
|
175
|
+
local date=$(echo "$entry" | $JQ_CMD -r '.date' | cut -c 6-)
|
|
176
|
+
local tokens=$(echo "$entry" | $JQ_CMD -r '.tokens')
|
|
177
|
+
|
|
178
|
+
# 计算条形长度
|
|
179
|
+
if [ "$max_tokens" -gt 0 ]; then
|
|
180
|
+
local bars=$(awk "BEGIN {printf \"%.0f\", $tokens / $max_tokens * 20}")
|
|
181
|
+
else
|
|
182
|
+
local bars=0
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# 生成条形
|
|
186
|
+
local bar=""
|
|
187
|
+
for i in $(seq 1 20); do
|
|
188
|
+
if [ "$i" -le "$bars" ]; then
|
|
189
|
+
bar+="█"
|
|
190
|
+
else
|
|
191
|
+
bar+="░"
|
|
192
|
+
fi
|
|
193
|
+
done
|
|
194
|
+
|
|
195
|
+
# 格式化 token 数量
|
|
196
|
+
local tokens_display=$(echo "$tokens" | awk '{
|
|
197
|
+
if ($1 >= 1000000) printf "%.1fM", $1/1000000
|
|
198
|
+
else if ($1 >= 1000) printf "%.1fK", $1/1000
|
|
199
|
+
else printf "%d", $1
|
|
200
|
+
}')
|
|
201
|
+
|
|
202
|
+
printf " %s │ %s │ %s\n" "$date" "$bar" "$tokens_display"
|
|
203
|
+
count=$((count + 1))
|
|
204
|
+
done
|
|
205
|
+
echo ""
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# 导出数据
|
|
209
|
+
export_data() {
|
|
210
|
+
local format="$1"
|
|
211
|
+
local stats=$(read_stats)
|
|
212
|
+
|
|
213
|
+
case "$format" in
|
|
214
|
+
csv)
|
|
215
|
+
echo "date,tokens,cost"
|
|
216
|
+
echo "$stats" | $JQ_CMD -r '.daily_data[] | "\(.date),\(.tokens),\(.tokens * 0.000006)"'
|
|
217
|
+
;;
|
|
218
|
+
json)
|
|
219
|
+
echo "$stats" | $JQ_CMD '.'
|
|
220
|
+
;;
|
|
221
|
+
*)
|
|
222
|
+
echo "支持的格式: csv, json"
|
|
223
|
+
exit 1
|
|
224
|
+
;;
|
|
225
|
+
esac
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# 根据 mode 返回不同数据
|
|
229
|
+
MODE=${1:-summary}
|
|
230
|
+
|
|
231
|
+
case "$MODE" in
|
|
232
|
+
today_tokens)
|
|
233
|
+
read_stats | $JQ_CMD -r '.today_tokens'
|
|
234
|
+
;;
|
|
235
|
+
today_cost)
|
|
236
|
+
read_stats | $JQ_CMD -r '.today_cost'
|
|
237
|
+
;;
|
|
238
|
+
week_tokens)
|
|
239
|
+
read_stats | $JQ_CMD -r '.week_tokens'
|
|
240
|
+
;;
|
|
241
|
+
week_cost)
|
|
242
|
+
read_stats | $JQ_CMD -r '.week_cost'
|
|
243
|
+
;;
|
|
244
|
+
month_tokens)
|
|
245
|
+
read_stats | $JQ_CMD -r '.month_tokens'
|
|
246
|
+
;;
|
|
247
|
+
month_cost)
|
|
248
|
+
read_stats | $JQ_CMD -r '.month_cost'
|
|
249
|
+
;;
|
|
250
|
+
last_month_tokens)
|
|
251
|
+
read_stats | $JQ_CMD -r '.last_month_tokens'
|
|
252
|
+
;;
|
|
253
|
+
last_month_cost)
|
|
254
|
+
read_stats | $JQ_CMD -r '.last_month_cost'
|
|
255
|
+
;;
|
|
256
|
+
trend)
|
|
257
|
+
read_stats | $JQ_CMD -r '.daily_data'
|
|
258
|
+
;;
|
|
259
|
+
chart)
|
|
260
|
+
generate_trend "$(read_stats | $JQ_CMD -r '.daily_data')"
|
|
261
|
+
;;
|
|
262
|
+
export)
|
|
263
|
+
export_data "$2"
|
|
264
|
+
;;
|
|
265
|
+
summary|json|*)
|
|
266
|
+
read_stats
|
|
267
|
+
;;
|
|
268
|
+
esac
|
package/uninstall.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
// ANSI colors
|
|
6
|
+
const colors = {
|
|
7
|
+
reset: "\x1b[0m",
|
|
8
|
+
red: "\x1b[31m",
|
|
9
|
+
green: "\x1b[32m",
|
|
10
|
+
yellow: "\x1b[33m",
|
|
11
|
+
cyan: "\x1b[36m"
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function log(message, color = colors.reset) {
|
|
15
|
+
console.log(`${color}${message}${colors.reset}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function success(message) {
|
|
19
|
+
log(`✓ ${message}`, colors.green);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function warning(message) {
|
|
23
|
+
log(`⚠ ${message}`, colors.yellow);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getHomeDir() {
|
|
27
|
+
return os.homedir();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function uninstallFiles() {
|
|
31
|
+
const home = getHomeDir();
|
|
32
|
+
const files = [
|
|
33
|
+
path.join(home, '.claude', 'statusline.sh'),
|
|
34
|
+
path.join(home, '.claude', 'scripts', 'token-history.sh'),
|
|
35
|
+
path.join(home, '.claude', 'statusline-wrapper.sh'),
|
|
36
|
+
// 命令文件
|
|
37
|
+
path.join(home, '.claude', 'commands', 'burn-your-money-stats.md'),
|
|
38
|
+
path.join(home, '.claude', 'commands', 'burn-your-money-today.md'),
|
|
39
|
+
path.join(home, '.claude', 'commands', 'burn-your-money-week.md'),
|
|
40
|
+
path.join(home, '.claude', 'commands', 'burn-your-money-month.md'),
|
|
41
|
+
path.join(home, '.claude', 'commands', 'burn-your-money-export.md'),
|
|
42
|
+
path.join(home, '.claude', 'commands', 'burn-your-money-export-csv.md')
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
log("Removing plugin files...", colors.cyan);
|
|
46
|
+
|
|
47
|
+
files.forEach(file => {
|
|
48
|
+
if (fs.existsSync(file)) {
|
|
49
|
+
try {
|
|
50
|
+
fs.unlinkSync(file);
|
|
51
|
+
success(`Removed ${path.basename(file)}`);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
warning(`Failed to remove ${file}: ${e.message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function restoreSettings() {
|
|
60
|
+
const home = getHomeDir();
|
|
61
|
+
const settingsFile = path.join(home, '.claude', 'settings.json');
|
|
62
|
+
|
|
63
|
+
log("Restoring settings.json...", colors.cyan);
|
|
64
|
+
|
|
65
|
+
if (fs.existsSync(settingsFile)) {
|
|
66
|
+
try {
|
|
67
|
+
let settings = JSON.parse(fs.readFileSync(settingsFile, 'utf8'));
|
|
68
|
+
|
|
69
|
+
if (settings.statusLine) {
|
|
70
|
+
delete settings.statusLine;
|
|
71
|
+
fs.writeFileSync(settingsFile, JSON.stringify(settings, null, 2));
|
|
72
|
+
success("Removed statusLine configuration from settings.json");
|
|
73
|
+
} else {
|
|
74
|
+
log("No statusLine configuration found.", colors.yellow);
|
|
75
|
+
}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
warning(`Failed to update settings.json: ${e.message}`);
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
warning("settings.json not found.");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function main() {
|
|
85
|
+
log("\n💸 Burn Your Money - Uninstaller\n", colors.red);
|
|
86
|
+
|
|
87
|
+
uninstallFiles();
|
|
88
|
+
restoreSettings();
|
|
89
|
+
|
|
90
|
+
log("\n✅ Uninstallation complete!", colors.green);
|
|
91
|
+
log("Run 'npm uninstall -g @winston.wan/burn-your-money' to remove the CLI tool.\n", colors.cyan);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
main();
|