@winston.wan/burn-your-money 2.0.4 → 2.0.5
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 +18 -0
- package/package.json +2 -1
- package/src/statusline.sh +18 -10
- package/src/token-history.sh +9 -9
- package/uninstall.js +88 -0
package/README.md
CHANGED
|
@@ -140,6 +140,24 @@ today_color="\\033[0;31m" # 红色(代表燃烧)
|
|
|
140
140
|
|
|
141
141
|
实际费用可能因供应商而异。
|
|
142
142
|
|
|
143
|
+
## 🗑️ 卸载
|
|
144
|
+
|
|
145
|
+
由于 NPM 的限制,`npm uninstall` 无法自动清理配置文件。请手动运行以下命令来彻底卸载:
|
|
146
|
+
|
|
147
|
+
1. **清理配置和文件**:
|
|
148
|
+
```bash
|
|
149
|
+
# 如果你还在项目目录下
|
|
150
|
+
npm run uninstall
|
|
151
|
+
|
|
152
|
+
# 或者手动执行卸载脚本 (如果使用 Git Bash)
|
|
153
|
+
curl -fsSL https://raw.githubusercontent.com/winston-wwzhen/burn-your-money/main/uninstall.js | node
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
2. **移除 NPM 包**:
|
|
157
|
+
```bash
|
|
158
|
+
npm uninstall -g @winston.wan/burn-your-money
|
|
159
|
+
```
|
|
160
|
+
|
|
143
161
|
## 🤝 贡献
|
|
144
162
|
|
|
145
163
|
欢迎 PR!特别是:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@winston.wan/burn-your-money",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "💸 Burn Your Money - 实时显示 Claude Code 的 token 消耗,看着你的钱包燃烧!",
|
|
5
5
|
"main": "src/statusline.sh",
|
|
6
6
|
"bin": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"install": "node install.js",
|
|
11
|
+
"uninstall": "node uninstall.js",
|
|
11
12
|
"test": "bash ./test.sh"
|
|
12
13
|
},
|
|
13
14
|
"repository": {
|
package/src/statusline.sh
CHANGED
|
@@ -20,12 +20,20 @@ init_config() {
|
|
|
20
20
|
fi
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
# 读取配置
|
|
23
24
|
# 读取配置
|
|
24
25
|
init_config
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
27
|
+
THEME=$(cat "$CONFIG_FILE" | jq -r '.theme // "fire"' 2>/dev/null)
|
|
28
|
+
ALERT_DAILY=$(cat "$CONFIG_FILE" | jq -r '.alert_daily // 10' 2>/dev/null)
|
|
29
|
+
SHOW_BURN_RATE=$(cat "$CONFIG_FILE" | jq -r '.show_burn_rate // true' 2>/dev/null)
|
|
30
|
+
SHOW_ETA=$(cat "$CONFIG_FILE" | jq -r '.show_eta // true' 2>/dev/null)
|
|
31
|
+
else
|
|
32
|
+
THEME="fire"
|
|
33
|
+
ALERT_DAILY=10
|
|
34
|
+
SHOW_BURN_RATE=true
|
|
35
|
+
SHOW_ETA=true
|
|
36
|
+
fi
|
|
29
37
|
|
|
30
38
|
# 主题颜色定义
|
|
31
39
|
case "$THEME" in
|
|
@@ -88,12 +96,12 @@ format_burn_rate() {
|
|
|
88
96
|
|
|
89
97
|
# 获取或创建会话状态
|
|
90
98
|
get_session_start_time() {
|
|
91
|
-
local session_id=$(jq -r '.session_id // "default"'
|
|
99
|
+
local session_id=$(cat "$TEMP_JSON" | jq -r '.session_id // "default"' 2>/dev/null || echo "default")
|
|
92
100
|
local now=$(date +%s)
|
|
93
101
|
|
|
94
102
|
if [ -f "$SESSION_STATE" ]; then
|
|
95
|
-
local cached_id=$(jq -r '.session_id // ""'
|
|
96
|
-
local cached_time=$(jq -r '.start_time // 0'
|
|
103
|
+
local cached_id=$(cat "$SESSION_STATE" | jq -r '.session_id // ""' 2>/dev/null || echo "")
|
|
104
|
+
local cached_time=$(cat "$SESSION_STATE" | jq -r '.start_time // 0' 2>/dev/null || echo "0")
|
|
97
105
|
|
|
98
106
|
if [ "$cached_id" = "$session_id" ] && [ "$cached_time" -gt 0 ]; then
|
|
99
107
|
echo "$cached_time"
|
|
@@ -113,11 +121,11 @@ trap "rm -f $TEMP_JSON" EXIT
|
|
|
113
121
|
cat > "$TEMP_JSON"
|
|
114
122
|
|
|
115
123
|
# 读取模型名称
|
|
116
|
-
model=$(jq -r '.model.display_name // "Unknown"'
|
|
124
|
+
model=$(cat "$TEMP_JSON" | jq -r '.model.display_name // "Unknown"' 2>/dev/null || echo "Unknown")
|
|
117
125
|
|
|
118
126
|
# 读取当前会话的 token 数据(从 context_window)
|
|
119
|
-
current_input=$(jq -r '.context_window.total_input_tokens // 0'
|
|
120
|
-
current_output=$(jq -r '.context_window.total_output_tokens // 0'
|
|
127
|
+
current_input=$(cat "$TEMP_JSON" | jq -r '.context_window.total_input_tokens // 0' 2>/dev/null || echo "0")
|
|
128
|
+
current_output=$(cat "$TEMP_JSON" | jq -r '.context_window.total_output_tokens // 0' 2>/dev/null || echo "0")
|
|
121
129
|
current_session_tokens=$((current_input + current_output))
|
|
122
130
|
|
|
123
131
|
# 计算燃烧速度
|
package/src/token-history.sh
CHANGED
|
@@ -46,26 +46,26 @@ read_stats() {
|
|
|
46
46
|
local cost_per_m_output=15.0
|
|
47
47
|
|
|
48
48
|
# 获取今日 token:总计 - 历史每日总和(排除今天)
|
|
49
|
-
local total_io_tokens=$(jq -r '[.modelUsage["glm-4.7"].inputTokens, .modelUsage["glm-4.7"].outputTokens] | add // 0'
|
|
50
|
-
local history_sum=$(jq -r "[.dailyModelTokens[] | select(.date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0"
|
|
49
|
+
local total_io_tokens=$(cat "$STATS_CACHE" | jq -r '[.modelUsage["glm-4.7"].inputTokens, .modelUsage["glm-4.7"].outputTokens] | add // 0' 2>/dev/null || echo "0")
|
|
50
|
+
local history_sum=$(cat "$STATS_CACHE" | jq -r "[.dailyModelTokens[] | select(.date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" 2>/dev/null || echo "0")
|
|
51
51
|
local today_data=$((total_io_tokens - history_sum))
|
|
52
52
|
[ "$today_data" -lt 0 ] && today_data=0
|
|
53
53
|
|
|
54
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"
|
|
55
|
+
local week_tokens=$(cat "$STATS_CACHE" | jq -r "[.dailyModelTokens[] | select(.date >= \"$WEEK_START\" and .date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" 2>/dev/null || echo "0")
|
|
56
56
|
week_tokens=$((week_tokens + today_data))
|
|
57
57
|
|
|
58
58
|
# 本月 token
|
|
59
|
-
local month_tokens=$(jq -r "[.dailyModelTokens[] | select(.date >= \"$MONTH_START\" and .date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0"
|
|
59
|
+
local month_tokens=$(cat "$STATS_CACHE" | jq -r "[.dailyModelTokens[] | select(.date >= \"$MONTH_START\" and .date != \"$TODAY\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" 2>/dev/null || echo "0")
|
|
60
60
|
month_tokens=$((month_tokens + today_data))
|
|
61
61
|
|
|
62
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"
|
|
63
|
+
local last_month_tokens=$(cat "$STATS_CACHE" | jq -r "[.dailyModelTokens[] | select(.date >= \"$LAST_MONTH_START\" and .date < \"$MONTH_START\") | .tokensByModel[\"glm-4.7\"] // 0] | add // 0" 2>/dev/null || echo "0")
|
|
64
64
|
|
|
65
65
|
# 计算全部历史费用
|
|
66
|
-
local total_input=$(jq -r '.modelUsage["glm-4.7"].inputTokens // 0'
|
|
67
|
-
local total_output=$(jq -r '.modelUsage["glm-4.7"].outputTokens // 0'
|
|
68
|
-
local total_cache_read=$(jq -r '.modelUsage["glm-4.7"].cacheReadInputTokens // 0'
|
|
66
|
+
local total_input=$(cat "$STATS_CACHE" | jq -r '.modelUsage["glm-4.7"].inputTokens // 0' 2>/dev/null || echo "0")
|
|
67
|
+
local total_output=$(cat "$STATS_CACHE" | jq -r '.modelUsage["glm-4.7"].outputTokens // 0' 2>/dev/null || echo "0")
|
|
68
|
+
local total_cache_read=$(cat "$STATS_CACHE" | jq -r '.modelUsage["glm-4.7"].cacheReadInputTokens // 0' 2>/dev/null || echo "0")
|
|
69
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
70
|
|
|
71
71
|
# 总 token 数量(包含 cache)
|
|
@@ -93,7 +93,7 @@ read_stats() {
|
|
|
93
93
|
fi
|
|
94
94
|
|
|
95
95
|
# 获取每日数据(用于趋势图)
|
|
96
|
-
local daily_data=$(jq -c "[.dailyModelTokens[-7:][] | {date: .date, tokens: (.tokensByModel[\"glm-4.7\"] // 0)}]"
|
|
96
|
+
local daily_data=$(cat "$STATS_CACHE" | jq -c "[.dailyModelTokens[-7:][] | {date: .date, tokens: (.tokensByModel[\"glm-4.7\"] // 0)}]" 2>/dev/null || echo "[]")
|
|
97
97
|
|
|
98
98
|
# 输出 JSON
|
|
99
99
|
jq -n \
|
package/uninstall.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
];
|
|
36
|
+
|
|
37
|
+
log("Removing plugin files...", colors.cyan);
|
|
38
|
+
|
|
39
|
+
files.forEach(file => {
|
|
40
|
+
if (fs.existsSync(file)) {
|
|
41
|
+
try {
|
|
42
|
+
fs.unlinkSync(file);
|
|
43
|
+
success(`Removed ${file}`);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
warning(`Failed to remove ${file}: ${e.message}`);
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
// log(`File not found: ${file}`, colors.yellow);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function restoreSettings() {
|
|
54
|
+
const home = getHomeDir();
|
|
55
|
+
const settingsFile = path.join(home, '.claude', 'settings.json');
|
|
56
|
+
|
|
57
|
+
log("Restoring settings.json...", colors.cyan);
|
|
58
|
+
|
|
59
|
+
if (fs.existsSync(settingsFile)) {
|
|
60
|
+
try {
|
|
61
|
+
let settings = JSON.parse(fs.readFileSync(settingsFile, 'utf8'));
|
|
62
|
+
|
|
63
|
+
if (settings.statusLine) {
|
|
64
|
+
delete settings.statusLine;
|
|
65
|
+
fs.writeFileSync(settingsFile, JSON.stringify(settings, null, 2));
|
|
66
|
+
success("Removed statusLine configuration from settings.json");
|
|
67
|
+
} else {
|
|
68
|
+
log("No statusLine configuration found.", colors.yellow);
|
|
69
|
+
}
|
|
70
|
+
} catch (e) {
|
|
71
|
+
warning(`Failed to update settings.json: ${e.message}`);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
warning("settings.json not found.");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function main() {
|
|
79
|
+
log("\n💸 Burn Your Money - Uninstaller\n", colors.red);
|
|
80
|
+
|
|
81
|
+
uninstallFiles();
|
|
82
|
+
restoreSettings();
|
|
83
|
+
|
|
84
|
+
log("\n✅ Uninstallation complete!", colors.green);
|
|
85
|
+
log("Run 'npm uninstall -g @winston.wan/burn-your-money' to remove the CLI tool.\n", colors.cyan);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
main();
|