Settings: move session store path to Debug

This commit is contained in:
Peter Steinberger
2025-12-07 04:38:08 +00:00
parent 2714ed503b
commit ddf8aef4f7
2 changed files with 97 additions and 39 deletions

View File

@@ -4,7 +4,6 @@ import SwiftUI
struct ConfigSettings: View {
@State private var configModel: String = ""
@State private var customModel: String = ""
@State private var configStorePath: String = SessionLoader.defaultStorePath
@State private var configSaving = false
@State private var hasLoaded = false
@State private var models: [ModelChoice] = []
@@ -93,15 +92,6 @@ struct ConfigSettings: View {
}
}
LabeledContent("Session store") {
TextField("Path", text: self.$configStorePath)
.textFieldStyle(.roundedBorder)
.frame(width: 360)
.onChange(of: self.configStorePath) { _, _ in
self.autosaveConfig()
}
}
Spacer()
}
.frame(maxWidth: .infinity, alignment: .leading)
@@ -128,26 +118,13 @@ struct ConfigSettings: View {
}
private func loadConfig() {
let url = self.configURL()
guard let data = try? Data(contentsOf: url) else {
self.configModel = SessionLoader.fallbackModel
self.configStorePath = SessionLoader.defaultStorePath
return
}
guard
let parsed = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let inbound = parsed["inbound"] as? [String: Any],
let reply = inbound["reply"] as? [String: Any]
else {
return
}
let parsed = self.loadConfigDict()
let inbound = parsed["inbound"] as? [String: Any]
let reply = inbound?["reply"] as? [String: Any]
let agent = reply?["agent"] as? [String: Any]
let heartbeatMinutes = reply?["heartbeatMinutes"] as? Int
let heartbeatBody = reply?["heartbeatBody"] as? String
let session = reply["session"] as? [String: Any]
let agent = reply["agent"] as? [String: Any]
let heartbeatMinutes = reply["heartbeatMinutes"] as? Int
let heartbeatBody = reply["heartbeatBody"] as? String
self.configStorePath = (session?["store"] as? String) ?? SessionLoader.defaultStorePath
let loadedModel = (agent?["model"] as? String) ?? ""
if !loadedModel.isEmpty {
self.configModel = loadedModel
@@ -171,19 +148,16 @@ struct ConfigSettings: View {
self.configSaving = true
defer { self.configSaving = false }
var session: [String: Any] = [:]
var agent: [String: Any] = [:]
var reply: [String: Any] = [:]
let trimmedStore = self.configStorePath.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmedStore.isEmpty { session["store"] = trimmedStore }
var root = self.loadConfigDict()
var inbound = root["inbound"] as? [String: Any] ?? [:]
var reply = inbound["reply"] as? [String: Any] ?? [:]
var agent = reply["agent"] as? [String: Any] ?? [:]
let chosenModel = (self.configModel == "__custom__" ? self.customModel : self.configModel)
.trimmingCharacters(in: .whitespacesAndNewlines)
let trimmedModel = chosenModel
if !trimmedModel.isEmpty { agent["model"] = trimmedModel }
reply["session"] = session
reply["agent"] = agent
if let heartbeatMinutes {
@@ -195,8 +169,8 @@ struct ConfigSettings: View {
reply["heartbeatBody"] = trimmedBody
}
let inbound: [String: Any] = ["reply": reply]
let root: [String: Any] = ["inbound": inbound]
inbound["reply"] = reply
root["inbound"] = inbound
do {
let data = try JSONSerialization.data(withJSONObject: root, options: [.prettyPrinted, .sortedKeys])
@@ -208,6 +182,12 @@ struct ConfigSettings: View {
} catch {}
}
private func loadConfigDict() -> [String: Any] {
let url = self.configURL()
guard let data = try? Data(contentsOf: url) else { return [:] }
return (try? JSONSerialization.jsonObject(with: data) as? [String: Any]) ?? [:]
}
private func loadModels() async {
guard !self.modelsLoading else { return }
self.modelsLoading = true

View File

@@ -10,6 +10,8 @@ struct DebugSettings: View {
@State private var modelsError: String?
@ObservedObject private var relayManager = RelayProcessManager.shared
@State private var relayRootInput: String = RelayProcessManager.shared.projectRootPath()
@State private var sessionStorePath: String = SessionLoader.defaultStorePath
@State private var sessionStoreSaveError: String?
var body: some View {
VStack(alignment: .leading, spacing: 10) {
@@ -65,6 +67,27 @@ struct DebugSettings: View {
.font(.caption2)
.foregroundStyle(.secondary)
}
LabeledContent("Session store") {
VStack(alignment: .leading, spacing: 6) {
HStack(spacing: 8) {
TextField("Path", text: self.$sessionStorePath)
.textFieldStyle(.roundedBorder)
.font(.caption.monospaced())
.frame(width: 340)
Button("Save") { self.saveSessionStorePath() }
.buttonStyle(.borderedProminent)
}
if let sessionStoreSaveError {
Text(sessionStoreSaveError)
.font(.footnote)
.foregroundStyle(.secondary)
} else {
Text("Used by the CLI session loader; stored in ~/.clawdis/clawdis.json.")
.font(.footnote)
.foregroundStyle(.secondary)
}
}
}
LabeledContent("Model catalog") {
VStack(alignment: .leading, spacing: 6) {
Text(self.modelCatalogPath)
@@ -115,7 +138,10 @@ struct DebugSettings: View {
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 12)
.task { await self.reloadModels() }
.task {
await self.reloadModels()
self.loadSessionStorePath()
}
}
private var pinoLogPath: String {
@@ -200,4 +226,56 @@ struct DebugSettings: View {
private func saveRelayRoot() {
RelayProcessManager.shared.setProjectRoot(path: self.relayRootInput)
}
private func loadSessionStorePath() {
let url = self.configURL()
guard
let data = try? Data(contentsOf: url),
let parsed = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let inbound = parsed["inbound"] as? [String: Any],
let reply = inbound["reply"] as? [String: Any],
let session = reply["session"] as? [String: Any],
let path = session["store"] as? String
else {
self.sessionStorePath = SessionLoader.defaultStorePath
return
}
self.sessionStorePath = path
}
private func saveSessionStorePath() {
let trimmed = self.sessionStorePath.trimmingCharacters(in: .whitespacesAndNewlines)
var root: [String: Any] = [:]
let url = self.configURL()
if let data = try? Data(contentsOf: url),
let parsed = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
{
root = parsed
}
var inbound = root["inbound"] as? [String: Any] ?? [:]
var reply = inbound["reply"] as? [String: Any] ?? [:]
var session = reply["session"] as? [String: Any] ?? [:]
session["store"] = trimmed.isEmpty ? SessionLoader.defaultStorePath : trimmed
reply["session"] = session
inbound["reply"] = reply
root["inbound"] = inbound
do {
let data = try JSONSerialization.data(withJSONObject: root, options: [.prettyPrinted, .sortedKeys])
try FileManager.default.createDirectory(
at: url.deletingLastPathComponent(),
withIntermediateDirectories: true)
try data.write(to: url, options: [.atomic])
self.sessionStoreSaveError = nil
} catch {
self.sessionStoreSaveError = error.localizedDescription
}
}
private func configURL() -> URL {
FileManager.default.homeDirectoryForCurrentUser
.appendingPathComponent(".clawdis")
.appendingPathComponent("clawdis.json")
}
}