diff --git a/backend/migrations/20250716161432_update_executor_names_to_kebab_case.sql b/backend/migrations/20250716161432_update_executor_names_to_kebab_case.sql
new file mode 100644
index 00000000..4e5ad891
--- /dev/null
+++ b/backend/migrations/20250716161432_update_executor_names_to_kebab_case.sql
@@ -0,0 +1,20 @@
+-- Migration to update executor type names from snake_case/camelCase to kebab-case
+-- This handles the change from charmopencode -> charm-opencode and setup_script -> setup-script
+
+-- Update task_attempts.executor column
+UPDATE task_attempts
+SET executor = 'charm-opencode'
+WHERE executor = 'charmopencode';
+
+UPDATE task_attempts
+SET executor = 'setup-script'
+WHERE executor = 'setup_script';
+
+-- Update execution_processes.executor_type column
+UPDATE execution_processes
+SET executor_type = 'charm-opencode'
+WHERE executor_type = 'charmopencode';
+
+UPDATE execution_processes
+SET executor_type = 'setup-script'
+WHERE executor_type = 'setup_script';
\ No newline at end of file
diff --git a/backend/src/bin/generate_types.rs b/backend/src/bin/generate_types.rs
index 53e1ac1f..6e64fbf3 100644
--- a/backend/src/bin/generate_types.rs
+++ b/backend/src/bin/generate_types.rs
@@ -10,7 +10,7 @@ export const EXECUTOR_TYPES: string[] = [
"claude",
"amp",
"gemini",
- "charmopencode",
+ "charm-opencode",
"claude-code-router"
];
@@ -28,7 +28,7 @@ export const EXECUTOR_LABELS: Record = {
"claude": "Claude",
"amp": "Amp",
"gemini": "Gemini",
- "charmopencode": "Charm Opencode",
+ "charm-opencode": "Charm Opencode",
"claude-code-router": "Claude Code Router"
};
diff --git a/backend/src/executor.rs b/backend/src/executor.rs
index 4cff6d39..414616a7 100644
--- a/backend/src/executor.rs
+++ b/backend/src/executor.rs
@@ -342,19 +342,19 @@ pub enum ExecutorType {
/// Configuration for different executor types
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
-#[serde(tag = "type", rename_all = "lowercase")]
+#[serde(tag = "type", rename_all = "kebab-case")]
#[ts(export)]
pub enum ExecutorConfig {
Echo,
Claude,
Amp,
Gemini,
+ #[serde(alias = "setup_script")]
SetupScript {
script: String,
},
- #[serde(rename = "claude-code-router")]
- #[ts(rename = "claude-code-router")]
ClaudeCodeRouter,
+ #[serde(alias = "charmopencode")]
CharmOpencode,
// Future executors can be added here
// Shell { command: String },
@@ -378,9 +378,9 @@ impl FromStr for ExecutorConfig {
"claude" => Ok(ExecutorConfig::Claude),
"amp" => Ok(ExecutorConfig::Amp),
"gemini" => Ok(ExecutorConfig::Gemini),
- "charmopencode" => Ok(ExecutorConfig::CharmOpencode),
+ "charm-opencode" => Ok(ExecutorConfig::CharmOpencode),
"claude-code-router" => Ok(ExecutorConfig::ClaudeCodeRouter),
- "setup_script" => Ok(ExecutorConfig::SetupScript {
+ "setup-script" => Ok(ExecutorConfig::SetupScript {
script: "setup script".to_string(),
}),
_ => Err(format!("Unknown executor type: {}", s)),
@@ -464,9 +464,9 @@ impl std::fmt::Display for ExecutorConfig {
ExecutorConfig::Claude => "claude",
ExecutorConfig::Amp => "amp",
ExecutorConfig::Gemini => "gemini",
- ExecutorConfig::CharmOpencode => "charmopencode",
+ ExecutorConfig::CharmOpencode => "charm-opencode",
ExecutorConfig::ClaudeCodeRouter => "claude-code-router",
- ExecutorConfig::SetupScript { .. } => "setup_script",
+ ExecutorConfig::SetupScript { .. } => "setup-script",
};
write!(f, "{}", s)
}
diff --git a/backend/src/executors/setup_script.rs b/backend/src/executors/setup_script.rs
index e1b5b238..3721df89 100644
--- a/backend/src/executors/setup_script.rs
+++ b/backend/src/executors/setup_script.rs
@@ -122,7 +122,7 @@ impl Executor for SetupScriptExecutor {
Ok(crate::executor::NormalizedConversation {
entries,
session_id: None,
- executor_type: "setup_script".to_string(),
+ executor_type: "setup-script".to_string(),
prompt: Some(self.script.clone()),
summary: None,
})
diff --git a/backend/src/routes/task_attempts.rs b/backend/src/routes/task_attempts.rs
index e8f29a53..f71b1f34 100644
--- a/backend/src/routes/task_attempts.rs
+++ b/backend/src/routes/task_attempts.rs
@@ -1331,7 +1331,7 @@ pub async fn get_execution_process_normalized_logs(
// Create final normalized conversation
let executor_type = if process.process_type == ExecutionProcessType::SetupScript {
- "setup_script".to_string()
+ "setup-script".to_string()
} else {
process
.executor_type
diff --git a/backend/src/services/process_service.rs b/backend/src/services/process_service.rs
index 823dfdee..53163a05 100644
--- a/backend/src/services/process_service.rs
+++ b/backend/src/services/process_service.rs
@@ -639,7 +639,7 @@ impl ProcessService {
Some("claude-code-router") => crate::executor::ExecutorConfig::ClaudeCodeRouter,
Some("amp") => crate::executor::ExecutorConfig::Amp,
Some("gemini") => crate::executor::ExecutorConfig::Gemini,
- Some("charmopencode") => crate::executor::ExecutorConfig::CharmOpencode,
+ Some("charm-opencode") => crate::executor::ExecutorConfig::CharmOpencode,
_ => crate::executor::ExecutorConfig::Echo, // Default for "echo" or None
}
}
@@ -657,8 +657,8 @@ impl ProcessService {
let (command, args, executor_type_string) = match executor_type {
crate::executor::ExecutorType::SetupScript(_) => (
shell_cmd.to_string(),
- Some(serde_json::to_string(&[shell_arg, "setup_script"]).unwrap()),
- None, // Setup scripts don't have an executor type
+ Some(serde_json::to_string(&[shell_arg, "setup-script"]).unwrap()),
+ Some("setup-script".to_string()),
),
crate::executor::ExecutorType::DevServer(_) => (
shell_cmd.to_string(),
@@ -885,7 +885,7 @@ impl ProcessService {
// Store delegation context in args for execution monitor to read
let args_with_delegation = serde_json::json!([
shell_arg,
- "setup_script",
+ "setup-script",
"--delegation-context",
delegation_context.to_string()
]);
@@ -893,7 +893,7 @@ impl ProcessService {
let create_process = CreateExecutionProcess {
task_attempt_id: attempt_id,
process_type: ExecutionProcessType::SetupScript,
- executor_type: None, // Setup scripts don't have an executor type
+ executor_type: Some("setup-script".to_string()),
command: shell_cmd.to_string(),
args: Some(args_with_delegation.to_string()),
working_directory: worktree_path.to_string(),
diff --git a/frontend/src/components/OnboardingDialog.tsx b/frontend/src/components/OnboardingDialog.tsx
index 52ee06ad..2089030a 100644
--- a/frontend/src/components/OnboardingDialog.tsx
+++ b/frontend/src/components/OnboardingDialog.tsx
@@ -98,8 +98,10 @@ export function OnboardingDialog({ open, onComplete }: OnboardingDialogProps) {
{executor.type === 'claude' && 'Claude Code from Anthropic'}
{executor.type === 'amp' && 'From Sourcegraph'}
{executor.type === 'gemini' && 'Google Gemini from Bloop'}
- {executor.type === 'charmopencode' &&
+ {executor.type === 'charm-opencode' &&
'Charm/Opencode AI assistant'}
+ {executor.type === 'claude-code-router' &&
+ 'Claude Code Router'}
{executor.type === 'echo' &&
'This is just for debugging vibe-kanban itself'}
diff --git a/shared/types.ts b/shared/types.ts
index 393f49c9..fff63d88 100644
--- a/shared/types.ts
+++ b/shared/types.ts
@@ -22,7 +22,7 @@ export type SoundConstants = { sound_files: Array, sound_labels: Arra
export type ConfigConstants = { editor: EditorConstants, sound: SoundConstants, };
-export type ExecutorConfig = { "type": "echo" } | { "type": "claude" } | { "type": "amp" } | { "type": "gemini" } | { "type": "setupscript", script: string, } | { "type": "claude-code-router" } | { "type": "charmopencode" };
+export type ExecutorConfig = { "type": "echo" } | { "type": "claude" } | { "type": "amp" } | { "type": "gemini" } | { "type": "setup-script", script: string, } | { "type": "claude-code-router" } | { "type": "charm-opencode" };
export type ExecutorConstants = { executor_types: Array, executor_labels: Array, };
@@ -128,7 +128,7 @@ export const EXECUTOR_TYPES: string[] = [
"claude",
"amp",
"gemini",
- "charmopencode",
+ "charm-opencode",
"claude-code-router"
];
@@ -146,7 +146,7 @@ export const EXECUTOR_LABELS: Record = {
"claude": "Claude",
"amp": "Amp",
"gemini": "Gemini",
- "charmopencode": "Charm Opencode",
+ "charm-opencode": "Charm Opencode",
"claude-code-router": "Claude Code Router"
};