diff --git a/ClaudeChecker/ContentView.swift b/ClaudeChecker/ContentView.swift
index 2c7f764..fd75fae 100644
--- a/ClaudeChecker/ContentView.swift
+++ b/ClaudeChecker/ContentView.swift
@@ -591,25 +591,48 @@ struct SettingsView: View {
.font(.system(size: 16, weight: .semibold))
// Auth section
- VStack(alignment: .leading, spacing: 6) {
+ VStack(alignment: .leading, spacing: 8) {
Label("Authentication", systemImage: "person.crop.circle")
.font(.system(size: 12, weight: .medium))
.foregroundColor(.secondary)
- Text("ClaudeChecker signs into claude.ai inside a built-in browser window and reads your quota data directly from the API. Your session is stored locally and persists across restarts.")
+ HStack(spacing: 6) {
+ Circle()
+ .fill(vm.isSignedIn ? Color.green : Color.orange)
+ .frame(width: 7, height: 7)
+ Text(vm.isSignedIn ? "Signed in to claude.ai" : "Not signed in")
+ .font(.system(size: 12, weight: .medium))
+ .foregroundColor(vm.isSignedIn ? .primary : .orange)
+ }
+
+ Text("Your session is stored locally and persists across restarts.")
.font(.system(size: 11.5))
.foregroundColor(.secondary)
.fixedSize(horizontal: false, vertical: true)
- Button(action: {
- showSettings = false
- vm.triggerLogin = true
- }) {
- Label("Sign in again", systemImage: "arrow.right.circle")
- .font(.system(size: 12))
+ HStack(spacing: 8) {
+ Button(action: {
+ showSettings = false
+ vm.triggerLogin = true
+ }) {
+ Label(vm.isSignedIn ? "Re-authenticate" : "Sign in", systemImage: "arrow.right.circle")
+ .font(.system(size: 12))
+ }
+ .buttonStyle(.bordered)
+ .controlSize(.small)
+
+ if vm.isSignedIn {
+ Button(action: {
+ Task { await vm.signOut() }
+ }) {
+ Label("Sign out", systemImage: "rectangle.portrait.and.arrow.right")
+ .font(.system(size: 12))
+ }
+ .buttonStyle(.bordered)
+ .controlSize(.small)
+ .tint(.red)
+ }
}
- .buttonStyle(.bordered)
- .controlSize(.small)
}
Divider()
diff --git a/ClaudeChecker/Info.plist b/ClaudeChecker/Info.plist
index e25d27c..ba1ad04 100644
--- a/ClaudeChecker/Info.plist
+++ b/ClaudeChecker/Info.plist
@@ -15,9 +15,9 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 2.0.5
+ 2.0.6
CFBundleVersion
- 12
+ 13
LSMinimumSystemVersion
13.0
LSUIElement
diff --git a/ClaudeChecker/UsageViewModel.swift b/ClaudeChecker/UsageViewModel.swift
index 60c17f3..3f1cea4 100644
--- a/ClaudeChecker/UsageViewModel.swift
+++ b/ClaudeChecker/UsageViewModel.swift
@@ -13,6 +13,7 @@ class UsageViewModel: ObservableObject {
@Published var overageSpendLimit: OverageSpendLimit?
@Published var planLabel: String = "Claude"
@Published var isNotAuthenticated: Bool = false
+ @Published var isSignedIn: Bool = false
@Published var triggerLogin: Bool = false
@Published var showInMenuBar: Bool = true {
didSet { UserDefaults.standard.set(showInMenuBar, forKey: "show_in_menubar") }
@@ -36,6 +37,21 @@ class UsageViewModel: ObservableObject {
loadPlaceholderData()
}
+ func signOut() async {
+ let store = WKWebsiteDataStore.default()
+ let types = WKWebsiteDataStore.allWebsiteDataTypes()
+ let records = await store.dataRecords(ofTypes: types)
+ let claudeRecords = records.filter { $0.displayName.contains("claude.ai") }
+ await store.removeData(ofTypes: types, for: claudeRecords)
+ isSignedIn = false
+ isNotAuthenticated = true
+ lastUpdated = nil
+ limits = []
+ extraUsage = nil
+ prepaidCredits = nil
+ overageSpendLimit = nil
+ }
+
func refresh() async {
isLoading = true
errorMessage = nil
@@ -54,6 +70,7 @@ class UsageViewModel: ObservableObject {
overageSpendLimit = overage
planLabel = "Pro"
lastUpdated = Date()
+ isSignedIn = true
for i in limits.indices {
let key = limits[i].window.rawValue
diff --git a/README.md b/README.md
index 4305a63..ea6b01a 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
[](https://www.apple.com/macos/)
[](https://swift.org)
-[](https://github.com/superdooper86/claudechecker/releases)
+[](https://github.com/superdooper86/claudechecker/releases)
[](LICENSE)
diff --git a/version.json b/version.json
index e7b0458..702782c 100644
--- a/version.json
+++ b/version.json
@@ -1,5 +1,5 @@
{
- "version": "2.0.5",
- "url": "https://github.com/superdooper86/claudechecker/releases/download/v2.0.5/ClaudeChecker.zip",
- "notes": "Fixed window size and update banner dismiss."
+ "version": "2.0.6",
+ "url": "https://github.com/superdooper86/claudechecker/releases/download/v2.0.6/ClaudeChecker.zip",
+ "notes": "Authentication section shows sign-in status with re-authenticate and sign out options."
}