summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-09 15:55:01 +0000
committersoryu <soryu@soryu.co>2026-02-09 15:55:01 +0000
commit339c1769379a851c4126021132573bd4b7994cf2 (patch)
tree8a9a3cdc9d86b3dc2e6883853fb7b22c21dd9e99
parentbfa7bd8d7609397f570f1cd9b83d2269abc0ed63 (diff)
downloadsoryu-339c1769379a851c4126021132573bd4b7994cf2.tar.gz
soryu-339c1769379a851c4126021132573bd4b7994cf2.zip
Set directive env vars correctly for daemon
-rw-r--r--makima/src/daemon/task/manager.rs43
-rw-r--r--makima/src/daemon/ws/protocol.rs3
-rw-r--r--makima/src/db/repository.rs9
-rw-r--r--makima/src/orchestration/directive.rs1
-rw-r--r--makima/src/server/handlers/contract_chat.rs1
-rw-r--r--makima/src/server/handlers/mesh.rs6
-rw-r--r--makima/src/server/handlers/mesh_chat.rs1
-rw-r--r--makima/src/server/handlers/mesh_supervisor.rs3
-rw-r--r--makima/src/server/state.rs3
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 {