diff options
| author | soryu <soryu@soryu.co> | 2026-02-09 15:55:01 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-09 15:55:01 +0000 |
| commit | 339c1769379a851c4126021132573bd4b7994cf2 (patch) | |
| tree | 8a9a3cdc9d86b3dc2e6883853fb7b22c21dd9e99 | |
| parent | bfa7bd8d7609397f570f1cd9b83d2269abc0ed63 (diff) | |
| download | soryu-339c1769379a851c4126021132573bd4b7994cf2.tar.gz soryu-339c1769379a851c4126021132573bd4b7994cf2.zip | |
Set directive env vars correctly for daemon
| -rw-r--r-- | makima/src/daemon/task/manager.rs | 43 | ||||
| -rw-r--r-- | makima/src/daemon/ws/protocol.rs | 3 | ||||
| -rw-r--r-- | makima/src/db/repository.rs | 9 | ||||
| -rw-r--r-- | makima/src/orchestration/directive.rs | 1 | ||||
| -rw-r--r-- | makima/src/server/handlers/contract_chat.rs | 1 | ||||
| -rw-r--r-- | makima/src/server/handlers/mesh.rs | 6 | ||||
| -rw-r--r-- | makima/src/server/handlers/mesh_chat.rs | 1 | ||||
| -rw-r--r-- | makima/src/server/handlers/mesh_supervisor.rs | 3 | ||||
| -rw-r--r-- | makima/src/server/state.rs | 3 |
9 files changed, 68 insertions, 2 deletions
diff --git a/makima/src/daemon/task/manager.rs b/makima/src/daemon/task/manager.rs index ae84294..68c5c42 100644 --- a/makima/src/daemon/task/manager.rs +++ b/makima/src/daemon/task/manager.rs @@ -1538,6 +1538,7 @@ impl TaskManager { local_only, auto_merge_local, supervisor_worktree_task_id, + directive_id, } => { tracing::info!( task_id = %task_id, @@ -1556,6 +1557,7 @@ impl TaskManager { continue_from_task_id = ?continue_from_task_id, copy_files = ?copy_files, contract_id = ?contract_id, + directive_id = ?directive_id, supervisor_worktree_task_id = ?supervisor_worktree_task_id, plan_len = plan.len(), "Spawning new task" @@ -1566,7 +1568,7 @@ impl TaskManager { target_repo_path, completion_action, continue_from_task_id, copy_files, contract_id, autonomous_loop, resume_session, conversation_history, patch_data, patch_base_sha, local_only, auto_merge_local, - supervisor_worktree_task_id, + supervisor_worktree_task_id, directive_id, ).await?; } DaemonCommand::PauseTask { task_id } => { @@ -1671,6 +1673,7 @@ impl TaskManager { local_only, auto_merge_local, None, // supervisor_worktree_task_id - supervisors use their own worktree + None, // directive_id ).await { tracing::error!( task_id = %task_id, @@ -1928,6 +1931,7 @@ impl TaskManager { local_only: bool, auto_merge_local: bool, supervisor_worktree_task_id: Option<Uuid>, + directive_id: Option<Uuid>, ) -> TaskResult<()> { tracing::info!(task_id = %task_id, is_orchestrator = is_orchestrator, is_supervisor = is_supervisor, depth = depth, patch_available = patch_data.is_some(), "=== SPAWN_TASK START ==="); @@ -2009,7 +2013,7 @@ impl TaskManager { is_orchestrator, is_supervisor, target_repo_path, completion_action, continue_from_task_id, copy_files, contract_id, autonomous_loop, resume_session, conversation_history, patch_data, patch_base_sha, local_only, auto_merge_local, - supervisor_worktree_task_id, + supervisor_worktree_task_id, directive_id, ).await { tracing::error!(task_id = %task_id, error = %e, "Task execution failed"); inner.mark_failed(task_id, &e.to_string()).await; @@ -4115,6 +4119,7 @@ impl TaskManagerInner { local_only: bool, auto_merge_local: bool, supervisor_worktree_task_id: Option<Uuid>, + directive_id: Option<Uuid>, ) -> Result<(), DaemonError> { tracing::info!(task_id = %task_id, is_orchestrator = is_orchestrator, is_supervisor = is_supervisor, resume_session = resume_session, has_patch = patch_data.is_some(), "=== RUN_TASK START ==="); @@ -4825,6 +4830,40 @@ impl TaskManagerInner { (extra_env, full_plan, system_prompt) }; + // Add directive environment if task has directive_id + let (extra_env, full_plan, system_prompt) = if let Some(did) = directive_id { + tracing::info!(task_id = %task_id, directive_id = %did, "Setting up directive integration"); + + let mut env = extra_env.unwrap_or_default(); + env.insert("MAKIMA_DIRECTIVE_ID".to_string(), did.to_string()); + + // If not already an orchestrator/supervisor, we need API access for makima CLI + if !is_orchestrator && !is_supervisor && !env.contains_key("MAKIMA_API_KEY") { + let tool_key = generate_tool_key(); + tracing::info!(task_id = %task_id, "Generated tool key for directive access"); + + let register_msg = DaemonMessage::register_tool_key(task_id, tool_key.clone()); + if self.ws_tx.send(register_msg).await.is_err() { + tracing::warn!(task_id = %task_id, "Failed to register directive tool key"); + } + + env.insert("MAKIMA_API_URL".to_string(), self.api_url.clone()); + env.insert("MAKIMA_API_KEY".to_string(), tool_key); + env.insert("MAKIMA_TASK_ID".to_string(), task_id.to_string()); + } + + let msg = DaemonMessage::task_output( + task_id, + "Directive integration ready (makima CLI available)\n".to_string(), + false, + ); + let _ = self.ws_tx.send(msg).await; + + (Some(env), full_plan, system_prompt) + } else { + (extra_env, full_plan, system_prompt) + }; + // Spawn Claude process let plan_bytes = full_plan.len(); let plan_chars = full_plan.chars().count(); diff --git a/makima/src/daemon/ws/protocol.rs b/makima/src/daemon/ws/protocol.rs index 574e864..834e139 100644 --- a/makima/src/daemon/ws/protocol.rs +++ b/makima/src/daemon/ws/protocol.rs @@ -524,6 +524,9 @@ pub enum DaemonCommand { /// Task ID to share worktree with (supervisor's task ID). If Some, use that task's worktree instead of creating a new one. #[serde(rename = "supervisorWorktreeTaskId", default, skip_serializing_if = "Option::is_none")] supervisor_worktree_task_id: Option<Uuid>, + /// Directive ID if this task is associated with a directive. + #[serde(rename = "directiveId", default, skip_serializing_if = "Option::is_none")] + directive_id: Option<Uuid>, }, /// Pause a running task. diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index 9dedc14..930a73e 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -5072,6 +5072,15 @@ pub async fn delete_directive_for_owner( owner_id: Uuid, id: Uuid, ) -> Result<bool, sqlx::Error> { + // Delete all tasks associated with this directive + sqlx::query( + r#"DELETE FROM tasks WHERE directive_id = $1 AND owner_id = $2"#, + ) + .bind(id) + .bind(owner_id) + .execute(pool) + .await?; + let result = sqlx::query( r#"DELETE FROM directives WHERE id = $1 AND owner_id = $2"#, ) diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs index a95e63f..744977e 100644 --- a/makima/src/orchestration/directive.rs +++ b/makima/src/orchestration/directive.rs @@ -408,6 +408,7 @@ impl DirectiveOrchestrator { local_only: false, auto_merge_local: false, supervisor_worktree_task_id: None, + directive_id: updated_task.directive_id, }; if let Err(e) = self.state.send_daemon_command(daemon_id, command).await { diff --git a/makima/src/server/handlers/contract_chat.rs b/makima/src/server/handlers/contract_chat.rs index 2c7a800..5d8ab3e 100644 --- a/makima/src/server/handlers/contract_chat.rs +++ b/makima/src/server/handlers/contract_chat.rs @@ -1610,6 +1610,7 @@ async fn handle_contract_request( local_only, auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: task.directive_id, }; if let Err(e) = command_sender.send(command).await { diff --git a/makima/src/server/handlers/mesh.rs b/makima/src/server/handlers/mesh.rs index 5572d95..eb87e17 100644 --- a/makima/src/server/handlers/mesh.rs +++ b/makima/src/server/handlers/mesh.rs @@ -709,6 +709,7 @@ pub async fn start_task( local_only, auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: task.directive_id, }; tracing::info!( @@ -764,6 +765,7 @@ pub async fn start_task( local_only, auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: task.directive_id, }; if state.send_daemon_command(alt_daemon_id, alt_command).await.is_ok() { @@ -1181,6 +1183,7 @@ pub async fn send_message( local_only, auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: updated_task.directive_id, }; if state.send_daemon_command(new_daemon_id, spawn_cmd).await.is_ok() { @@ -2825,6 +2828,7 @@ pub async fn reassign_task( local_only, auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: task.directive_id, }; tracing::info!( @@ -3165,6 +3169,7 @@ pub async fn continue_task( local_only, auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: task.directive_id, }; tracing::info!( @@ -4097,6 +4102,7 @@ pub async fn branch_task( local_only: false, // No contract, so not local_only auto_merge_local: false, // No contract, so no auto_merge_local supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: None, }; if let Err(e) = state.send_daemon_command(target_daemon_id, command).await { diff --git a/makima/src/server/handlers/mesh_chat.rs b/makima/src/server/handlers/mesh_chat.rs index cf56ab6..638a4d3 100644 --- a/makima/src/server/handlers/mesh_chat.rs +++ b/makima/src/server/handlers/mesh_chat.rs @@ -1169,6 +1169,7 @@ async fn handle_mesh_request( local_only, auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor + directive_id: task.directive_id, }; match state.send_daemon_command(target_daemon_id, command).await { diff --git a/makima/src/server/handlers/mesh_supervisor.rs b/makima/src/server/handlers/mesh_supervisor.rs index 8bf2534..c9cb849 100644 --- a/makima/src/server/handlers/mesh_supervisor.rs +++ b/makima/src/server/handlers/mesh_supervisor.rs @@ -410,6 +410,7 @@ pub async fn try_start_pending_task( auto_merge_local: contract.auto_merge_local, // For retried tasks, use their own worktree (they already have state from previous attempt) supervisor_worktree_task_id: None, + directive_id: updated_task.directive_id, }; if let Err(e) = state.send_daemon_command(daemon.id, cmd).await { @@ -732,6 +733,7 @@ pub async fn spawn_task( auto_merge_local: contract.auto_merge_local, // All tasks share the supervisor's worktree supervisor_worktree_task_id: Some(supervisor_id), + directive_id: updated_task.directive_id, }; if let Err(e) = state.send_daemon_command(daemon.id, cmd).await { @@ -2239,6 +2241,7 @@ pub async fn resume_supervisor( local_only: contract.local_only, auto_merge_local: contract.auto_merge_local, supervisor_worktree_task_id: None, // Supervisor uses its own worktree + directive_id: supervisor_task.directive_id, }; if let Err(e) = state.send_daemon_command(target_daemon_id, command).await { diff --git a/makima/src/server/state.rs b/makima/src/server/state.rs index ba9f9cf..58e8545 100644 --- a/makima/src/server/state.rs +++ b/makima/src/server/state.rs @@ -280,6 +280,9 @@ pub enum DaemonCommand { /// Task ID to share worktree with (supervisor's task ID). If Some, use that task's worktree instead of creating a new one. #[serde(rename = "supervisorWorktreeTaskId", default, skip_serializing_if = "Option::is_none")] supervisor_worktree_task_id: Option<Uuid>, + /// Directive ID if this task is associated with a directive + #[serde(rename = "directiveId", default, skip_serializing_if = "Option::is_none")] + directive_id: Option<Uuid>, }, /// Pause a running task PauseTask { |
