task_graph_mcp/resources/
workflows.rs1use crate::config::workflows::WorkflowsConfig;
7use anyhow::Result;
8use serde_json::{Value, json};
9
10pub fn list_workflows(workflows: &WorkflowsConfig) -> Result<Value> {
12 let mut workflow_list: Vec<Value> = Vec::new();
13
14 for (name, config) in &workflows.named_workflows {
15 let source = config.source_file.as_ref().map(|p| p.display().to_string());
16
17 workflow_list.push(json!({
18 "name": name,
19 "description": config.description,
20 "source_file": source,
21 "states": config.states.keys().collect::<Vec<_>>(),
22 "phases": config.phases.keys().collect::<Vec<_>>(),
23 }));
24 }
25
26 workflow_list.sort_by(|a, b| {
28 a.get("name")
29 .and_then(|v| v.as_str())
30 .unwrap_or("")
31 .cmp(b.get("name").and_then(|v| v.as_str()).unwrap_or(""))
32 });
33
34 let default_workflow = workflows.default_workflow_key.as_ref();
36
37 Ok(json!({
38 "workflows": workflow_list,
39 "default_workflow": default_workflow,
40 "count": workflows.named_workflows.len(),
41 }))
42}
43
44pub fn get_workflow(workflows: &WorkflowsConfig, name: &str) -> Result<Value> {
46 let config = workflows
47 .named_workflows
48 .get(name)
49 .ok_or_else(|| anyhow::anyhow!("Workflow '{}' not found", name))?;
50
51 let source = config.source_file.as_ref().map(|p| p.display().to_string());
52
53 let states: Vec<Value> = config
55 .states
56 .iter()
57 .map(|(state_name, state)| {
58 json!({
59 "name": state_name,
60 "exits": state.exits,
61 "timed": state.timed,
62 "has_enter_prompt": state.prompts.enter.is_some(),
63 "has_exit_prompt": state.prompts.exit.is_some(),
64 })
65 })
66 .collect();
67
68 let phases: Vec<Value> = config
70 .phases
71 .iter()
72 .map(|(phase_name, phase)| {
73 json!({
74 "name": phase_name,
75 "has_enter_prompt": phase.prompts.enter.is_some(),
76 "has_exit_prompt": phase.prompts.exit.is_some(),
77 })
78 })
79 .collect();
80
81 Ok(json!({
82 "name": name,
83 "description": config.description,
84 "source_file": source,
85 "settings": {
86 "initial_state": config.settings.initial_state,
87 "disconnect_state": config.settings.disconnect_state,
88 "blocking_states": config.settings.blocking_states,
89 },
90 "states": states,
91 "phases": phases,
92 "combo_count": config.combos.len(),
93 }))
94}