ccus-cli 0.2.4 → 0.2.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 CHANGED
@@ -162,7 +162,7 @@ ccus aggregate serve --input-dir ./team-exports
162
162
  - 默认输出一个 `json` 数据包,里面同时包含 `rawEvents`、`weeklySummary`、`dailySummaries`
163
163
  - 导出文件内容为**紧凑 JSON**(无缩进),并默认 **gzip 压缩**后写成 `.json.gz`;gzip 与紧凑化都只是存储/展示层变化,解压后的字段集合与 `schemaVersion` 不变
164
164
  - 默认写 `.json.gz`;若用 `--out` 指定一个非 `.gz` 结尾的路径,则按明文 JSON 写出(不压缩)
165
- - 当前导出 bundle / weeklySummary 的 `schemaVersion` 为 `8`:v7 起新增 `weeklySummary.codex` 与 `dailySummaries[].codex`(Codex CLI 的消息/请求/token 统计),v8 起该 codex 段再加 5h/7d 的 peak/latest 额度(从 `source="codex"` 事件重算、与 Claude 额度分开看);aggregate daily/weekly CSV 的主字段(消息/请求/token/额度)已把 Codex **叠加进 Claude 合计**(累加量相加、额度 peak 取两源 max、latest 两源相加、7d 累计含两源读数),不再单列 `codex*` 列,detail.csv 加 `source` 列区分来源
165
+ - 当前导出 bundle / weeklySummary 的 `schemaVersion` 为 `9`:v7 起新增 `weeklySummary.codex` 与 `dailySummaries[].codex`(Codex CLI 的消息/请求/token 统计),v8 起该 codex 段再加 5h/7d 的 peak/latest 额度(从 `source="codex"` 事件重算、与 Claude 额度分开看),v9 起 codex `inputTokens` 改为净输入(`input_tokens - cached_input_tokens`,不含缓存命中)以对齐 Claude 的 `input_tokens` 口径;aggregate daily/weekly CSV 的主字段(消息/请求/token/额度)已把 Codex **叠加进 Claude 合计**(累加量相加、额度 peak 取两源 max、latest 两源相加、7d 累计含两源读数),不再单列 `codex*` 列,detail.csv 加 `source` 列区分来源
166
166
  - 默认文件名会带 git email 的帐号名前缀和起止日期,例如:`alice_export_2026-05-26_to_2026-06-01.json.gz`
167
167
  - `userMessageCount` 来自 `~/.claude/projects/**/*.jsonl` 的非 meta `type:user` 事件
168
168
  - `apiRequestCount` 与 token 指标来自 `~/.claude/projects/**/*.jsonl` 中带 `message.usage` 的 `type:assistant` 事件
@@ -172,7 +172,7 @@ ccus aggregate serve --input-dir ./team-exports
172
172
  ## 多人汇总
173
173
 
174
174
  - 输入目录放很多通过 `ccus export` 导出的 bundle 文件,`.json.gz`(gzip 压缩)与明文 `.json` 都能识别,gzip 文件读取时自动解压
175
- - `aggregate` 接受 `schemaVersion: 6/7/8` 的 bundle(v8 含 codex 额度,v7/v6 容错回退 null/零值);更旧的导出请先用当前版本重新 `ccus export`
175
+ - `aggregate` 接受 `schemaVersion: 6/7/8/9` 的 bundle(v9 codex inputTokens 为净输入,v8 含 codex 额度,v7/v6 容错回退 null/零值);更旧的导出请先用当前版本重新 `ccus export`
176
176
  - 同一个人在多台电脑上各自导出 bundle 时会自动合并去重:去重以**天**为粒度,对每个「同人同天」取 `generatedAt` 最新的那份导出,避免同一台机器重复导出或周与周重叠造成翻倍;**周汇总不取整周单份,而是把按天去重后的各天数据上卷累加**,所以多台电脑在不同天产生的用量会正确合进同一周。usage(5h / 7d)从选中事件按真实时间戳重算,Claude+Codex 合并:peak 取两源 max、latest 两源相加
177
177
  - `ccus aggregate --input-dir DIR --out-dir DIR`
178
178
  - 输出三个文件:
package/dist/cli.js CHANGED
@@ -395,7 +395,7 @@ async function runExport(options) {
395
395
  exportUserName = gitIdentity.userName;
396
396
  }
397
397
  const weeklySummary = {
398
- schemaVersion: 8,
398
+ schemaVersion: 9,
399
399
  generatedAt: new Date().toISOString(),
400
400
  range: {
401
401
  label: window.label,
@@ -479,7 +479,7 @@ async function runExport(options) {
479
479
  };
480
480
  });
481
481
  const bundle = {
482
- schemaVersion: 8,
482
+ schemaVersion: 9,
483
483
  generatedAt: new Date().toISOString(),
484
484
  range: {
485
485
  label: window.label,
@@ -50,7 +50,7 @@ function isWeeklyExportBundle(value) {
50
50
  if (!isRecord(value)) {
51
51
  return false;
52
52
  }
53
- if (typeof value.schemaVersion !== "number" || ![6, 7, 8].includes(value.schemaVersion)) {
53
+ if (typeof value.schemaVersion !== "number" || ![6, 7, 8, 9].includes(value.schemaVersion)) {
54
54
  return false;
55
55
  }
56
56
  if (!Array.isArray(value.rawEvents) || !Array.isArray(value.dailySummaries) || !isRecord(value.weeklySummary) || !isRecord(value.identity) || !isRecord(value.range)) {
@@ -131,7 +131,7 @@ async function loadWeeklyExportBundles(inputDir) {
131
131
  }
132
132
  }
133
133
  if (invalidFiles.length > 0) {
134
- throw new Error(`Unsupported export bundle schema in files: ${invalidFiles.join(", ")}. Re-export with current ccus so aggregate receives schemaVersion 6/7/8 bundles.`);
134
+ throw new Error(`Unsupported export bundle schema in files: ${invalidFiles.join(", ")}. Re-export with current ccus so aggregate receives schemaVersion 6/7/8/9 bundles.`);
135
135
  }
136
136
  return bundles;
137
137
  }
@@ -47,6 +47,8 @@ function timestampInRange(timestamp, start, end) {
47
47
  /**
48
48
  * 从 `token_count` 事件的 `info.last_token_usage` 取 token 用量对象(缺失返回 null)。
49
49
  * 必须用 last_token_usage(本次增量),不能用 total_token_usage(会话累计,会重复计)。
50
+ * 注意:Codex 的 `input_tokens` 含缓存命中(`cached_input_tokens` 是其子集),
51
+ * 累加 inputTokens 时要减去 cached 得到净输入,对齐 Claude 的 `input_tokens` 口径。
50
52
  */
51
53
  function extractLastTokenUsage(payload) {
52
54
  if (!isRecord(payload.info)) {
@@ -91,8 +93,10 @@ function summarizeRollout(content, start, end) {
91
93
  if (payload.type === "token_count") {
92
94
  const usage = extractLastTokenUsage(payload);
93
95
  if (usage) {
96
+ // 净输入 = input_tokens - cached_input_tokens(input_tokens 含缓存命中,减去对齐 Claude 口径)。
97
+ const netInputTokens = Math.max(0, getNumber(usage.input_tokens) - getNumber(usage.cached_input_tokens));
94
98
  result.apiRequestCount += 1;
95
- result.inputTokens += getNumber(usage.input_tokens);
99
+ result.inputTokens += netInputTokens;
96
100
  result.outputTokens += getNumber(usage.output_tokens);
97
101
  result.cacheReadInputTokens += getNumber(usage.cached_input_tokens);
98
102
  }
@@ -211,8 +215,10 @@ async function summarizeCodexSessionUsageByDay(start, end) {
211
215
  const usage = extractLastTokenUsage(payload);
212
216
  if (usage) {
213
217
  const current = ensureDay((0, time_1.localDateKey)(new Date(ms)));
218
+ // 同 summarizeRollout:累加净输入(input - cached),对齐 Claude 口径。
219
+ const netInputTokens = Math.max(0, getNumber(usage.input_tokens) - getNumber(usage.cached_input_tokens));
214
220
  current.apiRequestCount += 1;
215
- current.inputTokens += getNumber(usage.input_tokens);
221
+ current.inputTokens += netInputTokens;
216
222
  current.outputTokens += getNumber(usage.output_tokens);
217
223
  current.cacheReadInputTokens += getNumber(usage.cached_input_tokens);
218
224
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccus-cli",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Claude Code statusline usage logger and dashboard CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {