1use crate::prompts::PromptBuilder;
2use std::sync::Arc;
3
4use std::sync::atomic::AtomicBool;
5
6use anyhow::Result;
7use assistant_slash_command::{
8 ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
9};
10use gpui::{Task, WeakView};
11use language::LspAdapterDelegate;
12use ui::prelude::*;
13
14use workspace::Workspace;
15
16pub(crate) struct WorkflowSlashCommand {
17 prompt_builder: Arc<PromptBuilder>,
18}
19
20impl WorkflowSlashCommand {
21 pub fn new(prompt_builder: Arc<PromptBuilder>) -> Self {
22 Self { prompt_builder }
23 }
24}
25
26impl SlashCommand for WorkflowSlashCommand {
27 fn name(&self) -> String {
28 "workflow".into()
29 }
30
31 fn description(&self) -> String {
32 "insert a prompt that opts into the edit workflow".into()
33 }
34
35 fn menu_text(&self) -> String {
36 "Insert Workflow Prompt".into()
37 }
38
39 fn requires_argument(&self) -> bool {
40 false
41 }
42
43 fn complete_argument(
44 self: Arc<Self>,
45 _arguments: &[String],
46 _cancel: Arc<AtomicBool>,
47 _workspace: Option<WeakView<Workspace>>,
48 _cx: &mut WindowContext,
49 ) -> Task<Result<Vec<ArgumentCompletion>>> {
50 Task::ready(Ok(Vec::new()))
51 }
52
53 fn run(
54 self: Arc<Self>,
55 _arguments: &[String],
56 _workspace: WeakView<Workspace>,
57 _delegate: Option<Arc<dyn LspAdapterDelegate>>,
58 cx: &mut WindowContext,
59 ) -> Task<Result<SlashCommandOutput>> {
60 let prompt_builder = self.prompt_builder.clone();
61 cx.spawn(|_cx| async move {
62 let text = prompt_builder.generate_workflow_prompt()?;
63 let range = 0..text.len();
64
65 Ok(SlashCommandOutput {
66 text,
67 sections: vec![SlashCommandOutputSection {
68 range,
69 icon: IconName::Route,
70 label: "Workflow".into(),
71 }],
72 run_commands_in_text: false,
73 })
74 })
75 }
76}