Skip to content

Commit b01b4d0

Browse files
committed
Initial commit: CCMonitor v1.0.0
A native macOS menu bar app for real-time monitoring of Claude Code token usage and costs. Features include FSEvents-based file watching, incremental JSONL parsing, LiteLLM pricing with 3-tier cache, multi-dimensional aggregation, Swift Charts dashboard, burn rate forecasting, and budget alerts.
0 parents  commit b01b4d0

47 files changed

Lines changed: 3967 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: macos-15
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Select Xcode
16+
run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
17+
18+
- name: Build
19+
run: swift build
20+
21+
- name: Run tests
22+
run: swift test

.github/workflows/release.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build-and-release:
13+
runs-on: macos-15
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Select Xcode
18+
run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
19+
20+
- name: Build release
21+
run: ./scripts/build-app.sh release
22+
23+
- name: Zip app bundle
24+
run: |
25+
cd build
26+
zip -r CCMonitor.app.zip CCMonitor.app
27+
28+
- name: Extract version from tag
29+
id: version
30+
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
31+
32+
- name: Create GitHub Release
33+
uses: softprops/action-gh-release@v2
34+
with:
35+
name: CCMonitor ${{ steps.version.outputs.VERSION }}
36+
body: |
37+
## CCMonitor ${{ steps.version.outputs.VERSION }}
38+
39+
### Installation
40+
1. Download `CCMonitor.app.zip` below
41+
2. Unzip and move `CCMonitor.app` to `/Applications/`
42+
3. Launch from `/Applications/` (required for Launch at Login)
43+
44+
### Requirements
45+
- macOS 14.0 (Sonoma) or later
46+
files: build/CCMonitor.app.zip
47+
draft: false
48+
prerelease: false

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Swift / SPM
2+
.build/
3+
.swiftpm/
4+
Package.resolved
5+
*.xcodeproj/
6+
xcuserdata/
7+
DerivedData/
8+
9+
# Build output
10+
build/
11+
12+
# macOS
13+
.DS_Store
14+
*.dSYM/
15+
16+
# IDE
17+
.vscode/
18+
.idea/
19+
20+
# Reference project (not part of CCMonitor)
21+
ccusage/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 AgentsMesh
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Package.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// swift-tools-version: 5.10
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "CCMonitor",
7+
platforms: [
8+
.macOS(.v14),
9+
],
10+
dependencies: [
11+
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"),
12+
],
13+
targets: [
14+
.executableTarget(
15+
name: "CCMonitor",
16+
dependencies: [
17+
.product(name: "Logging", package: "swift-log"),
18+
],
19+
path: "Sources/CCMonitor",
20+
resources: [
21+
.process("Resources"),
22+
]
23+
),
24+
.testTarget(
25+
name: "CCMonitorTests",
26+
dependencies: ["CCMonitor"],
27+
path: "Tests/CCMonitorTests"
28+
),
29+
]
30+
)

README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# CCMonitor
2+
3+
A native macOS menu bar app for real-time monitoring of [Claude Code](https://docs.anthropic.com/en/docs/claude-code) token usage and costs.
4+
5+
<p align="center">
6+
<img src="https://img.shields.io/badge/platform-macOS%2014%2B-blue" alt="Platform">
7+
<img src="https://img.shields.io/badge/swift-5.10-orange" alt="Swift">
8+
<img src="https://img.shields.io/badge/license-MIT-green" alt="License">
9+
</p>
10+
11+
## Features
12+
13+
- **Real-time Monitoring** — Watches `~/.claude/projects/**/*.jsonl` via FSEvents, processes new entries within seconds
14+
- **Accurate Pricing** — Fetches model pricing from LiteLLM database with 3-tier cache (remote → local → embedded fallback)
15+
- **Incremental Processing** — Tracks byte offsets per file; restarts pick up exactly where they left off
16+
- **Rich Dashboard** — Swift Charts with bar/line toggle, time range selection (minutes/hours/days), click-to-inspect data points
17+
- **Menu Bar at a Glance** — Configurable display: cost only, cost + tokens, or icon only
18+
- **Multi-dimensional Aggregation** — By time (minute/hour/day), by project, by model, by session
19+
- **Burn Rate & Forecast** — Real-time $/hr rate with daily and monthly cost projections
20+
- **Budget Alerts** — Configurable daily/monthly budgets with visual progress indicators
21+
- **Instant Startup** — Aggregation snapshots restore cached data in under a second
22+
23+
## Requirements
24+
25+
- macOS 14.0 (Sonoma) or later
26+
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed and used (generates the JSONL logs this app monitors)
27+
28+
## Installation
29+
30+
### Download Release
31+
32+
Download the latest `CCMonitor.app.zip` from [Releases](https://github.com/AgentsMesh/CCMonitor/releases), unzip, and move to `/Applications/`.
33+
34+
### Build from Source
35+
36+
```bash
37+
git clone https://github.com/AgentsMesh/CCMonitor.git
38+
cd CCMonitor
39+
40+
# Build release .app bundle
41+
./scripts/build-app.sh release
42+
43+
# Run directly
44+
open build/CCMonitor.app
45+
46+
# Or install to /Applications
47+
cp -R build/CCMonitor.app /Applications/
48+
```
49+
50+
> **Note:** `SMAppService` requires the app to be in `/Applications` for Launch at Login to work.
51+
52+
## Architecture
53+
54+
```
55+
FSEvents (directory watch, 0.5s latency)
56+
57+
58+
IncrementalFileReader (byte offset tracking, persistent state)
59+
│ [String] new lines
60+
61+
JSONLParser (filter type=assistant + message.usage, dedup by hash)
62+
│ [UsageEntry]
63+
64+
CostCalculator + PricingService (token × price, 200K tiered pricing)
65+
│ UsageEntry + cost
66+
67+
UsageAggregator (@Observable, incremental multi-dimension aggregation)
68+
│ automatic SwiftUI refresh
69+
70+
Dashboard UI (Swift Charts + SwiftUI)
71+
```
72+
73+
### Key Design Decisions
74+
75+
| Decision | Rationale |
76+
|----------|-----------|
77+
| Swift Package Manager (not Xcode project) | Reproducible builds, no `.xcodeproj` noise |
78+
| `@Observable` (Observation framework) | Modern SwiftUI state management, fine-grained updates |
79+
| FSEvents API | Native macOS file watching, recursive directory support |
80+
| Actor-based `IncrementalFileReader` | Thread-safe byte offset tracking across concurrent file access |
81+
| 3-tier pricing cache | Accurate online pricing with offline resilience |
82+
| Aggregation snapshots | Sub-second startup after first run |
83+
84+
## Project Structure
85+
86+
```
87+
Sources/CCMonitor/
88+
├── App/ # Entry point, AppState pipeline, Launch at Login
89+
├── Models/ # UsageEntry, ModelPricing, AggregatedUsage, SessionInfo, ProjectInfo
90+
├── Services/
91+
│ ├── Watcher/ # FSEventsWatcher, IncrementalFileReader
92+
│ ├── Parser/ # JSONLParser
93+
│ ├── Pricing/ # PricingService (LiteLLM), CostCalculator (tiered pricing)
94+
│ ├── Aggregation/ # UsageAggregator, BurnRateCalculator, AggregationCache
95+
│ └── Persistence/ # SwiftData UsageStore
96+
├── ViewModels/ # MenuBarViewModel, DashboardViewModel, SettingsViewModel
97+
├── Views/
98+
│ ├── MenuBar/ # Menu bar popover
99+
│ ├── Dashboard/Panels/ # Summary cards, time series, model distribution, projects, budget
100+
│ ├── Settings/ # General + Budget tabs
101+
│ └── Components/ # Reusable UI components
102+
├── Utilities/ # Constants, Formatters, PathDiscovery, WindowManager
103+
└── Resources/ # Embedded pricing fallback
104+
```
105+
106+
## Development
107+
108+
```bash
109+
# Build debug
110+
swift build
111+
112+
# Run tests
113+
swift test
114+
115+
# Build release .app
116+
./scripts/build-app.sh release
117+
```
118+
119+
### Dependencies
120+
121+
| Package | Version | Purpose |
122+
|---------|---------|---------|
123+
| [swift-log](https://github.com/apple/swift-log) | ≥ 1.5.0 | Structured logging |
124+
125+
All other frameworks (SwiftUI, SwiftData, Charts, AppKit, ServiceManagement) are system-provided.
126+
127+
## License
128+
129+
MIT

0 commit comments

Comments
 (0)