From 4bd40f047a6f4703945c6db2811d8feda27241d6 Mon Sep 17 00:00:00 2001 From: soryu Date: Mon, 16 Feb 2026 19:01:56 +0000 Subject: soryu-co/soryu - makima (#66) * feat: soryu-co/soryu - makima: Fix contracts page scrolling overflow * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint --- makima/src/orchestration/directive.rs | 81 +++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 9 deletions(-) (limited to 'makima/src/orchestration') diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs index 020c2e4..62f15d9 100644 --- a/makima/src/orchestration/directive.rs +++ b/makima/src/orchestration/directive.rs @@ -245,6 +245,20 @@ impl DirectiveOrchestrator { ..Default::default() }; repository::update_directive_step(&self.pool, step.step_id, update).await?; + + // Mark linked orders as done + if let Ok(linked_orders) = repository::get_orders_by_step_id(&self.pool, step.step_id).await { + for order in linked_orders { + if order.status != "done" && order.status != "archived" { + let order_update = crate::db::models::UpdateOrderRequest { + status: Some("done".to_string()), + ..Default::default() + }; + let _ = repository::update_order(&self.pool, order.owner_id, order.id, order_update).await; + } + } + } + repository::advance_directive_ready_steps(&self.pool, step.directive_id) .await?; repository::check_directive_idle(&self.pool, step.directive_id).await?; @@ -961,11 +975,7 @@ pub async fn trigger_completion_task( }) .collect(); - let prompt = if directive.pr_url.is_some() { - build_verification_prompt(&directive, &directive_branch, base_branch) - } else { - build_completion_prompt(&directive, &step_tasks, &step_branches, &directive_branch, base_branch) - }; + let prompt = build_completion_prompt(&directive, &step_tasks, &step_branches, &directive_branch, base_branch); let task_name = if directive.pr_url.is_some() { format!("Update PR: {}", directive.title) @@ -1330,12 +1340,58 @@ fn build_completion_prompt( .collect::>() .join("\n"); - if directive.pr_url.is_some() { - // Re-completion: PR already exists, merge new branches into existing PR branch + if let Some(ref pr_url) = directive.pr_url { + // Re-completion: PR already exists — but it may have been merged or closed. + // We must check the PR state first and handle accordingly. format!( r#"You are updating an existing PR for directive "{title}". -The PR branch `{directive_branch}` already exists. Merge any new step branches into it. +IMPORTANT: The previous PR may have been merged or closed. You MUST check its state first. + +## Step 1: Check PR state + +Run this command to check the PR state: +``` +gh pr view {pr_url} --json state --jq '.state' +``` + +## If the PR state is MERGED or CLOSED: + +The previous PR was already merged/closed. You need to create a NEW PR with a fresh branch. + +1. Clear the old PR URL: +``` +makima directive update --pr-url "" +``` + +2. Create a fresh branch with a timestamp suffix to avoid collision: +``` +git fetch origin +NEW_BRANCH="{directive_branch}-v$(date +%s)" +git checkout -b "$NEW_BRANCH" origin/{base_branch} +{merge_commands} +git push -u origin "$NEW_BRANCH" +``` + +3. Create a new PR: +``` +gh pr create --title "{title}" --body "{pr_body}" --head "$NEW_BRANCH" --base {base_branch} +``` + +4. Store the new PR URL: +``` +makima directive update --pr-url "" +``` +Replace the URL with the actual PR URL from the `gh pr create` output. This step is CRITICAL. + +5. Update the directive pr_branch to the new branch name: +``` +makima directive update --pr-branch "$NEW_BRANCH" +``` + +## If the PR state is OPEN: + +The PR is still open. Merge new step branches into the existing PR branch. Steps completed: {step_summary} @@ -1352,9 +1408,16 @@ git push origin {directive_branch} Already-merged branches will be a no-op. If there are merge conflicts, resolve them sensibly. "#, title = directive.title, + pr_url = pr_url, directive_branch = directive_branch, + base_branch = base_branch, step_summary = step_summary, merge_commands = merge_commands, + pr_body = format!( + "## Directive\\n\\n{}\\n\\n## Steps\\n\\n{}", + directive.goal.replace('\n', "\\n").replace('"', "\\\""), + step_summary.replace('\n', "\\n").replace('"', "\\\""), + ), ) } else { // First completion: create new PR @@ -1508,7 +1571,7 @@ pub fn build_order_pickup_prompt( } // ── Orders being picked up ─────────────────────────────────── - prompt.push_str("== ORDERS AVAILABLE FOR PICKUP ==\n"); + prompt.push_str("== ORDERS AVAILABLE FOR PLANNING ==\n"); prompt.push_str("The following open orders have been linked to this directive. \ Review them and create steps to fulfil them.\n\n"); for (i, order) in orders.iter().enumerate() { -- cgit v1.2.3