diff options
| author | soryu <soryu@soryu.co> | 2026-02-14 21:27:57 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-14 21:27:57 +0000 |
| commit | 3002fdeb91ad62e48bf0ad2bd5f1206acfc9539d (patch) | |
| tree | ef8bed9718c39041191b58a284ee31f5d8d32521 | |
| parent | afd820f99056caeada04c19d7c33fef615a809b4 (diff) | |
| parent | 1f0dd5872bafd3776108edadcb519ae5de801e77 (diff) | |
| download | soryu-3002fdeb91ad62e48bf0ad2bd5f1206acfc9539d.tar.gz soryu-3002fdeb91ad62e48bf0ad2bd5f1206acfc9539d.zip | |
Merge remote-tracking branch 'origin/makima/soryu-co-soryu---makima--fix-directive-pr-creation-00fea7d9' into makima/directive-soryu-co-soryu-makima-c29f9112makima/soryu-co-soryu---makima--create-pr-for-all-directi-dae80fbbmakima/directive-soryu-co-soryu-makima-c29f9112
| -rw-r--r-- | makima/src/daemon/skills/directive.md | 6 | ||||
| -rw-r--r-- | makima/src/db/repository.rs | 3 | ||||
| -rw-r--r-- | makima/src/orchestration/directive.rs | 78 |
3 files changed, 84 insertions, 3 deletions
diff --git a/makima/src/daemon/skills/directive.md b/makima/src/daemon/skills/directive.md index 68d9277..9d2b644 100644 --- a/makima/src/daemon/skills/directive.md +++ b/makima/src/daemon/skills/directive.md @@ -76,6 +76,12 @@ Updates the goal and bumps `goalUpdatedAt`. If the directive is `idle`, it react makima directive pause ``` +### Update Directive Metadata +```bash +makima directive update --pr-url "<url>" --pr-branch "<branch>" +``` +Updates the directive's PR URL and/or PR branch. Used by completion tasks to store the PR URL after creating it. + ## Memory Commands Directives have an optional key-value memory system that persists across steps and planning cycles. Use memory to share context, decisions, and learned information between steps — so downstream tasks don't need to re-discover what earlier steps already figured out. diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index a2489aa..ed4a1fa 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -5194,6 +5194,7 @@ pub struct CompletedStepTask { #[derive(Debug, Clone, sqlx::FromRow)] pub struct DirectiveCompletionCheck { pub directive_id: Uuid, + pub owner_id: Uuid, pub completion_task_id: Uuid, pub task_status: String, pub pr_url: Option<String>, @@ -5230,7 +5231,7 @@ pub async fn get_completion_tasks_to_check( ) -> Result<Vec<DirectiveCompletionCheck>, sqlx::Error> { sqlx::query_as::<_, DirectiveCompletionCheck>( r#" - SELECT d.id as directive_id, d.completion_task_id, t.status as task_status, d.pr_url + SELECT d.id as directive_id, d.owner_id, d.completion_task_id, t.status as task_status, d.pr_url FROM directives d JOIN tasks t ON t.id = d.completion_task_id WHERE d.completion_task_id IS NOT NULL diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs index 6d5d63d..0deacca 100644 --- a/makima/src/orchestration/directive.rs +++ b/makima/src/orchestration/directive.rs @@ -637,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" => { @@ -698,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<Option<String>, 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. @@ -962,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 "<the PR URL from gh pr create output>" +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. "#, |
