embacle_server/runner/
mod.rs1pub mod factory;
8pub mod multiplex;
9
10use embacle::config::CliRunnerType;
11
12pub const ALL_PROVIDERS: &[CliRunnerType] = &[
14 CliRunnerType::ClaudeCode,
15 CliRunnerType::Copilot,
16 CliRunnerType::CursorAgent,
17 CliRunnerType::OpenCode,
18 CliRunnerType::GeminiCli,
19 CliRunnerType::CodexCli,
20 CliRunnerType::GooseCli,
21 CliRunnerType::ClineCli,
22 CliRunnerType::ContinueCli,
23];
24
25pub fn parse_runner_type(s: &str) -> Option<CliRunnerType> {
30 match s.to_lowercase().as_str() {
31 "claude_code" | "claude" | "claudecode" => Some(CliRunnerType::ClaudeCode),
32 "copilot" => Some(CliRunnerType::Copilot),
33 "cursor_agent" | "cursoragent" | "cursor-agent" => Some(CliRunnerType::CursorAgent),
34 "opencode" | "open_code" => Some(CliRunnerType::OpenCode),
35 "gemini" | "gemini_cli" | "geminicli" | "gemini-cli" => Some(CliRunnerType::GeminiCli),
36 "codex" | "codex_cli" | "codexcli" | "codex-cli" => Some(CliRunnerType::CodexCli),
37 "goose" | "goose_cli" | "goosecli" | "goose-cli" => Some(CliRunnerType::GooseCli),
38 "cline" | "cline_cli" | "clinecli" | "cline-cli" => Some(CliRunnerType::ClineCli),
39 "continue" | "continue_cli" | "continuecli" | "continue-cli" | "cn" => {
40 Some(CliRunnerType::ContinueCli)
41 }
42 _ => None,
43 }
44}
45
46pub const fn valid_provider_names() -> &'static str {
48 "claude_code, copilot, cursor_agent, opencode, gemini_cli, codex_cli, goose_cli, cline_cli, continue_cli"
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn parse_snake_case_variants() {
57 assert_eq!(
58 parse_runner_type("claude_code"),
59 Some(CliRunnerType::ClaudeCode)
60 );
61 assert_eq!(parse_runner_type("copilot"), Some(CliRunnerType::Copilot));
62 assert_eq!(
63 parse_runner_type("cursor_agent"),
64 Some(CliRunnerType::CursorAgent)
65 );
66 assert_eq!(parse_runner_type("opencode"), Some(CliRunnerType::OpenCode));
67 assert_eq!(
68 parse_runner_type("gemini_cli"),
69 Some(CliRunnerType::GeminiCli)
70 );
71 assert_eq!(
72 parse_runner_type("codex_cli"),
73 Some(CliRunnerType::CodexCli)
74 );
75 assert_eq!(
76 parse_runner_type("goose_cli"),
77 Some(CliRunnerType::GooseCli)
78 );
79 assert_eq!(
80 parse_runner_type("cline_cli"),
81 Some(CliRunnerType::ClineCli)
82 );
83 assert_eq!(
84 parse_runner_type("continue_cli"),
85 Some(CliRunnerType::ContinueCli)
86 );
87 }
88
89 #[test]
90 fn parse_short_forms() {
91 assert_eq!(parse_runner_type("claude"), Some(CliRunnerType::ClaudeCode));
92 assert_eq!(
93 parse_runner_type("cursor-agent"),
94 Some(CliRunnerType::CursorAgent)
95 );
96 assert_eq!(parse_runner_type("gemini"), Some(CliRunnerType::GeminiCli));
97 assert_eq!(parse_runner_type("codex"), Some(CliRunnerType::CodexCli));
98 assert_eq!(parse_runner_type("goose"), Some(CliRunnerType::GooseCli));
99 assert_eq!(parse_runner_type("cline"), Some(CliRunnerType::ClineCli));
100 assert_eq!(
101 parse_runner_type("continue"),
102 Some(CliRunnerType::ContinueCli)
103 );
104 assert_eq!(parse_runner_type("cn"), Some(CliRunnerType::ContinueCli));
105 }
106
107 #[test]
108 fn parse_case_insensitive() {
109 assert_eq!(parse_runner_type("COPILOT"), Some(CliRunnerType::Copilot));
110 assert_eq!(
111 parse_runner_type("Claude_Code"),
112 Some(CliRunnerType::ClaudeCode)
113 );
114 }
115
116 #[test]
117 fn parse_unknown_returns_none() {
118 assert_eq!(parse_runner_type("gpt4"), None);
119 assert_eq!(parse_runner_type(""), None);
120 }
121
122 #[test]
123 fn all_providers_has_nine_entries() {
124 assert_eq!(ALL_PROVIDERS.len(), 9);
125 }
126}