Compare commits

...
Author SHA1 Message Date
SuperDooper 73b251a1e9 chore: release notes for v1.2.1-beta.1 2026-05-10 23:14:48 +02:00
SuperDooper 7bab6a0df0 chore: bump to v1.2.1-beta.1 2026-05-10 23:14:47 +02:00
SuperDooper db6380fa66 fix: detect sign-in state from cookies on startup, add orgs API fallback for org ID 2026-05-10 23:14:45 +02:00
github-actions[bot] 47a148fa67 Release v1.2.0 2026-05-08 21:20:18 +00:00
SuperDooper 85ac329d36 chore: release notes for v1.2.0 2026-05-08 23:19:24 +02:00
SuperDooper a0fb6eabcf chore: bump to v1.2.0 2026-05-08 23:19:23 +02:00
github-actions[bot] b778d03323 Beta release v1.1.4-beta.7 2026-05-08 21:11:36 +00:00
SuperDooper 13387888b2 chore: release notes for 1.1.4-beta.7 2026-05-08 23:10:35 +02:00
SuperDooper 44be1649a1 chore: bump to 1.1.4-beta.7 2026-05-08 23:10:34 +02:00
SuperDooper 1160712e1b fix: remove ScrollView from main panel so popover auto-sizes to content 2026-05-08 23:10:22 +02:00
github-actions[bot] e4f55c80ee Beta release v1.1.4-beta.6 2026-05-08 21:05:48 +00:00
SuperDooper 526752dc36 chore: release notes for 1.1.4-beta.6 2026-05-08 23:04:54 +02:00
SuperDooper a2d983b555 chore: bump to 1.1.4-beta.6 2026-05-08 23:04:53 +02:00
SuperDooper 0d807c2285 fix: Session Diary — remove Claude icon/header, split stats left/right 2026-05-08 23:04:52 +02:00
SuperDooper 1c42433145 Windows beta release win-v0.0.1-beta.49 2026-05-08 20:46:42 +00:00
SuperDooper c0ac2e5a66 Windows beta release win-v0.0.1-beta.48 2026-05-08 20:39:17 +00:00
SuperDooper 405e65f9f7 Windows beta release win-v0.0.1-beta.47 2026-05-08 20:28:41 +00:00
SuperDooper 1c7433ebea Windows beta release win-v0.0.1-beta.46 2026-05-08 20:19:52 +00:00
SuperDooper a39ef800e8 Windows beta release win-v0.0.1-beta.45 2026-05-08 20:05:58 +00:00
SuperDooper 76dec8b85d Windows beta release win-v0.0.1-beta.44 2026-05-08 20:00:55 +00:00
SuperDooper 2f04f8581c Windows beta release win-v0.0.1-beta.42 2026-05-08 19:41:45 +00:00
SuperDooper 788c066a1e Windows beta release win-v0.0.1-beta.41 2026-05-08 19:39:07 +00:00
SuperDooper 31280d4ab2 Windows beta release win-v0.0.1-beta.40 2026-05-08 19:33:28 +00:00
SuperDooper 7b1c5bbf8e Windows beta release win-v0.0.1-beta.39 2026-05-08 19:19:11 +00:00
SuperDooper f2ba44bbaa Windows beta release win-v0.0.1-beta.38 2026-05-08 19:07:16 +00:00
SuperDooper de1fffe0e3 Windows beta release win-v0.0.1-beta.37 2026-05-08 19:00:02 +00:00
SuperDooper e80f07d1b9 Windows beta release win-v0.0.1-beta.36 2026-05-08 17:40:07 +00:00
github-actions[bot] e9ca8a7efc Beta release v1.1.4-beta.5 2026-05-08 17:32:10 +00:00
8 changed files with 46 additions and 25 deletions
+5 -8
View File
@@ -40,8 +40,7 @@ struct ContentView: View {
.environmentObject(updater)
.transition(.move(edge: .trailing).combined(with: .opacity))
} else {
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 0) {
VStack(spacing: 0) {
// Cards grid
if vm.limits.isEmpty {
EmptyStateView()
@@ -96,7 +95,6 @@ struct ContentView: View {
.padding(.bottom, 8)
}
}
}
}
.transition(.opacity)
@@ -398,12 +396,11 @@ struct DiaryRow: View {
var body: some View {
VStack(alignment: .leading, spacing: 5) {
HStack {
AgentIconView(agent: .claude, size: 12)
Text("Claude")
.font(.system(size: 12, weight: .medium))
.foregroundColor(color)
Text("\(totalSaved) samples")
.font(.system(size: 10.5))
.foregroundColor(.secondary)
Spacer()
Text("\(totalSaved) samples · Avg Burn Rate: +\(String(format: "%.1f", burnRate))%/h")
Text("Avg burn rate: \(String(format: "%.1f", burnRate))%/h")
.font(.system(size: 10.5))
.foregroundColor(.secondary)
}
+2 -2
View File
@@ -15,9 +15,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.4-beta.5</string>
<string>1.2.1-beta.1</string>
<key>CFBundleVersion</key>
<string>45</string>
<string>49</string>
<key>LSMinimumSystemVersion</key>
<string>13.0</string>
<key>LSUIElement</key>
+22 -1
View File
@@ -38,6 +38,16 @@ class UsageViewModel: ObservableObject {
burnHistoryStore = saved
}
loadPlaceholderData()
Task { await checkInitialSignInState() }
}
private func checkInitialSignInState() async {
let cookies = await WKWebsiteDataStore.default().httpCookieStore.allCookies()
let hasSession = cookies.contains {
$0.domain.contains("claude.ai") &&
($0.name == "sessionKey" || $0.name == "__Secure-next-auth.session-token")
}
if hasSession { isSignedIn = true }
}
func signOut() async {
@@ -140,11 +150,22 @@ class UsageViewModel: ObservableObject {
let memberships = (account?["memberships"] ?? json["memberships"]) as? [[String: Any]]
let firstOrg = memberships?.first?["organization"] as? [String: Any]
// org ID primary path then flat-list fallback
// org ID primary path then flat-list fallback then dedicated endpoint
var orgId: String? = firstOrg?["uuid"] as? String
if orgId == nil {
orgId = (json["organizations"] as? [[String: Any]])?.first?["uuid"] as? String
}
if orgId == nil, let cookie = await claudeCookieHeader() {
// Final fallback: fetch /api/organizations directly
var orgsReq = URLRequest(url: URL(string: "https://claude.ai/api/organizations")!)
orgsReq.setValue("application/json", forHTTPHeaderField: "accept")
orgsReq.setValue(cookie, forHTTPHeaderField: "Cookie")
if let (orgsData, orgsResp) = try? await URLSession.shared.data(for: orgsReq),
let orgsHttp = orgsResp as? HTTPURLResponse, orgsHttp.statusCode == 200,
let orgs = try? JSONSerialization.jsonObject(with: orgsData) as? [[String: Any]] {
orgId = orgs.first?["uuid"] as? String
}
}
let email = account?["email_address"] as? String
+2 -2
View File
@@ -8,9 +8,9 @@
[![macOS](https://img.shields.io/badge/macOS-13.0+-000000?style=flat&logo=apple&logoColor=white)](https://www.apple.com/macos/)
[![Swift](https://img.shields.io/badge/Swift-5.9-F05138?style=flat&logo=swift&logoColor=white)](https://swift.org)
[![Version](https://img.shields.io/badge/version-1.1.3-orange?style=flat)](https://github.com/superdooper86/claudechecker/releases)
[![Version](https://img.shields.io/badge/version-1.2.0-orange?style=flat)](https://github.com/superdooper86/claudechecker/releases)
[![License](https://img.shields.io/badge/license-MIT-blue?style=flat)](LICENSE)
[![Beta](https://img.shields.io/badge/beta-1.1.4--beta.4-orange?style=flat)](https://github.com/superdooper86/claudechecker/releases/tag/v1.1.4-beta.4) <!-- BETA_BADGE -->
<!-- BETA_BADGE -->
</div>
+6 -3
View File
@@ -1,4 +1,7 @@
## What's new in v1.1.4-beta.5
## What's new in v1.2.1
### Improvements
- Bootstrap API call consolidated — org ID, email, and plan name now fetched in a single request per refresh
### Bug fixes
- Fixed "Not signed in" showing incorrectly on launch when the session was already active
- Sign-in state is now detected immediately from stored cookies on startup, before the first data refresh completes
- Added `/api/organizations` as a final fallback for org ID resolution when the bootstrap API response doesn't include it
- Session cookie detection now checks both `sessionKey` and `__Secure-next-auth.session-token` cookie names
+3 -3
View File
@@ -1,5 +1,5 @@
{
"version": "1.1.4-beta.4",
"url": "https://github.com/superdooper86/claudechecker/releases/download/v1.1.4-beta.4/ClaudeChecker.zip",
"notes": "## What's new in v1.1.4-beta.4\n\n### Bug fix\n- Plan name now updates correctly on every refresh (was only set on first launch)"
"version": "1.1.4-beta.7",
"url": "https://github.com/superdooper86/claudechecker/releases/download/v1.1.4-beta.7/ClaudeChecker.zip",
"notes": "## What's new in v1.1.4-beta.7\n\n### Bug fix\n- Main panel no longer scrolls — popover now auto-sizes to fit content"
}
+3 -3
View File
@@ -1,5 +1,5 @@
{
"version": "0.0.1-beta.35",
"url": "https://github.com/superdooper86/claudechecker/releases/download/win-v0.0.1-beta.35/ClaudeChecker-Windows.zip",
"notes": "## What's new in beta.10\r\n\r\n### Bug fixes\r\n- Limits now update correctly on each refresh cycle\r\n- Session expiry is detected and prompts re-authentication instead of silently showing stale data\r\n- Plan name (e.g. Pro, Max) is now read from the API instead of being hardcoded"
"version": "0.0.1-beta.49",
"url": "https://github.com/superdooper86/claudechecker/releases/download/win-v0.0.1-beta.49/ClaudeChecker-Windows.zip",
"notes": "## What's new in beta.36\r\n\r\n### Bug fixes\r\n- Settings no longer incorrectly shows \"Not signed in\" when limits are working\r\n- Session Diary now shows correctly after the first successful refresh\r\n- Extra Usage Credits section now restored from cache on startup\r\n- Plan name, overage, and prepaid credits are now cached and shown immediately on launch\r\n- App now loads cached state instantly on startup before the background refresh completes"
}
+3 -3
View File
@@ -1,5 +1,5 @@
{
"version": "1.1.3",
"url": "https://github.com/superdooper86/claudechecker/releases/download/v1.1.3/ClaudeChecker.zip",
"notes": "## What's new in v1.1.3\n\n### UI polish\n- Limit headers now read \"5 Hour Limit\" and \"7 Day Limit\"\n- Tapping anywhere on the blue update banner opens the update window\n\n### Session Diary fix\n- Burn history is persisted across app launches — the sparkline populates immediately on first open instead of requiring a manual refresh\n\n### Window sizing fixes\n- The popover now resizes correctly when switching between the main view and settings\n- Background colour no longer shows through during the resize animation"
"version": "1.2.0",
"url": "https://github.com/superdooper86/claudechecker/releases/download/v1.2.0/ClaudeChecker.zip",
"notes": "## What's new in v1.2.0\n\n### Bug fixes\n- App now works for all users — org ID is fetched dynamically from the API instead of being hardcoded\n- Plan name (e.g. Pro, Max) now updates correctly on every refresh\n\n### Improvements\n- Plan name is read from the API rather than hardcoded\n- Bootstrap API call consolidated — org ID, email, and plan name fetched in a single request per refresh\n- Main panel no longer scrolls — popover auto-sizes to fit content\n- Session Diary card redesigned — sample count and avg burn rate shown left/right above the sparkline, Claude header removed"
}