native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
4.6 kB · 163 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164import Foundationimport ProwlCLIShared
struct ListRuntimeSnapshot: Sendable { struct Worktree: Sendable { let id: String let name: String let path: String let rootPath: String let kind: ListCommandWorktree.Kind let taskStatus: ListCommandTask.Status? let tabs: [Tab] }
struct Tab: Sendable { let id: UUID let handle: Int? let title: String let selected: Bool let focusedPaneID: UUID? let panes: [Pane]
init( id: UUID, handle: Int? = nil, title: String, selected: Bool, focusedPaneID: UUID?, panes: [Pane] ) { self.id = id self.handle = handle self.title = title self.selected = selected self.focusedPaneID = focusedPaneID self.panes = panes } }
struct Pane: Sendable { let id: UUID let handle: Int? let title: String let cwd: String? let visible: Bool let agent: String?
init(id: UUID, handle: Int? = nil, title: String, cwd: String?, visible: Bool = false, agent: String? = nil) { self.id = id self.handle = handle self.title = title self.cwd = cwd self.visible = visible self.agent = agent } }
let worktrees: [Worktree] let focusedWorktreeID: String?}
final class ListCommandHandler: CommandHandler { typealias SnapshotProvider = @MainActor () throws -> ListRuntimeSnapshot typealias ResolveCaller = @MainActor (CLICommandContext) -> CallerPane?
private let snapshotProvider: SnapshotProvider private let resolveCaller: ResolveCaller
init( resolveCaller: @escaping ResolveCaller = { _ in nil }, snapshotProvider: @escaping SnapshotProvider ) { self.resolveCaller = resolveCaller self.snapshotProvider = snapshotProvider }
func handle(envelope: CommandEnvelope) async -> CommandResponse { await handle(envelope: envelope, context: CLICommandContext()) }
// swiftlint:disable:next async_without_await func handle(envelope: CommandEnvelope, context: CLICommandContext) async -> CommandResponse { do { let snapshot = try snapshotProvider() let caller = resolveCaller(context).map { ListCommandCaller(paneID: $0.surfaceID.uuidString, worktreeID: $0.worktreeID) } let payload = makePayload(from: snapshot, includeHandles: envelope.output == .text, caller: caller) return try CommandResponse( ok: true, command: "list", schemaVersion: "prowl.cli.list.v1", data: RawJSON(encoding: payload) ) } catch { return CommandResponse( ok: false, command: "list", schemaVersion: "prowl.cli.list.v1", error: CommandError( code: CLIErrorCode.listFailed, message: "Failed to list panes." ) ) } }
private func makePayload( from snapshot: ListRuntimeSnapshot, includeHandles: Bool, caller: ListCommandCaller? ) -> ListCommandPayload { var items: [ListCommandItem] = [] var didAssignFocusedPane = false
for worktree in snapshot.worktrees { for tab in worktree.tabs { for pane in tab.panes { let isFocused = !didAssignFocusedPane && worktree.id == snapshot.focusedWorktreeID && tab.selected && tab.focusedPaneID == pane.id
if isFocused { didAssignFocusedPane = true }
items.append( ListCommandItem( worktree: ListCommandWorktree( id: worktree.id, name: worktree.name, path: worktree.path, rootPath: worktree.rootPath, kind: worktree.kind ), tab: ListCommandTab( id: tab.id.uuidString, handle: includeHandles ? tab.handle : nil, title: tab.title, selected: tab.selected ), pane: ListCommandPane( id: pane.id.uuidString, handle: includeHandles ? pane.handle : nil, title: pane.title, cwd: pane.cwd, focused: isFocused, visible: pane.visible, agent: pane.agent ), task: ListCommandTask(status: worktree.taskStatus) ) ) } } }
let listedCaller = caller.flatMap { caller in items.contains { $0.pane.id == caller.pane.id } ? caller : nil } return ListCommandPayload(count: items.count, items: items, caller: listedCaller) }}