feat: move CLI config into its own Settings tab
This commit is contained in:
@@ -1032,16 +1032,10 @@ struct SessionsSettings: View {
|
|||||||
@State private var errorMessage: String?
|
@State private var errorMessage: String?
|
||||||
@State private var loading = false
|
@State private var loading = false
|
||||||
@State private var hasLoaded = false
|
@State private var hasLoaded = false
|
||||||
@State private var configModel: String = ""
|
|
||||||
@State private var configStorePath: String = SessionLoader.defaultStorePath
|
|
||||||
@State private var configContextTokens: String = ""
|
|
||||||
@State private var configStatus: String?
|
|
||||||
@State private var configSaving = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 14) {
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
self.header
|
self.header
|
||||||
self.configEditor
|
|
||||||
self.storeMetadata
|
self.storeMetadata
|
||||||
Divider().padding(.vertical, 4)
|
Divider().padding(.vertical, 4)
|
||||||
self.content
|
self.content
|
||||||
@@ -1052,7 +1046,6 @@ struct SessionsSettings: View {
|
|||||||
.task {
|
.task {
|
||||||
guard !self.hasLoaded else { return }
|
guard !self.hasLoaded else { return }
|
||||||
self.hasLoaded = true
|
self.hasLoaded = true
|
||||||
self.loadConfig()
|
|
||||||
await self.refresh()
|
await self.refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1068,57 +1061,6 @@ struct SessionsSettings: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var configEditor: some View {
|
|
||||||
VStack(alignment: .leading, spacing: 10) {
|
|
||||||
Text("Clawdis CLI config")
|
|
||||||
.font(.callout.weight(.semibold))
|
|
||||||
Text("Writes to ~/.clawdis/clawdis.json (inbound.reply.agent/session).")
|
|
||||||
.font(.footnote)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
|
|
||||||
LabeledContent("Model") {
|
|
||||||
TextField("e.g. claude-3.5-sonnet", text: self.$configModel)
|
|
||||||
.textFieldStyle(.roundedBorder)
|
|
||||||
.frame(width: 260)
|
|
||||||
}
|
|
||||||
|
|
||||||
LabeledContent("Session store") {
|
|
||||||
TextField("Path", text: self.$configStorePath)
|
|
||||||
.textFieldStyle(.roundedBorder)
|
|
||||||
.frame(width: 320)
|
|
||||||
}
|
|
||||||
|
|
||||||
LabeledContent("Context tokens") {
|
|
||||||
TextField("Optional", text: self.$configContextTokens)
|
|
||||||
.textFieldStyle(.roundedBorder)
|
|
||||||
.frame(width: 160)
|
|
||||||
}
|
|
||||||
|
|
||||||
HStack(spacing: 12) {
|
|
||||||
Button {
|
|
||||||
Task { await self.saveConfig() }
|
|
||||||
} label: {
|
|
||||||
Label(self.configSaving ? "Saving…" : "Save config", systemImage: "square.and.arrow.down")
|
|
||||||
.labelStyle(.titleAndIcon)
|
|
||||||
}
|
|
||||||
.disabled(self.configSaving)
|
|
||||||
|
|
||||||
Button {
|
|
||||||
self.loadConfig()
|
|
||||||
} label: {
|
|
||||||
Label("Revert", systemImage: "arrow.uturn.backward")
|
|
||||||
}
|
|
||||||
.disabled(self.configSaving)
|
|
||||||
|
|
||||||
if let configStatus {
|
|
||||||
Text(configStatus)
|
|
||||||
.font(.footnote)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var storeMetadata: some View {
|
private var storeMetadata: some View {
|
||||||
VStack(alignment: .leading, spacing: 8) {
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
HStack(alignment: .top, spacing: 10) {
|
HStack(alignment: .top, spacing: 10) {
|
||||||
@@ -1257,6 +1199,76 @@ struct SessionsSettings: View {
|
|||||||
NSWorkspace.shared.open(url.deletingLastPathComponent())
|
NSWorkspace.shared.open(url.deletingLastPathComponent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
struct ConfigSettings: View {
|
||||||
|
@State private var configModel: String = ""
|
||||||
|
@State private var configStorePath: String = SessionLoader.defaultStorePath
|
||||||
|
@State private var configContextTokens: String = ""
|
||||||
|
@State private var configStatus: String?
|
||||||
|
@State private var configSaving = false
|
||||||
|
@State private var hasLoaded = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
|
Text("Clawdis CLI config")
|
||||||
|
.font(.title3.weight(.semibold))
|
||||||
|
Text("Edit ~/.clawdis/clawdis.json (inbound.reply.agent/session).")
|
||||||
|
.font(.callout)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
|
||||||
|
LabeledContent("Model") {
|
||||||
|
TextField("e.g. claude-3.5-sonnet", text: self.$configModel)
|
||||||
|
.textFieldStyle(.roundedBorder)
|
||||||
|
.frame(width: 260)
|
||||||
|
}
|
||||||
|
|
||||||
|
LabeledContent("Session store") {
|
||||||
|
TextField("Path", text: self.$configStorePath)
|
||||||
|
.textFieldStyle(.roundedBorder)
|
||||||
|
.frame(width: 360)
|
||||||
|
}
|
||||||
|
|
||||||
|
LabeledContent("Context tokens") {
|
||||||
|
TextField("Optional", text: self.$configContextTokens)
|
||||||
|
.textFieldStyle(.roundedBorder)
|
||||||
|
.frame(width: 160)
|
||||||
|
}
|
||||||
|
|
||||||
|
HStack(spacing: 12) {
|
||||||
|
Button {
|
||||||
|
Task { await self.saveConfig() }
|
||||||
|
} label: {
|
||||||
|
Label(self.configSaving ? "Saving…" : "Save config", systemImage: "square.and.arrow.down")
|
||||||
|
.labelStyle(.titleAndIcon)
|
||||||
|
}
|
||||||
|
.disabled(self.configSaving)
|
||||||
|
|
||||||
|
Button {
|
||||||
|
self.loadConfig()
|
||||||
|
} label: {
|
||||||
|
Label("Revert", systemImage: "arrow.uturn.backward")
|
||||||
|
}
|
||||||
|
.disabled(self.configSaving)
|
||||||
|
|
||||||
|
if let configStatus {
|
||||||
|
Text(configStatus)
|
||||||
|
.font(.footnote)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.padding(.horizontal, 12)
|
||||||
|
.task {
|
||||||
|
guard !self.hasLoaded else { return }
|
||||||
|
self.hasLoaded = true
|
||||||
|
self.loadConfig()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func configURL() -> URL {
|
private func configURL() -> URL {
|
||||||
FileManager.default.homeDirectoryForCurrentUser
|
FileManager.default.homeDirectoryForCurrentUser
|
||||||
@@ -1325,8 +1337,6 @@ struct SessionsSettings: View {
|
|||||||
withIntermediateDirectories: true)
|
withIntermediateDirectories: true)
|
||||||
try data.write(to: url, options: [.atomic])
|
try data.write(to: url, options: [.atomic])
|
||||||
self.configStatus = "Saved to \(url.path)"
|
self.configStatus = "Saved to \(url.path)"
|
||||||
// refresh session view with new defaults
|
|
||||||
await self.refresh()
|
|
||||||
} catch {
|
} catch {
|
||||||
self.configStatus = "Save failed: \(error.localizedDescription)"
|
self.configStatus = "Save failed: \(error.localizedDescription)"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user