import KeyboardShortcutsimport SwiftUI @MainActorstruct AdvancedPane: View { @Bindable var settings: SettingsStore @State private var isInstallingCLI = false @State private var cliStatus: String? var body: some View { ScrollView(.vertical, showsIndicators: true) { VStack(alignment: .leading, spacing: 16) { SettingsSection(contentSpacing: 8) { Text(L("section_keyboard_shortcut")) .font(.caption) .foregroundStyle(.secondary) .textCase(.uppercase) HStack(alignment: .center, spacing: 12) { Text(L("open_menu_shortcut_title")) .font(.body) Spacer() KeyboardShortcuts.Recorder(for: .openMenu) } Text(L("open_menu_shortcut_subtitle")) .font(.footnote) .foregroundStyle(.tertiary) } Divider() SettingsSection(contentSpacing: 10) { HStack(spacing: 12) { Button { Task { await self.installCLI() } } label: { if self.isInstallingCLI { ProgressView().controlSize(.small) } else { Text(L("install_cli")) } } .disabled(self.isInstallingCLI) if let status = self.cliStatus { Text(status) .font(.footnote) .foregroundStyle(.tertiary) .lineLimit(2) } } Text(L("install_cli_subtitle")) .font(.footnote) .foregroundStyle(.tertiary) } Divider() SettingsSection(contentSpacing: 10) { PreferenceToggleRow( title: L("show_debug_settings_title"), subtitle: L("show_debug_settings_subtitle"), binding: self.$settings.debugMenuEnabled) PreferenceToggleRow( title: L("surprise_me_title"), subtitle: L("surprise_me_subtitle"), binding: self.$settings.randomBlinkEnabled) PreferenceToggleRow( title: L("weekly_limit_confetti_title"), subtitle: L("weekly_limit_confetti_subtitle"), binding: self.$settings.confettiOnWeeklyLimitResetsEnabled) } Divider() SettingsSection(contentSpacing: 10) { PreferenceToggleRow( title: L("hide_personal_info_title"), subtitle: L("hide_personal_info_subtitle"), binding: self.$settings.hidePersonalInfo) PreferenceToggleRow( title: L("show_provider_storage_usage_title"), subtitle: L("show_provider_storage_usage_subtitle"), binding: self.$settings.providerStorageFootprintsEnabled) } Divider() SettingsSection( title: L("section_keychain_access"), caption: L("keychain_access_caption")) { PreferenceToggleRow( title: L("disable_keychain_access_title"), subtitle: L("disable_keychain_access_subtitle"), binding: self.$settings.debugDisableKeychainAccess) } } .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, 20) .padding(.vertical, 12) } }} extension AdvancedPane { private func installCLI() async { if self.isInstallingCLI { return } self.isInstallingCLI = true defer { self.isInstallingCLI = false } let helperURL = Bundle.main.bundleURL.appendingPathComponent("Contents/Helpers/CodexBarCLI") let fm = FileManager.default guard fm.fileExists(atPath: helperURL.path) else { self.cliStatus = L("cli_not_found") return } let destinations = [ "/usr/local/bin/codexbar", "/opt/homebrew/bin/codexbar", ] var results: [String] = [] for dest in destinations { let dir = (dest as NSString).deletingLastPathComponent guard fm.fileExists(atPath: dir) else { continue } guard fm.isWritableFile(atPath: dir) else { results.append("No write access: \(dir)") continue } if fm.fileExists(atPath: dest) { if Self.isLink(atPath: dest, pointingTo: helperURL.path) { results.append("Installed: \(dir)") } else { results.append("Exists: \(dir)") } continue } do { try fm.createSymbolicLink(atPath: dest, withDestinationPath: helperURL.path) results.append("Installed: \(dir)") } catch { results.append("Failed: \(dir)") } } self.cliStatus = results.isEmpty ? L("no_writable_bin_dirs") : results.joined(separator: " · ") } private static func isLink(atPath path: String, pointingTo destination: String) -> Bool { guard let link = try? FileManager.default.destinationOfSymbolicLink(atPath: path) else { return false } let dir = (path as NSString).deletingLastPathComponent let resolved = URL(fileURLWithPath: link, relativeTo: URL(fileURLWithPath: dir)) .standardizedFileURL .path return resolved == destination }}
import KeyboardShortcuts
import SwiftUI
@MainActor
struct AdvancedPane: View {
@Bindable var settings: SettingsStore
@State private var isInstallingCLI = false
@State private var cliStatus: String?
var body: some View {
ScrollView(.vertical, showsIndicators: true) {
VStack(alignment: .leading, spacing: 16) {
SettingsSection(contentSpacing: 8) {
Text(L("section_keyboard_shortcut"))
.font(.caption)
.foregroundStyle(.secondary)
.textCase(.uppercase)
HStack(alignment: .center, spacing: 12) {
Text(L("open_menu_shortcut_title"))
.font(.body)
Spacer()
KeyboardShortcuts.Recorder(for: .openMenu)
}
Text(L("open_menu_shortcut_subtitle"))
.font(.footnote)
.foregroundStyle(.tertiary)
}
Divider()
SettingsSection(contentSpacing: 10) {
HStack(spacing: 12) {
Button {
Task { await self.installCLI() }
} label: {
if self.isInstallingCLI {
ProgressView().controlSize(.small)
} else {
Text(L("install_cli"))
}
}
.disabled(self.isInstallingCLI)
if let status = self.cliStatus {
Text(status)
.font(.footnote)
.foregroundStyle(.tertiary)
.lineLimit(2)
}
}
Text(L("install_cli_subtitle"))
.font(.footnote)
.foregroundStyle(.tertiary)
}
Divider()
SettingsSection(contentSpacing: 10) {
PreferenceToggleRow(
title: L("show_debug_settings_title"),
subtitle: L("show_debug_settings_subtitle"),
binding: self.$settings.debugMenuEnabled)
PreferenceToggleRow(
title: L("surprise_me_title"),
subtitle: L("surprise_me_subtitle"),
binding: self.$settings.randomBlinkEnabled)
PreferenceToggleRow(
title: L("weekly_limit_confetti_title"),
subtitle: L("weekly_limit_confetti_subtitle"),
binding: self.$settings.confettiOnWeeklyLimitResetsEnabled)
}
Divider()
SettingsSection(contentSpacing: 10) {
PreferenceToggleRow(
title: L("hide_personal_info_title"),
subtitle: L("hide_personal_info_subtitle"),
binding: self.$settings.hidePersonalInfo)
PreferenceToggleRow(
title: L("show_provider_storage_usage_title"),
subtitle: L("show_provider_storage_usage_subtitle"),
binding: self.$settings.providerStorageFootprintsEnabled)
}
Divider()
SettingsSection(
title: L("section_keychain_access"),
caption: L("keychain_access_caption"))
{
PreferenceToggleRow(
title: L("disable_keychain_access_title"),
subtitle: L("disable_keychain_access_subtitle"),
binding: self.$settings.debugDisableKeychainAccess)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 20)
.padding(.vertical, 12)
}
}
}
extension AdvancedPane {
private func installCLI() async {
if self.isInstallingCLI { return }
self.isInstallingCLI = true
defer { self.isInstallingCLI = false }
let helperURL = Bundle.main.bundleURL.appendingPathComponent("Contents/Helpers/CodexBarCLI")
let fm = FileManager.default
guard fm.fileExists(atPath: helperURL.path) else {
self.cliStatus = L("cli_not_found")
return
}
let destinations = [
"/usr/local/bin/codexbar",
"/opt/homebrew/bin/codexbar",
]
var results: [String] = []
for dest in destinations {
let dir = (dest as NSString).deletingLastPathComponent
guard fm.fileExists(atPath: dir) else { continue }
guard fm.isWritableFile(atPath: dir) else {
results.append("No write access: \(dir)")
continue
}
if fm.fileExists(atPath: dest) {
if Self.isLink(atPath: dest, pointingTo: helperURL.path) {
results.append("Installed: \(dir)")
} else {
results.append("Exists: \(dir)")
}
continue
}
do {
try fm.createSymbolicLink(atPath: dest, withDestinationPath: helperURL.path)
results.append("Installed: \(dir)")
} catch {
results.append("Failed: \(dir)")
}
}
self.cliStatus = results.isEmpty
? L("no_writable_bin_dirs")
: results.joined(separator: " · ")
}
private static func isLink(atPath path: String, pointingTo destination: String) -> Bool {
guard let link = try? FileManager.default.destinationOfSymbolicLink(atPath: path) else { return false }
let dir = (path as NSString).deletingLastPathComponent
let resolved = URL(fileURLWithPath: link, relativeTo: URL(fileURLWithPath: dir))
.standardizedFileURL
.path
return resolved == destination
}
}