feat: 用量改读 statusline 生产的本地快照(生产者/消费者),实时准确

原先读 statusline 的 /tmp API 兜底缓存;新版 Claude Code 走 stdin、该缓存不再刷新
→ 数字过期(14% vs 实际 60%+)。改为消费「打过补丁的 claude-statusline 从 stdin
落盘的权威实时快照」:
- USAGE_LOCAL_PATH 默认改指 ~/.claude/usage-snapshot.json
- 修复 resets_at 解析:Claude Code stdin 给的是 epoch 数字(非 ISO),_parse_reset_ts
  现兼容 epoch/ISO,否则算不出 time_pct、pace 会消失
- 仍不发任何网络请求;快照缺失/损坏 → "--"
- 同步更新 CLAUDE.md / README.md 的数据源说明(生产者/消费者)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 19:22:03 +08:00
parent 14359c8726
commit 21426e13bc
5 changed files with 35 additions and 26 deletions

19
data.py
View File

@@ -169,10 +169,14 @@ def _mao(now):
# ---------- Claude Code 用量 ----------
def _parse_iso_ts(s):
"""ISO 时间串 → epoch 秒兼容结尾 'Z'。失败返回 None。"""
if not s:
def _parse_reset_ts(s):
"""resets_at → epoch 秒兼容三种epoch 数字Claude Code stdin 给的就是 epoch
ISO 时间串(含结尾 'Z')、空。失败返回 None。"""
if s is None or s == "":
return None
s = str(s)
if s.replace(".", "", 1).isdigit(): # 纯数字 → 当作 epoch 秒
return float(s)
try:
return datetime.fromisoformat(s.replace("Z", "+00:00")).timestamp()
except Exception:
@@ -181,7 +185,7 @@ def _parse_iso_ts(s):
def _window_time_pct(resets_at, window, now):
"""该滚动窗口「已流逝时间百分比」= (window 距重置剩余) / window ×100。失败返回 None。"""
reset = _parse_iso_ts(resets_at)
reset = _parse_reset_ts(resets_at)
if reset is None:
return None
remaining = max(0, min(window, reset - now.timestamp()))
@@ -189,10 +193,11 @@ def _window_time_pct(resets_at, window, now):
def _usage(now):
"""Claude Code 用量5h / 7d——只读本地 statusline 缓存(见 usage_local.py**不发任何请求**。
"""Claude Code 用量5h / 7d——只读本地 statusline 生产的快照(见 usage_local.py**不发任何请求**。
time_pct(时间已流逝%) 与 pace 每次按当前时间**现算**resets_at 为绝对时间,始终准确)
utilization 取自本地缓存、可能滞后。文件缺失/损坏 → 回退占位 pct=Nonerenderer 显示 "--")。
utilization 来自 statusline 从 Claude Code stdin 落盘的权威实时值
time_pct(时间已流逝%) 与 pace 每次按当前时间**现算**resets_at 为绝对时间)。
文件缺失/损坏 → 回退占位 pct=Nonerenderer 显示 "--")。
结构契约renderer 依赖):{title, warn, bars:[{k, pct(0~100 或 None), time_pct(0~100)?}]}
pct ≥ warn 时该条进度条与百分比转红pace = pct time_pct>0 超前↑ / <0 节余↓)。
"""