ccus-cli 0.1.6 → 0.1.9

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 CHANGED
@@ -1,202 +1,219 @@
1
- # ccus
2
-
3
- 一个本地优先的 Claude Code statusline 使用率采集 CLI:
4
-
5
- - `ccus install`:自动把 statusLine 命令写进 Claude Code 的 `settings.json`,省去手动改配置。
6
- - `ccus statusline emit`:读取 Claude Code statusline 通过 `stdin` 传入的 JSON,输出 statusline 文本,并写入本地日志(加 `--no-store` / `--no-log` 则只输出、不落盘)。
7
- - `ccus dashboard serve`:直接启动本地 Web 页面,不用先手动生成 HTML 文件。
8
- - `ccus export`:默认导出当前周数据包(gzip 压缩的 `.json.gz`),里面同时包含原始事件和按天维度的周汇总。
9
- - `ccus aggregate`:读取一个目录里的多人 export bundle(`.json.gz` 或 `.json`),输出明细、按天、按周三个 CSV。
10
- - `ccus aggregate serve`:同样以 bundle 目录为输入,启动本地多人 dashboard 页面,不落地任何文件。
11
- - `ccus update`:主动检查 npm 上是否有新版本,有则提示手动升级命令;`ccus --version` 查看当前版本。
12
-
13
- > **支持范围**:`ccus statusline emit` 依赖 Claude Code 的 statusLine 机制(从 `stdin` 读 JSON、向 `stdout` 回一行文本),**只在命令行版 Claude Code(CLI / 终端)里生效**。
14
- >
15
- > Claude **桌面版** 和 **VS Code 插件** 都不支持 statusLine,因此不会调用 `ccus statusline emit`,也就采集不到使用率数据。
16
-
17
- ## 安装
18
-
19
- 全局安装(statusline 每次渲染都会调用,推荐全局装好,避免 `npx` 的启动开销):
20
-
21
- ```bash
22
- npm install -g ccus-cli
23
- ```
24
-
25
- 要求 Node.js >= 20。
26
-
27
- ## 更新检查
28
-
29
- ccus 通过 npm 全局安装,自带一个轻量的更新检查:
30
-
31
- - statusline 渲染时会**异步、节流(每天最多一次)**地向 npm registry 查询最新版本,结果缓存到数据目录下的 `update-check.json`。检查在 detached 后台进程里完成,**不阻塞 statusline、不污染单行输出**。
32
- - 一旦发现有更新,statusline 行尾会追加一个小标记,例如 `… | ⏱ 11:44 | ⬆ v0.1.5`。
33
- - 看到标记后手动升级即可:
34
-
35
- ```bash
36
- npm i -g ccus-cli@latest
37
- ```
38
-
39
- 也可以随时主动检查:
40
-
41
- ```bash
42
- ccus update # 立即查 registry,有新版本则打印升级命令
43
- ccus --version # 查看当前安装的版本
44
- ```
45
-
46
- > 出于稳妥考虑,ccus **只提示、不自动替你执行全局安装**。如需走私服或镜像(如 npmmirror),设置环境变量 `CCUS_REGISTRY` 指向对应 registry 即可。
47
-
48
- ## 快速开始
49
-
50
- 全局安装后,一条命令把 statusline 接进 Claude Code:
51
-
52
- ```bash
53
- ccus install
54
- ```
55
-
56
- 然后照常使用 Claude Code,statusline 会显示 5 小时额度使用率(`5h`)、7 天额度使用率(`7d`)、context window 占用百分比(`ctx`)、模型名、工作区名,以及当前 git 分支(`⎇ <branch>`,实时读取,非 git 仓库或处于 detached HEAD 时省略该段);原始 payload 也会落到本地日志,供后续 dashboard / export 使用。
57
-
58
- 攒了一段时间数据后,最常用的几条命令:
59
-
60
- ```bash
61
- ccus export # 导出当前周数据包(this-week)
62
- ccus export lw # 导出上一整周(last-week,周一到周日)
63
- ccus export tw # 导出本周(等价于默认 ccus export)
64
-
65
- ccus dashboard serve # 启动本地页面,默认看本周(this-week)的 5 小时使用率曲线与每日用户消息数
66
-
67
- ccus aggregate --input-dir ./team-exports # 多人的数据汇总,可以导出 detail.csv、daily.csv、weekly.csv 三个维度的文件
68
- ccus aggregate serve --input-dir ./team-exports #直接打开一个看板
69
- ```
70
-
71
- ### 一键安装(推荐)
72
-
73
- 不想手动改配置时,直接运行:
74
-
75
- ```bash
76
- ccus install
77
- ```
78
-
79
- 行为:
80
-
81
- - 默认写入 `~/.claude/settings.json`(可用 `--settings PATH` 覆盖;遵循 `CCUS_CLAUDE_DATA_DIR`)
82
- - 默认写入的命令是 `ccus statusline emit`(需要先全局安装,让 PATH 上能找到 `ccus`)
83
- - 只覆盖 `statusLine` 字段(保留其下已有的 `padding` 等键),其它顶层设置原样保留
84
- - 已存在且命令一致时显示 `already configured`,被替换时会回显旧命令
85
- - `settings.json` 无法解析为 JSON 时直接报错,不会覆盖文件
86
- - `--command CMD` 可完全自定义命令;`--data-dir PATH` 会在默认命令后追加 `--data-dir`,让采样落到指定目录
87
-
88
- ### 手动配置
89
-
90
- 也可以手动在 `settings.json` 里写:
91
-
92
- ```json
93
- {
94
- "statusLine": {
95
- "type": "command",
96
- "command": "ccus statusline emit"
97
- }
98
- }
99
- ```
100
-
101
- ## 常用命令
102
-
103
- ```bash
104
- ccus install
105
- ccus install --settings ~/.claude/settings.json
106
- ccus statusline emit
107
- ccus statusline emit --no-store # 只渲染并输出状态行,不写本地日志(别名 --no-log)
108
- ccus dashboard build --range today --out ./ccus-dashboard.html
109
- ccus dashboard open --range today
110
- ccus dashboard serve --range today --open
111
- ccus export
112
- ccus export --range today
113
- ccus export --range last-week
114
- ccus export lw # 位置参数简写,等价于 --range last-week
115
- ccus export tw # 等价于 --range this-week
116
- ccus export --out ./alice_export_2026-05-26_to_2026-06-01.json # --out 指定非 .gz 路径时写明文 JSON
117
- ccus aggregate --input-dir ./team-exports --out-dir ./team-report
118
- ccus aggregate serve --input-dir ./team-exports
119
- ```
120
-
121
- `serve` 会启动一个本地 HTTP 服务,默认监听 `127.0.0.1` 上的随机端口,并在每次请求时实时读取最新日志生成页面。`serve` 默认查看 `this-week`(整周)使用量曲线(`build` / `open` 仍默认 `today`),可用 `--range` 覆盖。
122
-
123
- 其中:
124
-
125
- - `5 小时使用量百分比` **展示指标**,来自 Claude 自身字段 `rate_limits.five_hour.used_percentage`
126
- - 使用率趋势图会在同一张图上叠加两条线:实线为 5 小时使用率(`rate_limits.five_hour`),虚线为 7 天使用率(`rate_limits.seven_day`),两者各自独立按时间桶聚合
127
- - 页面新增 **每日用户消息数** 柱状图:按自然日统计的真实用户请求数,口径与导出契约的 `userMessageCount` 一致(来自 `~/.claude/projects/**/*.jsonl`),不是 statusline 采样数,也仅用于页面展示、不进任何导出/聚合契约
128
- - 跨多天的窗口(如 `this-week` / `last-week`)使用率曲线会自动改用小时桶聚合,避免一周生成上千个点,且 x 轴改为按自然日(月-日)打刻度
129
- - 顶部统计卡展示 `Latest 5h usage`、`Peak 5h usage`、`Latest 7d usage`(含峰值)、`用户消息数`(窗口内每日真实用户请求数合计)
130
- - `--range today / this-week / last-week / 24h` 是 **你要查看的采样历史时间窗口**(`last-week` 指上一个完整周一到周日)
131
- - statusline 日志本身主要保存 `rawPayload` 与外部补充字段;默认导出时会同时保留原始事件,并额外汇总 `~/.claude/projects/**/*.jsonl` 中的会话 usage
132
-
133
- ## 导出
134
-
135
- - 默认导出 `this-week`;如需导出上一个完整周(周一到周日),用 `--range last-week`,或位置参数简写 `ccus export lw`(`tw` = 本周)
136
- - 周度导出固定覆盖**完整一周(周一到周日)**:`this-week` 即使本周还没过完、后面几天还没有任何数据,文件名的起止日期也会补齐到本周日,`dailySummaries` 同样按整周 7 天逐日输出
137
- - 默认输出一个 `json` 数据包,里面同时包含 `rawEvents`、`weeklySummary`、`dailySummaries`
138
- - 导出文件内容为**紧凑 JSON**(无缩进),并默认 **gzip 压缩**后写成 `.json.gz`;gzip 与紧凑化都只是存储/展示层变化,解压后的字段集合与 `schemaVersion` 不变
139
- - 默认写 `.json.gz`;若用 `--out` 指定一个非 `.gz` 结尾的路径,则按明文 JSON 写出(不压缩)
140
- - 当前导出 bundle / weeklySummary 的 `schemaVersion` 为 `6`,用于标识已使用 `fiveHourLatestUsagePct`、`fiveHourPeakUsagePct`、`sevenDayLatestUsagePct`、`sevenDayPeakUsagePct` 字段的新导出契约
141
- - 默认文件名会带 git email 的帐号名前缀和起止日期,例如:`alice_export_2026-05-26_to_2026-06-01.json.gz`
142
- - `userMessageCount` 来自 `~/.claude/projects/**/*.jsonl` 的非 meta `type:user` 事件
143
- - `apiRequestCount` token 指标来自 `~/.claude/projects/**/*.jsonl` 中带 `message.usage` 的 `type:assistant` 事件
144
- - `dailySummaries` 会按每天输出消息数、请求数、token 和当天 statusline usage 摘要
145
- - 不再支持其它导出格式
146
-
147
- ## 多人汇总
148
-
149
- - 输入目录放很多通过 `ccus export` 导出的 bundle 文件,`.json.gz`(gzip 压缩)与明文 `.json` 都能识别,gzip 文件读取时自动解压
150
- - `aggregate` 目前只接受 `schemaVersion: 6` 的 bundle;旧导出请先用当前版本重新 `ccus export`
151
- - `ccus aggregate --input-dir DIR --out-dir DIR`
152
- - 输出三个文件:
153
- - `detail.csv`:来自每个 bundle 的 `rawEvents`,`contextUsedM` / `contextMaxM` 为单条事件的 context window token;另附带 `inputTokensM` / `outputTokensM` / `cacheReadInputTokensM`(按 `date` 取自当天 `dailySummaries` 的日总量,同一天多行会重复,不能按行求和)
154
- - `daily.csv`:直接来自每个 bundle `dailySummaries`
155
- - `weekly.csv`:直接来自每个 bundle `weeklySummary`
156
- - CSV 里所有以 token 计的列(context 与 in/out/cache)都以百万(M)为单位(原始值除以 1,000,000),列名统一带 `M` 后缀;`contextWindowPct` 仍是百分比
157
- - 想直接查看团队多人 dashboard,可以用 `ccus aggregate serve --input-dir DIR [--port 0] [--host 127.0.0.1]`:默认监听 `127.0.0.1` 上的随机端口,启动后会自动用系统默认浏览器打开,每次请求实时读取目录里的 bundle,不写入任何文件
158
-
159
- ## 调试
160
-
161
- 出问题时(比如 statusline 不出数据、导出/聚合结果不对),可以打开详细日志:
162
-
163
- - 给任意命令加 `--verbose`(或 `--debug` / `-v`),例如 `ccus export --verbose`、`ccus aggregate --input-dir DIR --verbose`
164
- - 或设置环境变量 `CCUS_DEBUG=1`,对 Claude Code 自动调用的 `ccus statusline emit` 尤其方便(无法临时加参数时)
165
-
166
- 注意:
167
-
168
- - 调试日志一律输出到 **stderr**,stdout 仍然只输出正常结果(statusline 单行文本 / 文件路径),所以加上 `--verbose` 不会破坏 statusline 渲染
169
- - 平时 `ccus statusline emit` 即使内部出错也会静默降级输出兜底文本;开启调试后会把真正的错误堆栈打到 stderr,便于定位
170
-
171
- ## 默认数据目录
172
-
173
- - Windows: `%LOCALAPPDATA%\\ccus`
174
- - macOS: `~/Library/Application Support/ccus`
175
- - Linux: `$XDG_DATA_HOME/ccus` 或 `~/.local/share/ccus`
176
-
177
- ## 当前日志记录字段
178
-
179
- - `timestamp`
180
- - `gitUserName`
181
- - `gitUserEmail`
182
- - `schemaVersion`
183
- - `rawPayload`
184
-
185
- ## 开发
186
-
187
- 从源码构建:
188
-
189
- ```bash
190
- npm install
191
- npm run build
192
- ```
193
-
194
- 测试:
195
-
196
- ```bash
197
- npm run test:src # 直接跑 TypeScript 源码测试(tsx)
198
- npm run build # 编译到 dist
199
- npm test # 跑编译后的测试
200
- ```
201
-
202
- 发布到 npm 时只包含运行时产物(`dist` 下的 `cli.js`、`lib/**/*.js`、`types.js`)与 `README.md`、`package.json`;源码、测试、sourcemap、内部文档不会被打包。
1
+ # ccus
2
+
3
+ 一个本地优先的 Claude Code statusline 使用率采集 CLI:
4
+
5
+ - `ccus install`:自动把 statusLine 命令写进 Claude Code 的 `settings.json`,省去手动改配置。
6
+ - `ccus statusline emit`:读取 Claude Code statusline 通过 `stdin` 传入的 JSON,输出 statusline 文本,并写入本地日志(加 `--no-store` / `--no-log` 则只输出、不落盘)。
7
+ - `ccus dashboard serve`:直接启动本地 Web 页面,不用先手动生成 HTML 文件。
8
+ - `ccus export`:默认导出当前周数据包(gzip 压缩的 `.json.gz`),里面同时包含原始事件和按天维度的周汇总。
9
+ - `ccus aggregate`:读取一个目录里的多人 export bundle(`.json.gz` 或 `.json`),输出明细、按天、按周三个 CSV。
10
+ - `ccus aggregate serve`:同样以 bundle 目录为输入,启动本地多人 dashboard 页面,不落地任何文件。
11
+ - `ccus update`:主动检查 npm 上是否有新版本,有则提示手动升级命令;`ccus --version` 查看当前版本。
12
+
13
+ > **支持范围**:`ccus statusline emit` 依赖 Claude Code 的 statusLine 机制(从 `stdin` 读 JSON、向 `stdout` 回一行文本),**只在命令行版 Claude Code(CLI / 终端)里生效**。
14
+ >
15
+ > Claude **桌面版** 和 **VS Code 插件** 都不支持 statusLine,因此不会调用 `ccus statusline emit`,也就采集不到使用率数据。
16
+
17
+ ## 安装
18
+
19
+ 全局安装(statusline 每次渲染都会调用,推荐全局装好,避免 `npx` 的启动开销):
20
+
21
+ ```bash
22
+ npm install -g ccus-cli
23
+ ```
24
+
25
+ 要求 Node.js >= 20。
26
+
27
+ ## 更新检查
28
+
29
+ ccus 通过 npm 全局安装,自带一个轻量的更新检查:
30
+
31
+ - statusline 渲染时会**异步、节流(每天最多一次)**地向 npm registry 查询最新版本,结果缓存到数据目录下的 `update-check.json`。检查在 detached 后台进程里完成,**不阻塞 statusline、不污染单行输出**。
32
+ - 一旦发现有更新,statusline 行尾会追加一个小标记,例如 `… | ⏱ 11:44 | ⬆ v0.1.5`。
33
+ - 看到标记后手动升级即可:
34
+
35
+ ```bash
36
+ npm i -g ccus-cli@latest
37
+ ```
38
+
39
+ 也可以随时主动检查:
40
+
41
+ ```bash
42
+ ccus update # 立即查 registry,有新版本则打印升级命令
43
+ ccus --version # 查看当前安装的版本
44
+ ```
45
+
46
+ > 出于稳妥考虑,ccus **只提示、不自动替你执行全局安装**。如需走私服或镜像(如 npmmirror),设置环境变量 `CCUS_REGISTRY` 指向对应 registry 即可。
47
+
48
+ ## 快速开始
49
+
50
+ 全局安装后,一条命令把 statusline 接进 Claude Code:
51
+
52
+ ```bash
53
+ ccus install
54
+ ```
55
+
56
+ 然后照常使用 Claude Code,statusline 会显示 5 小时额度使用率(`5h`)、7 天额度使用率(`7d`)、context window 占用百分比(`ctx`)、模型名、工作区名,以及当前 git 分支(`⎇ <branch>`,实时读取,非 git 仓库或处于 detached HEAD 时省略该段);原始 payload 也会落到本地日志,供后续 dashboard / export 使用。
57
+
58
+ > **ctx 高占用标红(按窗口大小分档)**:当 context 占用偏高时,`ctx` 段会整段标红提醒。触发条件为「百分比超阈值」或「已用 token 超阈值」任一满足。
59
+ >
60
+ > ccus 会根据 `contextMax` 自动判断当前是哪种上下文窗口,并套用各自独立的挡位(`contextMax > 400K` 视为 1M 档,否则按 200K 档):
61
+ >
62
+ > | 档位 | 默认百分比阈值 | 默认 token 阈值 | 百分比环境变量 | token 环境变量 |
63
+ > | --- | --- | --- | --- | --- |
64
+ > | 200K 窗口 | `80`(约 160K 标红) | 不启用 | `CCUS_CTX_RED_PCT_200K` | `CCUS_CTX_RED_TOKENS_200K` |
65
+ > | 1M 窗口 | `50`(约 500K 标红) | 不启用 | `CCUS_CTX_RED_PCT_1M` | `CCUS_CTX_RED_TOKENS_1M` |
66
+ >
67
+ > 阈值优先级:**档位专属环境变量 > 通用环境变量(`CCUS_CTX_RED_PCT` / `CCUS_CTX_RED_TOKENS`)> 档位内置默认**。token 阈值支持 `120000` / `120k` / `0.5m` 写法。例如:
68
+ >
69
+ > - 只想让 200K 窗口在 70% 标红:设 `CCUS_CTX_RED_PCT_200K=70`。
70
+ > - 让 1M 窗口已用 token 超过 600K 就标红:设 `CCUS_CTX_RED_TOKENS_1M=600k`。
71
+ > - 两档统一用同一个百分比阈值:设通用 `CCUS_CTX_RED_PCT`(不设专属变量时生效)。
72
+ >
73
+ > 标红只是 statusline 的颜色展示,不改变 stdin/stdout 文本契约,也不落盘、不进任何导出/聚合契约。
74
+
75
+ 攒了一段时间数据后,最常用的几条命令:
76
+
77
+ ```bash
78
+ ccus export # 导出当前周数据包(this-week)
79
+ ccus export lw # 导出上一整周(last-week,周一到周日)
80
+ ccus export tw # 导出本周(等价于默认 ccus export)
81
+
82
+ ccus dashboard serve # 启动本地页面,默认看本周(this-week)的 5 小时使用率曲线与每日用户消息数
83
+
84
+ ccus aggregate --input-dir ./team-exports # 多人的数据汇总,可以导出 detail.csv、daily.csv、weekly.csv 三个维度的文件
85
+ ccus aggregate serve --input-dir ./team-exports #直接打开一个看板
86
+ ```
87
+
88
+ ### 一键安装(推荐)
89
+
90
+ 不想手动改配置时,直接运行:
91
+
92
+ ```bash
93
+ ccus install
94
+ ```
95
+
96
+ 行为:
97
+
98
+ - 默认写入 `~/.claude/settings.json`(可用 `--settings PATH` 覆盖;遵循 `CCUS_CLAUDE_DATA_DIR`)
99
+ - 默认写入的命令是 `ccus statusline emit`(需要先全局安装,让 PATH 上能找到 `ccus`)
100
+ - 只覆盖 `statusLine` 字段(保留其下已有的 `padding` 等键),其它顶层设置原样保留
101
+ - 已存在且命令一致时显示 `already configured`,被替换时会回显旧命令
102
+ - `settings.json` 无法解析为 JSON 时直接报错,不会覆盖文件
103
+ - `--command CMD` 可完全自定义命令;`--data-dir PATH` 会在默认命令后追加 `--data-dir`,让采样落到指定目录
104
+
105
+ ### 手动配置
106
+
107
+ 也可以手动在 `settings.json` 里写:
108
+
109
+ ```json
110
+ {
111
+ "statusLine": {
112
+ "type": "command",
113
+ "command": "ccus statusline emit"
114
+ }
115
+ }
116
+ ```
117
+
118
+ ## 常用命令
119
+
120
+ ```bash
121
+ ccus install
122
+ ccus install --settings ~/.claude/settings.json
123
+ ccus statusline emit
124
+ ccus statusline emit --no-store # 只渲染并输出状态行,不写本地日志(别名 --no-log)
125
+ ccus dashboard build --range today --out ./ccus-dashboard.html
126
+ ccus dashboard open --range today
127
+ ccus dashboard serve --range today --open
128
+ ccus export
129
+ ccus export --range today
130
+ ccus export --range last-week
131
+ ccus export lw # 位置参数简写,等价于 --range last-week
132
+ ccus export tw # 等价于 --range this-week
133
+ ccus export --out ./alice_export_2026-05-26_to_2026-06-01.json # --out 指定非 .gz 路径时写明文 JSON
134
+ ccus aggregate --input-dir ./team-exports --out-dir ./team-report
135
+ ccus aggregate serve --input-dir ./team-exports
136
+ ```
137
+
138
+ `serve` 会启动一个本地 HTTP 服务,默认监听 `127.0.0.1` 上的随机端口,并在每次请求时实时读取最新日志生成页面。`serve` 默认查看 `this-week`(整周)使用量曲线(`build` / `open` 仍默认 `today`),可用 `--range` 覆盖。
139
+
140
+ 其中:
141
+
142
+ - `5 小时使用量百分比` **展示指标**,来自 Claude 自身字段 `rate_limits.five_hour.used_percentage`
143
+ - 使用率趋势图会在同一张图上叠加两条线:实线为 5 小时使用率(`rate_limits.five_hour`),虚线为 7 天使用率(`rate_limits.seven_day`),两者各自独立按时间桶聚合
144
+ - 页面新增 **每日用户消息数** 柱状图:按自然日统计的真实用户请求数,口径与导出契约的 `userMessageCount` 一致(来自 `~/.claude/projects/**/*.jsonl`),不是 statusline 采样数,也仅用于页面展示、不进任何导出/聚合契约
145
+ - 跨多天的窗口(如 `this-week` / `last-week`)使用率曲线会自动改用小时桶聚合,避免一周生成上千个点,且 x 轴改为按自然日(月-日)打刻度
146
+ - 顶部统计卡展示 `Latest 5h usage`、`Peak 5h usage`、`Latest 7d usage`(含峰值)、`用户消息数`(窗口内每日真实用户请求数合计)
147
+ - `--range today / this-week / last-week / 24h` 是 **你要查看的采样历史时间窗口**(`last-week` 指上一个完整周一到周日)
148
+ - statusline 日志本身主要保存 `rawPayload` 与外部补充字段;默认导出时会同时保留原始事件,并额外汇总 `~/.claude/projects/**/*.jsonl` 中的会话 usage
149
+
150
+ ## 导出
151
+
152
+ - 默认导出 `this-week`;如需导出上一个完整周(周一到周日),用 `--range last-week`,或位置参数简写 `ccus export lw`(`tw` = 本周)
153
+ - 周度导出固定覆盖**完整一周(周一到周日)**:`this-week` 即使本周还没过完、后面几天还没有任何数据,文件名的起止日期也会补齐到本周日,`dailySummaries` 同样按整周 7 天逐日输出
154
+ - 默认输出一个 `json` 数据包,里面同时包含 `rawEvents`、`weeklySummary`、`dailySummaries`
155
+ - 导出文件内容为**紧凑 JSON**(无缩进),并默认 **gzip 压缩**后写成 `.json.gz`;gzip 与紧凑化都只是存储/展示层变化,解压后的字段集合与 `schemaVersion` 不变
156
+ - 默认写 `.json.gz`;若用 `--out` 指定一个非 `.gz` 结尾的路径,则按明文 JSON 写出(不压缩)
157
+ - 当前导出 bundle / weeklySummary `schemaVersion` `6`,用于标识已使用 `fiveHourLatestUsagePct`、`fiveHourPeakUsagePct`、`sevenDayLatestUsagePct`、`sevenDayPeakUsagePct` 字段的新导出契约
158
+ - 默认文件名会带 git email 的帐号名前缀和起止日期,例如:`alice_export_2026-05-26_to_2026-06-01.json.gz`
159
+ - `userMessageCount` 来自 `~/.claude/projects/**/*.jsonl` 的非 meta `type:user` 事件
160
+ - `apiRequestCount` 与 token 指标来自 `~/.claude/projects/**/*.jsonl` 中带 `message.usage` 的 `type:assistant` 事件
161
+ - `dailySummaries` 会按每天输出消息数、请求数、token 和当天 statusline usage 摘要
162
+ - 不再支持其它导出格式
163
+
164
+ ## 多人汇总
165
+
166
+ - 输入目录放很多通过 `ccus export` 导出的 bundle 文件,`.json.gz`(gzip 压缩)与明文 `.json` 都能识别,gzip 文件读取时自动解压
167
+ - `aggregate` 目前只接受 `schemaVersion: 6` 的 bundle;旧导出请先用当前版本重新 `ccus export`
168
+ - `ccus aggregate --input-dir DIR --out-dir DIR`
169
+ - 输出三个文件:
170
+ - `detail.csv`:来自每个 bundle 的 `rawEvents`,`contextUsedM` / `contextMaxM` 为单条事件的 context window token;另附带 `inputTokensM` / `outputTokensM` / `cacheReadInputTokensM`(按 `date` 取自当天 `dailySummaries` 的日总量,同一天多行会重复,不能按行求和)
171
+ - `daily.csv`:直接来自每个 bundle 的 `dailySummaries`
172
+ - `weekly.csv`:直接来自每个 bundle 的 `weeklySummary`
173
+ - CSV 里所有以 token 计的列(context 与 in/out/cache)都以百万(M)为单位(原始值除以 1,000,000),列名统一带 `M` 后缀;`contextWindowPct` 仍是百分比
174
+ - 想直接查看团队多人 dashboard,可以用 `ccus aggregate serve --input-dir DIR [--port 0] [--host 127.0.0.1]`:默认监听 `127.0.0.1` 上的随机端口,启动后会自动用系统默认浏览器打开,每次请求实时读取目录里的 bundle,不写入任何文件
175
+
176
+ ## 调试
177
+
178
+ 出问题时(比如 statusline 不出数据、导出/聚合结果不对),可以打开详细日志:
179
+
180
+ - 给任意命令加 `--verbose`(或 `--debug` / `-v`),例如 `ccus export --verbose`、`ccus aggregate --input-dir DIR --verbose`
181
+ - 或设置环境变量 `CCUS_DEBUG=1`,对 Claude Code 自动调用的 `ccus statusline emit` 尤其方便(无法临时加参数时)
182
+
183
+ 注意:
184
+
185
+ - 调试日志一律输出到 **stderr**,stdout 仍然只输出正常结果(statusline 单行文本 / 文件路径),所以加上 `--verbose` 不会破坏 statusline 渲染
186
+ - 平时 `ccus statusline emit` 即使内部出错也会静默降级输出兜底文本;开启调试后会把真正的错误堆栈打到 stderr,便于定位
187
+
188
+ ## 默认数据目录
189
+
190
+ - Windows: `%LOCALAPPDATA%\\ccus`
191
+ - macOS: `~/Library/Application Support/ccus`
192
+ - Linux: `$XDG_DATA_HOME/ccus` 或 `~/.local/share/ccus`
193
+
194
+ ## 当前日志记录字段
195
+
196
+ - `timestamp`
197
+ - `gitUserName`
198
+ - `gitUserEmail`
199
+ - `schemaVersion`
200
+ - `rawPayload`
201
+
202
+ ## 开发
203
+
204
+ 从源码构建:
205
+
206
+ ```bash
207
+ npm install
208
+ npm run build
209
+ ```
210
+
211
+ 测试:
212
+
213
+ ```bash
214
+ npm run test:src # 直接跑 TypeScript 源码测试(tsx)
215
+ npm run build # 编译到 dist
216
+ npm test # 跑编译后的测试
217
+ ```
218
+
219
+ 发布到 npm 时只包含运行时产物(`dist` 下的 `cli.js`、`lib/**/*.js`、`types.js`)与 `README.md`、`package.json`;源码、测试、sourcemap、内部文档不会被打包。
package/dist/cli.js CHANGED
@@ -532,11 +532,23 @@ function resolveExportOptions(action, args, rest) {
532
532
  }
533
533
  return options;
534
534
  }
535
+ /** 用 readline 向用户提问,返回用户输入的一行文本。 */
536
+ async function prompt(question) {
537
+ const rl = (await Promise.resolve().then(() => __importStar(require("node:readline")))).createInterface({
538
+ input: process.stdin,
539
+ output: process.stderr,
540
+ });
541
+ return new Promise((resolve) => {
542
+ rl.question(question, (answer) => {
543
+ rl.close();
544
+ resolve(answer.trim());
545
+ });
546
+ });
547
+ }
535
548
  /**
536
549
  * `ccus update`:用户主动检查更新(绕过 24h 节流)。
537
550
  *
538
- * 根据当前的产品选择,这里只做「检查 + 提示」,不替用户执行全局安装。
539
- * 有新版本时打印应当手动运行的 `npm i -g` 命令。
551
+ * 发现新版本时交互式询问用户是否立即安装;输入 y/Y 则执行 `npm i -g ccus-cli@latest`。
540
552
  */
541
553
  async function handleUpdate(options) {
542
554
  const dataDir = getDataDir(options);
@@ -552,11 +564,30 @@ async function handleUpdate(options) {
552
564
  }
553
565
  // 顺手刷新缓存,让 statusline 标记和这次检查结果保持一致。
554
566
  await (0, update_check_1.performUpdateCheck)(dataDir);
555
- if ((0, version_1.isNewerVersion)(latest, current)) {
556
- process.stdout.write(`发现新版本:v${current} -> v${latest}\n运行以下命令升级:\n npm i -g ccus-cli@latest\n`);
557
- }
558
- else {
567
+ if (!(0, version_1.isNewerVersion)(latest, current)) {
559
568
  process.stdout.write(`已是最新版本 v${current}\n`);
569
+ return;
570
+ }
571
+ process.stdout.write(`发现新版本:v${current} -> v${latest}\n`);
572
+ let answer;
573
+ try {
574
+ answer = await prompt("立即升级?[y/N] ");
575
+ }
576
+ catch {
577
+ // stdin 不可交互(如管道),退回纯提示。
578
+ process.stdout.write(`运行以下命令升级:\n npm i -g ccus-cli@latest\n`);
579
+ return;
580
+ }
581
+ if (answer.toLowerCase() !== "y") {
582
+ process.stdout.write(`已取消。如需手动升级:\n npm i -g ccus-cli@latest\n`);
583
+ return;
584
+ }
585
+ process.stdout.write("正在升级…\n");
586
+ const { spawnSync } = await Promise.resolve().then(() => __importStar(require("node:child_process")));
587
+ const result = spawnSync("npm", ["i", "-g", "ccus-cli@latest"], { stdio: "inherit", shell: true });
588
+ if (result.status !== 0) {
589
+ process.stdout.write("升级失败,请手动运行:\n npm i -g ccus-cli@latest\n");
590
+ process.exitCode = 1;
560
591
  }
561
592
  }
562
593
  /**