ready to merge and ready to discard as states

This commit is contained in:
Ian Gulliver
2026-10-19 17:53:54 -07:00
parent fb79919ebb
commit 2bb527aca0
11 changed files with 394 additions and 293 deletions
+44 -2
View File
@@ -22,12 +22,16 @@ private let routeHash = Re(#"^#/(task|project)/(\w+)(?:/(\w+))?$"#)
struct TaskState {
enum Kind {
case answer, merging, held, working, idle
case answer, merging, held, working, ready, idle
}
let kind: Kind
let label: String
let title: String
var needsYou: Bool {
kind == .answer || kind == .ready
}
}
private let workingTitles: [ByreTask.StatePayload: (label: String, title: String)] = [
@@ -222,9 +226,42 @@ final class Store {
if let working = workingTitles[task.state] {
return TaskState(kind: .working, label: working.label, title: working.title)
}
switch task.ready {
case .merge:
return TaskState(kind: .ready, label: "Ready to merge", title: "The agent says the task is ready to merge")
case .discard:
return TaskState(kind: .ready, label: "Ready to discard", title: "The agent suggests discarding the task")
case nil:
break
}
return TaskState(kind: .idle, label: "Idle", title: "Waiting for a message")
}
func taskRank(_ task: ByreTask) -> Int {
if task.discarding {
return 4
}
switch taskState(task).kind {
case .answer: return 0
case .ready: return 1
case .idle: return 2
case .working: return 3
case .merging, .held: return 4
}
}
func byRank(_ tasks: [ByreTask]) -> [ByreTask] {
tasks.enumerated()
.sorted { a, b in
let ra = taskRank(a.element), rb = taskRank(b.element)
if ra != rb {
return ra < rb
}
return a.offset < b.offset
}
.map(\.element)
}
func currentLead() -> AgentSession? {
leadSessions.last(where: { $0.state != .completed }) ?? leadSessions.last
}
@@ -613,7 +650,7 @@ final class Store {
spawn("load projects") {
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":
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 projectId = ev.projectId {
spawn("load tasks") {
try await self.loadTasks(projectId)
@@ -634,6 +671,11 @@ final class Store {
spawn("load inbox") {
try await self.loadInbox()
}
if let projectId = ev.projectId {
spawn("load tasks") {
try await self.loadTasks(projectId)
}
}
case "inbox.updated":
clearInbox(try! decodePayload(ev.payload, as: InboxItem.self))
spawn("load inbox") {