native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
7.3 kB · 204 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205import Foundationimport ProwlCLISharedimport Testing
@testable import supacode
@MainActorstruct AgentReadCommandHandlerTests { @Test func blockedSnapshotWithoutSessionPreservesBlockerAndReportsPending() async throws { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: .blocked, blockerText: "Do you want to proceed?\n❯ 1. Yes\n 2. No")) }, resultProvider: { _, _, _ in Issue.record("Unexpected transcript read") return .failure(.incomplete) } )
let response = await handler.handle( envelope: CommandEnvelope(output: .json, command: .agentsRead(AgentReadInput(pane: "p7"))) )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: AgentReadCommandPayload.self)) #expect(payload.agent.status == .blocked) #expect(payload.agent.detectionReason == "claude.blockedPrompt") #expect(payload.agent.screenReason == "claude.blockedPrompt") #expect(payload.blocker?.text.contains("1. Yes") == true) #expect(payload.result.state == .pending) #expect(payload.result.error == nil) }
@Test func idleSnapshotWithoutSessionReportsUnavailable() async throws { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: .idle)) }, resultProvider: { _, _, _ in Issue.record("Unexpected transcript read") return .failure(.incomplete) } )
let response = await handler.handle( envelope: CommandEnvelope(output: .json, command: .agentsRead(AgentReadInput(pane: "p7"))) )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: AgentReadCommandPayload.self)) #expect(payload.result.state == .unavailable) #expect(payload.result.error?.code == CLIErrorCode.sessionUnresolved) }
@Test func resultOnlyFailsWithResultNotFoundForLiveAgentWithoutSession() async { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: .working)) }, resultProvider: { _, _, _ in Issue.record("Unexpected transcript read") return .failure(.incomplete) } )
let response = await handler.handle( envelope: CommandEnvelope( output: .text, command: .agentsRead(AgentReadInput(pane: "p7", resultOnly: true)) ) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.resultNotFound) }
@Test func workingSnapshotMapsMissingTrustedHistoryToPending() async throws { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: .working, session: self.makeSession())) }, resultProvider: { _, _, _ in .failure(.missing) } )
let response = await handler.handle( envelope: CommandEnvelope(output: .json, command: .agentsRead(AgentReadInput(pane: "p7"))) )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: AgentReadCommandPayload.self)) #expect(payload.result.state == .pending) #expect(payload.result.text == nil) #expect(payload.result.error == nil) }
@Test func resultOnlyTurnsUnavailableSnapshotResultIntoCommandFailure() async { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: .idle)) }, resultProvider: { _, _, _ in Issue.record("Unexpected transcript read") return .failure(.incomplete) } )
let response = await handler.handle( envelope: CommandEnvelope( output: .text, command: .agentsRead(AgentReadInput(pane: "p7", resultOnly: true)) ) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.sessionUnresolved) }
@Test func resultOnlySucceedsForCompleteTrustedResult() async throws { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: .done, session: self.makeSession())) }, resultProvider: { _, _, _ in .complete("Final result") } )
let response = await handler.handle( envelope: CommandEnvelope( output: .text, command: .agentsRead(AgentReadInput(pane: "p7", resultOnly: true)) ) )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: AgentReadCommandPayload.self)) #expect(payload.outputMode == .resultOnly) #expect(payload.result.state == .complete) #expect(payload.result.text == "Final result") }
@Test func liveWorkingOrBlockedAgentReportsPendingEvenWithAnEarlierCompleteTurn() async throws { for status in [AgentsCommandStatus.working, .blocked] { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: status, session: self.makeSession())) }, resultProvider: { _, _, _ in Issue.record("A live working/blocked agent must not read the transcript") return .complete("Answer from the previous turn") } )
let response = await handler.handle( envelope: CommandEnvelope(output: .json, command: .agentsRead(AgentReadInput(pane: "p7"))) )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: AgentReadCommandPayload.self)) #expect(payload.agent.status == status) #expect(payload.result.state == .pending) #expect(payload.result.text == nil) #expect(payload.result.error == nil) } }
@Test func resultOnlyFailsWhileTheAgentIsStillWorking() async { let handler = AgentReadCommandHandler( snapshotProvider: { _ in .success(self.makeSnapshot(status: .working, session: self.makeSession())) }, resultProvider: { _, _, _ in .complete("Answer from the previous turn") } )
let response = await handler.handle( envelope: CommandEnvelope( output: .text, command: .agentsRead(AgentReadInput(pane: "p7", resultOnly: true)) ) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.resultNotFound) }
private func makeSnapshot( status: AgentsCommandStatus, blockerText: String? = nil, session: AgentSession? = nil ) -> AgentReadRuntimeSnapshot { AgentReadRuntimeSnapshot( target: ReadTarget( worktree: ReadTargetWorktree( id: "/tmp/project", name: "main", path: "/tmp/project", rootPath: "/tmp/project", kind: "git" ), tab: ReadTargetTab(id: "2FC00CF0-3974-4E1B-BEF8-7A08A8E3B7C0", title: "Agent", selected: true), pane: ReadTargetPane( id: "6E1A2A10-D99F-4E3F-920C-D93AA3C05764", title: "Claude", cwd: "/tmp/project", focused: false ) ), agent: .claude, status: status, rawState: status == .done ? "idle" : status.rawValue, detectionReason: "claude.blockedPrompt", screenReason: "claude.blockedPrompt", lastChangedAt: "2026-08-11T12:00:00Z", blockerText: blockerText, transcriptSession: session ) }
private func makeSession() -> AgentSession { AgentSession( id: "019f4f1b-3650-7661-a56d-351f02f01139", transcriptPath: URL(fileURLWithPath: "/tmp/session.jsonl"), source: .openFile, confidence: .exact ) }}