8000 fix(collector): read plans in sync and split account-switch gaps for 0.10.3 by InfinityPacer · Pull Request #44 · InfinityPacer/meterleaf · GitHub
[go: up one dir, main page]

Skip to content

fix(collector): read plans in sync and split account-switch gaps for 0.10.3 - #44

Merged
InfinityPacer merged 4 commits into
mainfrom
fix/collector-credential-on-demand
Oct 21, 2026
Merged

InfinityPacer merged 4 commits into
mainfrom
fix/collector-credential-on-demand

Conversation

@InfinityPacer
Copy link
Copy Markdown
Owner

问题

  • 0.10.0 起采集器从登录凭据识别套餐,但凭据读取只接到了 scan,每分钟运行的后台 sync 一次都没读。新版 Claude Code 登录的 Pro、Max 账户在后台同步里仍是未识别套餐。
  • 修好接线后,如果每轮都读凭据,每天会读约 1440 次含令牌的凭据。改成每小时复查也没有意义,凭据没被改写,里面的套餐就不会变。
  • 两次运行之间切换 Claude 登录账户时,空档里的用量被记到「未归属」。切换前后的两个账户都是确定的,这样相当于凭空多出一个账户。

改动

  • sync 也接上凭据读取,与 scan 使用同一组数据来源(src/collector/main.ts)。
  • 凭据按需读取(src/collector/collect.ts、src/collector/claude-code/credential.ts)。
    • 每轮只看凭据的修改标记。macOS 用 security find-generic-password 不带 -w,只取条目属性,不取密码,也不需要授权。其他系统看 .credentials.json 的文件状态。
    • 只有在以下情况才读凭据内容:凭据被改写、登录账户或其资料变化、套餐在等第二轮确认。读不到时等凭据下次改写再试。拿不到修改标记时,退回每天复查一次。
  • 不同账户之间的空档按切换时刻分给前后两个账户(src/collector/attribution.ts、src/collector/claude-code/login.ts)。
    • 切换时刻依次取以下来源,前一个没有才用后一个:
      1. 会话记录里 /login 成功的那一行。只认整条消息正好是这段输出的用户行。
      2. 换账户时凭据的修改时间。
      3. 都没有时,整段空档算给新账户。
    • 额度读数仍按原规则,切换前后无法判断的读数直接跳过,避免把旧账户的读数挂到新账户上。
    • 升级后按新规则把已有事件重新归属一次,由 attribution_rules 记录规则版本。采集器本地状态只新增 login_hints 表,旧版本会忽略它。服务端数据库结构未变。
  • --help、docs/collector.md 和 CHANGELOG 已按现行行为更新,版本升到 0.10.3。

验证

  • bun test tests 472 个测试通过,bun run typecheck、bun run build、bun run build:collector、所改文件的 Prettier 检查和 git diff --check 均通过。
  • 新增的回归测试如下。
    • 命令行测试:后台 sync 两轮后上报凭据里的 team-premium,批次中不含令牌。该测试在旧代码上失败,收到的套餐为 null。
    • 凭据读取:50 轮内、以及过去 7 天凭据都未改写时不读取;改写后只读一次;改写后发现升级,连续两轮一致才采用;读不到时等改写再试;没有修改标记时每天复查一次。
    • 空档归属:会话里的登录时刻在多文件间分配空档;只有凭据修改时间时同样能分配;没有任何线索时归新账户;会话线索优先于凭据;空档外的线索不影响归属;引用到同样文字的工具输出不算登录;旧状态升级后只重新归属一次。
    • 原有测试「账户切换后空档无法判断」按新规则改为归新账户,额度跳过的测试保持不变并通过。
  • 在维护者的 Mac 上使用真实钥匙串验证。
    • 连续 5 轮采集只读了 2 次凭据内容,即第一轮读取和第二轮确认,之后只看修改标记,套餐始终为 team-premium。
    • 用临时数据目录和本机临时服务端运行 sync,第二轮上报 team-premium。
    • 在真实采集状态的副本上演练升级,已有归属无变化,也没有未归属事件。
    • 构建出的 dist/meterleaf-collector scan 正常识别套餐。

已知限制

  • 切换账户后,其他终端里仍在运行的会话可能还有几十秒继续使用旧账户,这段用量会算给新账户。
  • 在会话外登录且没有会话线索时,如果令牌刚好在空档内刷新,切换时刻可能偏差几分钟。
  • 已读过的历史会话不会回头补读 /login 线索,旧空档按「归新账户」处理。

🤖 Generated with Claude Code

InfinityPacer and others added 4 commits October 21, 2026 17:11
Background sync never received the credential reader, so only `scan`
detected plans from the login credential. Wire it into sync, and stop
reading it every round: read on a new or changed account, while a plan
awaits confirmation, hourly to catch upgrades, and hourly after a failed
read. Other rounds reuse the confirmed plan without touching the keychain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An unchanged credential cannot carry a new plan, so the hourly recheck
read the token for nothing. Compare the keychain item's modification
time (attributes only, no password) or the credential file's status
each round, and read the content only when it changed, the account or
its fields changed, or a plan awaits confirmation. Without a marker,
fall back to a daily recheck.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Usage between the last observation of one account and the first of the
next was filed under "unattributed", a phantom account. Split the gap at
the switch moment instead: the /login success line in the transcript,
else the credential's modification time, else give the whole gap to the
new account. Quota samples keep the strict rule. Existing gap events are
reattributed once after upgrade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@InfinityPacer
InfinityPacer merged commit 50c98b3 into main Oct 21, 2026
2 checks passed
@InfinityPacer
InfinityPacer deleted the fix/collector-credential-on-demand branch October 21, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0