1use agent_client_protocol::schema::v2::SessionId;
2use std::path::PathBuf;
3
4#[derive(Default)]
5pub enum ForegroundOperation {
6 #[default]
7 Idle,
8 PreparingPrompt(String),
9 Prompt(PromptPhase),
10 CreatingSession { previous_selections: Vec<(String, String)> },
11 ResumingSession { session_id: SessionId, cwd: PathBuf },
12 ListingWorkspaces,
13 PickingWorkspace,
14 MovingWorkspace,
15 LoadingWorkspaceSession { session_id: SessionId, cwd: PathBuf },
16}
17
18pub enum PromptPhase {
19 Submitting,
20 Running,
21 CompletedBeforeAcceptance,
22}
23
24impl ForegroundOperation {
25 pub(super) fn is_idle(&self) -> bool {
26 matches!(self, Self::Idle)
27 }
28
29 pub(super) fn prompt_in_flight(&self) -> bool {
30 matches!(self, Self::Prompt(PromptPhase::Submitting | PromptPhase::Running))
31 }
32
33 pub(super) fn accept_prompt(&mut self) {
34 match self {
35 Self::Prompt(PromptPhase::Submitting) => *self = Self::Prompt(PromptPhase::Running),
36 Self::Prompt(PromptPhase::CompletedBeforeAcceptance) => *self = Self::Idle,
37 _ => {}
38 }
39 }
40
41 pub(super) fn finish_prompt(&mut self) {
42 match self {
43 Self::Prompt(PromptPhase::Submitting) => *self = Self::Prompt(PromptPhase::CompletedBeforeAcceptance),
44 Self::Prompt(PromptPhase::Running) => *self = Self::Idle,
45 _ => {}
46 }
47 }
48
49 pub(super) fn reject_prompt(&mut self) {
50 if matches!(self, Self::PreparingPrompt(_) | Self::Prompt(_)) {
51 *self = Self::Idle;
52 }
53 }
54
55 pub(super) fn clear_conversation(&mut self) {
56 if matches!(self, Self::PreparingPrompt(_)) {
57 *self = Self::Idle;
58 }
59 self.finish_prompt();
60 }
61
62 pub(super) fn take_prepared_prompt(&mut self) -> Option<String> {
63 if !matches!(self, Self::PreparingPrompt(_)) {
64 return None;
65 }
66 let Self::PreparingPrompt(text) = std::mem::take(self) else { unreachable!() };
67 Some(text)
68 }
69}