feat: cron agent binding + doctor UI refresh

This commit is contained in:
Peter Steinberger
2026-01-13 03:23:36 +00:00
parent bfdbaa5ab6
commit b41e75a15d
19 changed files with 127 additions and 32 deletions

View File

@@ -13,6 +13,7 @@ extension CronJobEditor {
guard let job else { return }
self.name = job.name
self.description = job.description ?? ""
self.agentId = job.agentId ?? ""
self.enabled = job.enabled
self.sessionTarget = job.sessionTarget
self.wakeMode = job.wakeMode
@@ -67,6 +68,7 @@ extension CronJobEditor {
userInfo: [NSLocalizedDescriptionKey: "Name is required."])
}
let description = self.description.trimmingCharacters(in: .whitespacesAndNewlines)
let agentId = self.agentId.trimmingCharacters(in: .whitespacesAndNewlines)
let schedule: [String: Any]
switch self.scheduleKind {
case .at:
@@ -148,6 +150,11 @@ extension CronJobEditor {
"payload": payload,
]
if !description.isEmpty { root["description"] = description }
if !agentId.isEmpty {
root["agentId"] = agentId
} else if self.job?.agentId != nil {
root["agentId"] = NSNull()
}
if self.sessionTarget == .isolated {
let trimmed = self.postPrefix.trimmingCharacters(in: .whitespacesAndNewlines)

View File

@@ -3,6 +3,7 @@ extension CronJobEditor {
mutating func exerciseForTesting() {
self.name = "Test job"
self.description = "Test description"
self.agentId = "ops"
self.enabled = true
self.sessionTarget = .isolated
self.wakeMode = .now

View File

@@ -27,6 +27,7 @@ struct CronJobEditor: View {
@State var name: String = ""
@State var description: String = ""
@State var agentId: String = ""
@State var enabled: Bool = true
@State var sessionTarget: CronSessionTarget = .main
@State var wakeMode: CronWakeMode = .nextHeartbeat
@@ -77,6 +78,12 @@ struct CronJobEditor: View {
.textFieldStyle(.roundedBorder)
.frame(maxWidth: .infinity)
}
GridRow {
self.gridLabel("Agent ID")
TextField("Optional (default agent)", text: self.$agentId)
.textFieldStyle(.roundedBorder)
.frame(maxWidth: .infinity)
}
GridRow {
self.gridLabel("Enabled")
Toggle("", isOn: self.$enabled)

View File

@@ -145,6 +145,7 @@ struct CronJobState: Codable, Equatable {
struct CronJob: Identifiable, Codable, Equatable {
let id: String
let agentId: String?
var name: String
var description: String?
var enabled: Bool

View File

@@ -20,6 +20,9 @@ extension CronSettings {
HStack(spacing: 6) {
StatusPill(text: job.sessionTarget.rawValue, tint: .secondary)
StatusPill(text: job.wakeMode.rawValue, tint: .secondary)
if let agentId = job.agentId, !agentId.isEmpty {
StatusPill(text: "agent \(agentId)", tint: .secondary)
}
if let status = job.state.lastStatus {
StatusPill(text: status, tint: status == "ok" ? .green : .orange)
}
@@ -94,6 +97,9 @@ extension CronSettings {
if let desc = job.description, !desc.isEmpty {
LabeledContent("Description") { Text(desc).font(.callout) }
}
if let agentId = job.agentId, !agentId.isEmpty {
LabeledContent("Agent") { Text(agentId) }
}
LabeledContent("Session") { Text(job.sessionTarget.rawValue) }
LabeledContent("Wake") { Text(job.wakeMode.rawValue) }
LabeledContent("Next run") {

View File

@@ -7,6 +7,7 @@ struct CronSettings_Previews: PreviewProvider {
store.jobs = [
CronJob(
id: "job-1",
agentId: "ops",
name: "Daily summary",
description: nil,
enabled: true,
@@ -59,6 +60,7 @@ extension CronSettings {
let job = CronJob(
id: "job-1",
agentId: "ops",
name: "Daily summary",
description: "Summary job",
enabled: true,

View File

@@ -23,7 +23,9 @@ struct CronJobEditorSmokeTests {
@Test func cronJobEditorBuildsBodyForExistingJob() {
let job = CronJob(
id: "job-1",
agentId: "ops",
name: "Daily summary",
description: nil,
enabled: true,
createdAtMs: 1_700_000_000_000,
updatedAtMs: 1_700_000_000_000,

View File

@@ -60,6 +60,7 @@ struct CronModelsTests {
@Test func displayNameTrimsWhitespaceAndFallsBack() {
let base = CronJob(
id: "x",
agentId: nil,
name: " hello ",
description: nil,
enabled: true,
@@ -81,6 +82,7 @@ struct CronModelsTests {
@Test func nextRunDateAndLastRunDateDeriveFromState() {
let job = CronJob(
id: "x",
agentId: nil,
name: "t",
description: nil,
enabled: true,

View File

@@ -12,6 +12,7 @@ struct SettingsViewSmokeTests {
let job1 = CronJob(
id: "job-1",
agentId: "ops",
name: " Morning Check-in ",
description: nil,
enabled: true,
@@ -32,6 +33,7 @@ struct SettingsViewSmokeTests {
let job2 = CronJob(
id: "job-2",
agentId: nil,
name: "",
description: nil,
enabled: false,