native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
5.7 kB · 166 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167import Foundationimport Observation
nonisolated struct MirrorLaunchWorktree: Decodable, Identifiable, Equatable { let id: String let name: String let path: String let rootPath: String enum CodingKeys: String, CodingKey { case id, name, path case rootPath = "root_path" } var label: String { "\(URL(fileURLWithPath: rootPath).lastPathComponent) · \(name)" }}
nonisolated struct MirrorLaunchProfile: Decodable, Identifiable, Equatable { let id: String let name: String let enabled: Bool let runtime: String let availability: Availability struct Availability: Decodable, Equatable { let status: String let reason: String? } var isAvailable: Bool { enabled && availability.status == "available" }}
@MainActor@Observablefinal class MirrorLaunchModel { enum Kind: Hashable { case shell, agent } let supportsShell: Bool let supportsProfiles: Bool var kind: Kind var worktreeID: String? var profileID: String? var prompt = "" private(set) var worktrees: [MirrorLaunchWorktree] = [] private(set) var profiles: [MirrorLaunchProfile] = [] private(set) var isLoading = false private(set) var isCreating = false private(set) var error: String? private(set) var creationUncertain = false private let execute: (MirrorCommandRequest.Command) async throws -> MirrorJSON
init( supportsShell: Bool = false, supportsProfiles: Bool = true, execute: @escaping (MirrorCommandRequest.Command) async throws -> MirrorJSON ) { self.supportsShell = supportsShell self.supportsProfiles = supportsProfiles kind = supportsShell ? .shell : .agent self.execute = execute }
var canCreate: Bool { !isLoading && !isCreating && !creationUncertain && worktrees.contains { $0.id == worktreeID } && (kind == .shell ? supportsShell : supportsProfiles && profiles.contains { $0.id == profileID && $0.isAvailable } && prompt.utf8.count <= MirrorWire.maximumInput) }
func load() async { guard !isLoading, !isCreating, !creationUncertain else { return } isLoading = true error = nil defer { isLoading = false } worktrees = [] profiles = [] do { let listing: Listing = try await response(.list(.init())) var seen: Set<String> = [] worktrees = (listing.worktrees ?? listing.items.map(\.worktree)).filter { seen.insert($0.id).inserted } if !worktrees.contains(where: { $0.id == worktreeID }) { worktreeID = worktrees.first?.id } if supportsProfiles { let catalog: Catalog = try await response(.profiles(.init())) profiles = catalog.profiles } if !profiles.contains(where: { $0.id == profileID && $0.isAvailable }) { profileID = profiles.first(where: \.isAvailable)?.id } } catch { self.error = error.localizedDescription } }
func create() async -> MirrorPaneDescriptor? { guard canCreate, let worktreeID else { return nil } isCreating = true error = nil defer { isCreating = false } do { let request: MirrorCommandRequest.Create if kind == .shell { request = .init(worktreeID: worktreeID) } else { guard let profileID else { return nil } request = .init( worktreeID: worktreeID, profileID: profileID, prompt: prompt.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? nil : prompt) } let created: Created = try await response(.create(request)) guard let id = UUID(uuidString: created.target.pane.id) else { throw LaunchError.invalidResponse } let worktree = created.target.worktree return MirrorPaneDescriptor( id: id, title: created.target.pane.title, directory: worktree.path, busy: false, projectName: URL(fileURLWithPath: worktree.rootPath).lastPathComponent, subtitle: "\(created.target.pane.title) · \(worktree.name)") } catch { // A transport failure may follow a successful creation. Never automatically create again. creationUncertain = !(error is Rejected) || (error as? Rejected)?.code == "REMOTE_COMMAND_UNCONFIRMED" self.error = creationUncertain ? "Creation is unconfirmed. Refresh the Host pane list before creating another pane." : error.localizedDescription return nil } }
private func response<T: Decodable>(_ command: MirrorCommandRequest.Command) async throws -> T { let result = try await execute(command).decode(Response<T>.self) guard result.ok else { throw result.error ?? Rejected(code: nil, message: "Host rejected the command.") } guard let payload = result.data else { throw LaunchError.invalidResponse } return payload }
private struct Response<T: Decodable>: Decodable { let ok: Bool let data: T? let error: Rejected? } private struct Rejected: Decodable, LocalizedError { let code: String? let message: String var errorDescription: String? { message } } private enum LaunchError: LocalizedError { case invalidResponse var errorDescription: String? { "Host returned an invalid launch result." } } private struct Listing: Decodable { struct Item: Decodable { let worktree: MirrorLaunchWorktree } let items: [Item] let worktrees: [MirrorLaunchWorktree]? } private struct Catalog: Decodable { let profiles: [MirrorLaunchProfile] } private struct Created: Decodable { struct Target: Decodable { struct Pane: Decodable { let id: String let title: String } let worktree: MirrorLaunchWorktree let pane: Pane } let target: Target }}