Add ready, discard, merge-problem and workflow notifications

This commit is contained in:
Ian Gulliver
2026-10-19 19:35:23 -07:00
parent 31ee494c41
commit 88d1146778
7 changed files with 276 additions and 215 deletions
+31
View File
@@ -118,6 +118,37 @@ func clearTurns(_ taskId: String, through seq: Int64) {
}
}
@MainActor
func notifyTask(_ store: Store, _ ev: ByreEvent) {
guard let me = store.me, let taskId = ev.taskId, !taskId.isEmpty else {
return
}
let prefs = me.notificationPrefs
let origin = store.api.origin.absoluteString
switch ev.kind {
case "task.ready" where prefs.ready:
show(store, taskId, "task-\(taskId)@\(origin)", "Ready to merge: \(str(ev.payload.value, "overview") ?? "")")
case "task.discard_suggested" where prefs.discard:
show(store, taskId, "task-\(taskId)@\(origin)", "Suggests discard: \(str(ev.payload.value, "reason") ?? "")")
case "task.merge_stopped" where prefs.mergeProblems:
show(store, taskId, "task-\(taskId)@\(origin)", "Merge stopped: \(str(ev.payload.value, "reason") ?? "")")
case "task.merge_after_review_dropped" where prefs.mergeProblems:
show(store, taskId, "task-\(taskId)@\(origin)", "Didn't merge after the review: \(str(ev.payload.value, "reason") ?? "")")
case "task.workflow_finished" where prefs.workflows:
show(store, taskId, "workflow-\(ev.seq)@\(origin)", "Finished \(str(ev.payload.value, "workflow") ?? ""): \(str(ev.payload.value, "output") ?? "")")
default:
break
}
}
@MainActor
func clearTask(_ store: Store, _ taskId: String) {
let id = "task-\(taskId)@\(store.api.origin.absoluteString)"
enqueue {
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [id])
}
}
@MainActor
func notifyTurn(_ store: Store, _ ev: ByreEvent) {
guard let me = store.me, me.notificationPrefs.reports, ev.payload.value["summary"] as? Bool == true, let taskId = ev.taskId, !taskId.isEmpty else {
+4
View File
@@ -8,6 +8,10 @@ typealias NotificationPrefs = Components.Schemas.NotificationPrefs
private let kinds: [(key: WritableKeyPath<NotificationPrefs, Bool>, label: String)] = [
(\.questions, "Questions"),
(\.reports, "Turn summaries"),
(\.ready, "Ready to merge"),
(\.discard, "Suggests discard"),
(\.mergeProblems, "Merge problems"),
(\.workflows, "Workflow finished"),
(\.errors, "Session errors"),
(\.rateLimits, "Rate limits"),
]
+9
View File
@@ -624,6 +624,10 @@ final class Store {
try await self.loadProjects()
}
case "task.created", "task.merge_title", "task.merge_queued", "task.merge_unqueued", "task.merge_after_review", "task.merge_after_review_ended", "task.merge_after_review_cancelled", "task.parent_merge_started", "task.parent_merge_stopped", "task.merge_started", "task.merge_ended", "task.discard_started", "task.merged", "task.discarded", "task.state", "task.ready", "task.discard_suggested", "snapshot.created":
if let taskId = ev.taskId, ["task.merged", "task.discarded"].contains(ev.kind) || (ev.kind == "snapshot.created" && str(ev.payload.value, "trigger") != "answer") {
clearTask(self, taskId)
}
notifyTask(self, ev)
if let projectId = ev.projectId {
spawn("load tasks") {
try await self.loadTasks(projectId)
@@ -640,6 +644,9 @@ final class Store {
}
}
case "inbox.created":
if let taskId = ev.taskId {
clearTask(self, taskId)
}
notifyInbox(self, try! decodePayload(ev.payload, as: InboxItem.self))
spawn("load inbox") {
try await self.loadInbox()
@@ -656,6 +663,8 @@ final class Store {
}
case "session.error", "session.rate_limited":
notifyError(self, ev)
case "task.merge_stopped", "task.merge_after_review_dropped", "task.workflow_finished":
notifyTask(self, ev)
case "turn.ended":
notifyTurn(self, ev)
if ev.payload.value["summary"] as? Bool == true, let taskId = ev.taskId {