fix(mac): show clawd browser path in config
parent
aeffdc3632
commit
161895ed1a
|
|
@ -162,6 +162,23 @@ struct ConfigSettings: View {
|
||||||
.disabled(!self.browserEnabled)
|
.disabled(!self.browserEnabled)
|
||||||
.onChange(of: self.browserControlUrl) { _, _ in self.autosaveConfig() }
|
.onChange(of: self.browserControlUrl) { _, _ in self.autosaveConfig() }
|
||||||
}
|
}
|
||||||
|
GridRow {
|
||||||
|
self.gridLabel("Browser path")
|
||||||
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
if let label = self.browserPathLabel {
|
||||||
|
Text(label)
|
||||||
|
.font(.caption.monospaced())
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.textSelection(.enabled)
|
||||||
|
.lineLimit(1)
|
||||||
|
.truncationMode(.middle)
|
||||||
|
} else {
|
||||||
|
Text("—")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
GridRow {
|
GridRow {
|
||||||
self.gridLabel("Accent")
|
self.gridLabel("Accent")
|
||||||
HStack(spacing: 8) {
|
HStack(spacing: 8) {
|
||||||
|
|
@ -319,6 +336,58 @@ struct ConfigSettings: View {
|
||||||
return Color(red: r, green: g, blue: b)
|
return Color(red: r, green: g, blue: b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var browserPathLabel: String? {
|
||||||
|
guard self.browserEnabled else { return nil }
|
||||||
|
|
||||||
|
let host = (URL(string: self.browserControlUrl)?.host ?? "").lowercased()
|
||||||
|
if !host.isEmpty, !Self.isLoopbackHost(host) {
|
||||||
|
return "remote (\(host))"
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let candidate = Self.detectedBrowserCandidate() else { return nil }
|
||||||
|
return candidate.executablePath ?? candidate.appPath
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct BrowserCandidate {
|
||||||
|
let name: String
|
||||||
|
let appPath: String
|
||||||
|
let executablePath: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func detectedBrowserCandidate() -> BrowserCandidate? {
|
||||||
|
let candidates: [(name: String, appName: String)] = [
|
||||||
|
("Google Chrome Canary", "Google Chrome Canary.app"),
|
||||||
|
("Chromium", "Chromium.app"),
|
||||||
|
("Google Chrome", "Google Chrome.app"),
|
||||||
|
]
|
||||||
|
|
||||||
|
let roots = [
|
||||||
|
"/Applications",
|
||||||
|
"\(NSHomeDirectory())/Applications",
|
||||||
|
]
|
||||||
|
|
||||||
|
let fm = FileManager.default
|
||||||
|
for (name, appName) in candidates {
|
||||||
|
for root in roots {
|
||||||
|
let appPath = "\(root)/\(appName)"
|
||||||
|
if fm.fileExists(atPath: appPath) {
|
||||||
|
let bundle = Bundle(url: URL(fileURLWithPath: appPath))
|
||||||
|
let exec = bundle?.executableURL?.path
|
||||||
|
return BrowserCandidate(name: name, appPath: appPath, executablePath: exec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func isLoopbackHost(_ host: String) -> Bool {
|
||||||
|
if host == "localhost" { return true }
|
||||||
|
if host == "127.0.0.1" { return true }
|
||||||
|
if host == "::1" { return true }
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private func loadModels() async {
|
private func loadModels() async {
|
||||||
guard !self.modelsLoading else { return }
|
guard !self.modelsLoading else { return }
|
||||||
self.modelsLoading = true
|
self.modelsLoading = true
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue