GDM
36.48M · 2026-03-29
最近重度使用 Claude Code 做开发,每天的 token 消耗量非常大。虽然有 npx ccusage@latest 这样的命令行工具可以查看用量,但每次都要跑一遍命令,而且输出是纯文本表格,不够直观。
我想要的是:
于是决定用 SwiftUI 写一个 macOS 原生 App。整个过程从设计到开发到上架 GitHub,全程用 Claude Code 完成。
顶部四个指标卡片:总费用、总 Token、缓存命中率、会话数。中间是每日用量柱状图(鼠标悬停有 tooltip),右侧是模型分布饼图。
堆叠面积图展示各项目的 Token 消耗趋势,下方表格可以展开查看每个会话的详情。
按模型维度统计费用和 Token 分布。Opus 果然是大头。
所有会话按时间排序,支持搜索和排序,点进去可以看到 Token 时间线、模型切换、工具调用日志。
Claude Code 会在本地 ~/.claude/projects/ 目录下,为每个项目、每个会话生成 JSONL 文件。每一行是一个 JSON 对象,记录了:
{
"type": "assistant",
"message": {
"model": "claude-opus-4-6",
"usage": {
"input_tokens": 3,
"output_tokens": 9,
"cache_creation_input_tokens": 44874,
"cache_read_input_tokens": 0
}
},
"timestamp": "2026-03-19T12:14:17.775Z",
"sessionId": "7e175846-a0c7-4fcb-9f3f-5aaed25b5f4b",
"cwd": "/xxx",
"gitBranch": "xxx/xxx"
}
关键字段:
usage — 四种 token 计数:input、output、cache_creation、cache_readmodel — 使用的模型(opus/sonnet/haiku 等)sessionId + timestamp — 会话关联和时间线cwd + gitBranch — 项目和分支信息| 组件 | 选择 | 理由 |
|---|---|---|
| UI 框架 | SwiftUI | macOS 原生,声明式 UI |
| 图表 | Swift Charts | Apple 官方图表库,和 SwiftUI 无缝集成 |
| 数据层 | 纯内存模型 | 数据量不大,不需要数据库 |
| 项目管理 | XcodeGen | YAML 配置生成 xcodeproj,方便版本控制 |
| 最低版本 | macOS 14 | Swift Charts 的 SectorMark 需要 |
| 第三方依赖 | 无 | 零依赖,纯 Apple 框架 |
App
├── AppState (ObservableObject) # 全局状态 + 时间范围过滤
├── JSONLParser (Actor) # 异步解析所有 JSONL 文件
├── StatsEngine # 按日期/项目/模型聚合统计
├── ModelPricing # 可自定义的模型定价
└── L10n # 中英文国际化
数据流:App 启动 → JSONLParser 扫描 ~/.claude/projects/ → 解析所有 .jsonl 文件(包括子代理) → 构建 Project/Session 模型 → AppState 持有数据 → 各 View 通过 @EnvironmentObject 消费。
费用计算基于 Anthropic 官方定价,四种 token 类型分别计价:
static func cost(for model: String, usage: TokenUsage) -> Double {
let price = priceFor(model)
let input = Double(usage.inputTokens) / 1_000_000 * price.inputPerMillion
let output = Double(usage.outputTokens) / 1_000_000 * price.outputPerMillion
let cacheWrite = Double(usage.cacheCreationTokens) / 1_000_000 * price.cacheWritePerMillion
let cacheRead = Double(usage.cacheReadTokens) / 1_000_000 * price.cacheReadPerMillion
return input + output + cacheWrite + cacheRead
}
当前定价(2026年3月):
| 模型 | Input | Output | Cache Write | Cache Read |
|---|---|---|---|---|
| Opus 4.6 | $5/MTok | $25/MTok | $6.25/MTok | $0.50/MTok |
| Sonnet 4.6 | $3/MTok | $15/MTok | $3.75/MTok | $0.30/MTok |
| Haiku 4.5 | $1/MTok | $5/MTok | $1.25/MTok | $0.10/MTok |
用户可以在 Settings 里自定义每个模型的单价。
Swift Charts 本身不提供 hover tooltip,需要用 chartOverlay + onContinuousHover 手动实现:
.chartOverlay { proxy in
GeometryReader { geo in
Rectangle().fill(.clear).contentShape(Rectangle())
.onContinuousHover { phase in
switch phase {
case .active(let loc):
hoverLocation = loc
chartWidth = geo.size.width
if let date: Date = proxy.value(atX: loc.x) {
selectedDate = Calendar.current.startOfDay(for: date)
}
case .ended:
selectedDate = nil
}
}
}
}
Tooltip 位置需要处理边界情况 — 鼠标靠右时 tooltip 要翻转到左侧:
let tooltipW: CGFloat = 170
let xOff: CGFloat = hoverLocation.x + tooltipW + 20 > chartWidth
? hoverLocation.x - tooltipW - 12 // 翻转到左侧
: hoverLocation.x + 16 // 正常在右侧
Claude Code 的项目目录名是把文件路径中的 / 替换成 -,比如:
-Users-devsh-Documents-cnb-code-app-backend
需要解析回可读的项目名。策略是跳过常见路径前缀(Users、Documents 等),取最后有意义的部分:
static func decodeProjectName(_ dirName: String) -> String {
let components = dirName.components(separatedBy: "-").filter { !$0.isEmpty }
let skipPrefixes = ["Users", "Documents", "var", "folders", "private", "tmp", "T"]
// ... 跳过前缀,返回最后 1-2 个有意义的段
}
用 GitHub Actions 实现打 tag 自动构建 DMG 并发布到 Releases:
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
build:
runs-on: macos-15
steps:
- uses: actions/checkout@v4
- run: brew install xcodegen
- run: xcodegen generate
- run: xcodebuild -project Tokmon.xcodeproj -scheme Tokmon -configuration Release -derivedDataPath build
- run: |
mkdir dmg_contents
cp -R build/Build/Products/Release/Tokmon.app dmg_contents/
ln -s /Applications dmg_contents/Applications
hdiutil create -volname "Tokmon" -srcfolder dmg_contents -ov -format UDZO "Tokmon-${GITHUB_REF_NAME}.dmg"
- uses: softprops/action-gh-release@v2
with:
files: Tokmon-*.dmg
发版只需要:
git tag -a v1.0.0 -m "v1.0.0" && git push origin v1.0.0
通过 Tokmon 分析自己的使用数据,发现了几个有意思的点:
从 GitHub Releases 下载 DMG,拖到 Applications 即可。
brew install xcodegen
git clone
cd Tokmon
xcodegen generate
open Tokmon.xcodeproj # Cmd+R 运行
项目完全开源,MIT 协议:github.com/learningpro…
欢迎 Star、Issue、PR。如果你也在重度使用 Claude Code,希望这个工具能帮你更好地了解自己的用量和费用。
整个项目从设计到开发到发布,全程使用 Claude Code 完成。包括 UI 设计稿(用 Gemini 生成)、SwiftUI 代码、JSONL 解析、图表交互、国际化、CI/CD 配置、App 图标、README,甚至这篇文章。