summaryrefslogtreecommitdiff
path: root/makima/src/orchestration/directive.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/orchestration/directive.rs')
-rw-r--r--makima/src/orchestration/directive.rs88
1 files changed, 86 insertions, 2 deletions
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<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.
@@ -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 "<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.
"#,