From 9aadbc7958d39d181c0dd0600e2b7c30bb6c391a Mon Sep 17 00:00:00 2001 From: soryu Date: Sat, 14 Feb 2026 21:29:26 +0000 Subject: Makima system improvements: Orders, directive questions, PR creation fix, bug fixes (#62) * feat: soryu-co/soryu - makima: Fix directive goal update bug - stale closure issue * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Create Orders database schema and backend API * feat: soryu-co/soryu - makima: Fix task Claude instance not receiving user inputs from input box * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Build Orders frontend page replacing the Board page * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Fix directive PR creation system --- makima/src/orchestration/directive.rs | 88 ++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) (limited to 'makima/src/orchestration') diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs index ea8009d..0deacca 100644 --- a/makima/src/orchestration/directive.rs +++ b/makima/src/orchestration/directive.rs @@ -248,6 +248,16 @@ impl DirectiveOrchestrator { .await?; repository::check_directive_idle(&self.pool, step.directive_id).await?; } + "paused" => { + // Task is paused (e.g., waiting for user answer in reconcile mode) + // Keep step in running status — task will auto-resume when answered + tracing::debug!( + step_id = %step.step_id, + directive_id = %step.directive_id, + task_id = %step.task_id, + "Step task paused (waiting for user response) — keeping step running" + ); + } _ => { // Still running — do nothing } @@ -627,6 +637,45 @@ impl DirectiveOrchestrator { task_id = %check.completion_task_id, "Completion task finished" ); + + // If directive has no pr_url yet, try to extract from task output + if check.pr_url.is_none() { + match self.extract_pr_url_from_task(check.completion_task_id).await { + Ok(Some(url)) => { + tracing::info!( + directive_id = %check.directive_id, + pr_url = %url, + "Extracted PR URL from completion task output" + ); + let update = crate::db::models::UpdateDirectiveRequest { + pr_url: Some(url), + ..Default::default() + }; + let _ = repository::update_directive_for_owner( + &self.pool, + check.owner_id, + check.directive_id, + update, + ) + .await; + } + Ok(None) => { + tracing::warn!( + directive_id = %check.directive_id, + task_id = %check.completion_task_id, + "Completion task finished but no PR URL found in output" + ); + } + Err(e) => { + tracing::warn!( + directive_id = %check.directive_id, + error = %e, + "Failed to extract PR URL from completion task output" + ); + } + } + } + repository::clear_completion_task(&self.pool, check.directive_id).await?; } "failed" | "interrupted" => { @@ -688,6 +737,36 @@ impl DirectiveOrchestrator { Ok(task.id) } + + /// Extract a GitHub PR URL from a completion task's output events. + /// Searches task output for patterns like `https://github.com/.../pull/123`. + async fn extract_pr_url_from_task( + &self, + task_id: Uuid, + ) -> Result, anyhow::Error> { + let events = repository::get_task_output(&self.pool, task_id, Some(500)).await?; + + let pr_url_re = regex::Regex::new(r"https://github\.com/[^/\s]+/[^/\s]+/pull/\d+")?; + + // Search from most recent events backwards for the PR URL + for event in events.iter().rev() { + if let Some(ref data) = event.event_data { + // Check the content field inside event_data JSON + if let Some(content) = data.get("content").and_then(|c| c.as_str()) { + if let Some(m) = pr_url_re.find(content) { + return Ok(Some(m.as_str().to_string())); + } + } + // Also check the raw JSON string representation as fallback + let data_str = data.to_string(); + if let Some(m) = pr_url_re.find(&data_str) { + return Ok(Some(m.as_str().to_string())); + } + } + } + + Ok(None) + } } /// Build the planning prompt for a directive. @@ -952,10 +1031,15 @@ Then create the PR: gh pr create --title "{title}" --body "{pr_body}" --head {directive_branch} --base {base_branch} ``` -After creating the PR, store the URL: +IMPORTANT: After creating the PR, you MUST store the PR URL so the directive system can track it. + +1. Run `gh pr create` as shown above and capture its output +2. The output will contain the PR URL (e.g., https://github.com/owner/repo/pull/123) +3. Then run this command to store the URL: ``` -makima directive update --pr-url "" +makima directive update --pr-url "https://github.com/..." ``` +Replace the URL with the actual PR URL from the `gh pr create` output. This step is CRITICAL — the PR will not be tracked by the directive system without it. If there are merge conflicts, resolve them sensibly before pushing. "#, -- cgit v1.2.3