| 1 | import { CommandCancelled } from "../lib/commandOutcome"; |
| 2 | import type { QuestionAnswer, ToolApprovalMode } from "../lib/types"; |
| 3 | import type { MCPInteractionAction, PlanDecisionAction, RecoveryAction, SessionActionPorts, SessionPromptTarget } from "./sessionActionOwner"; |
| 4 | import type { SessionOperationAuthority } from "./useSessionOperations"; |
| 5 | |
| 6 | export type SessionPromptKind = "approval" | "ask" | "mcpInteraction"; |
| 7 | export type PromptRequest = |
| 8 | | { kind: "approval"; allow: boolean; session: boolean; persist: boolean } |
| 9 | | { kind: "plan"; action: PlanDecisionAction; leavePlanMode: boolean; remote: boolean; goal: string; toolApprovalMode: ToolApprovalMode; revision?: string } |
| 10 | | { kind: "recovery"; action: RecoveryAction; feedback: string } |
| 11 | | { kind: "question"; answers: QuestionAnswer[] } |
| 12 | | { kind: "mcp"; action: MCPInteractionAction; content?: Record<string, unknown> }; |
| 13 | export type PromptPorts = SessionActionPorts & { |
| 14 | isPromptCurrentForTab: (target: SessionPromptTarget) => boolean; |
| 15 | rememberRevision: (tabId: string, revision: string) => void; |
| 16 | }; |
| 17 | export type PromptInput = { target: SessionPromptTarget; promptKind: SessionPromptKind; request: PromptRequest; ports: PromptPorts }; |
| 18 | |
| 19 | /** Lazy loading and every business continuation share the same source receipt. */ |
| 20 | export async function executeSessionPrompt(input: PromptInput, source: SessionOperationAuthority) { |
| 21 | const { target, request, ports } = input; |
| 22 | const authority: SessionOperationAuthority = { |
| 23 | checkpoint() { |
| 24 | source.checkpoint(); |
| 25 | if (!ports.isPromptCurrentForTab(target)) throw new CommandCancelled("superseded"); |
| 26 | }, |
| 27 | ownsUI: () => source.ownsUI(), |
| 28 | }; |
| 29 | authority.checkpoint(); |
| 30 | const owner = await import("./sessionActionOwner"); |
| 31 | authority.checkpoint(); |
| 32 | switch (request.kind) { |
| 33 | case "approval": return owner.submitApproval(target, request, ports); |
| 34 | case "plan": |
| 35 | if (request.revision !== undefined) ports.rememberRevision(target.tabId, request.revision); |
| 36 | return owner.submitPlanDecision(target, request, ports, authority); |
| 37 | case "recovery": return owner.submitRecovery(target, request.action, request.feedback, ports); |
| 38 | case "question": return owner.submitQuestion(target, request.answers, ports); |
| 39 | case "mcp": return owner.submitMCPInteraction(target, request.action, request.content, ports); |
| 40 | } |
| 41 | } |
| 42 |