diff options
| author | soryu <soryu@soryu.co> | 2026-01-31 22:17:09 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-31 22:17:09 +0000 |
| commit | 3ea2c72e2c50c0d73614d9ac82f41508b6ab1ce4 (patch) | |
| tree | fbbd53c9e39d9af9dc0e92af5866dd9e3589bf2d /makima/src/server/handlers/mesh.rs | |
| parent | c526f93aa4255cb581eeb3f7a495c1689683b0a2 (diff) | |
| download | soryu-3ea2c72e2c50c0d73614d9ac82f41508b6ab1ce4.tar.gz soryu-3ea2c72e2c50c0d73614d9ac82f41508b6ab1ce4.zip | |
Add auto_merge_local option for local-only contracts (#50)
When local_only=true on a contract, all completion actions are skipped.
This adds a new option auto_merge_local that, when enabled along with
local_only, will automatically merge completed task changes to the
master/main branch locally (without pushing or creating PRs).
Changes:
- Add auto_merge_local column to contracts table (migration)
- Add auto_merge_local field to Contract model and summary
- Update CreateContractRequest and UpdateContractRequest structs
- Update contract repository create/update functions
- Add auto_merge_local to WebSocket protocol StartTask command
- Pass auto_merge_local through spawn_task and run_task functions
- Modify task manager completion logic: if local_only=true AND
auto_merge_local=true, execute 'merge' completion action locally
- Update all server handlers to retrieve and pass auto_merge_local
- Add TypeScript types to frontend components
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'makima/src/server/handlers/mesh.rs')
| -rw-r--r-- | makima/src/server/handlers/mesh.rs | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/makima/src/server/handlers/mesh.rs b/makima/src/server/handlers/mesh.rs index 9ef6248..af77b56 100644 --- a/makima/src/server/handlers/mesh.rs +++ b/makima/src/server/handlers/mesh.rs @@ -601,14 +601,14 @@ pub async fn start_task( .into_response(); } - // Get local_only flag from contract if task has one - let local_only = if let Some(contract_id) = task.contract_id { + // Get local_only and auto_merge_local flags from contract if task has one + let (local_only, auto_merge_local) = if let Some(contract_id) = task.contract_id { match repository::get_contract_for_owner(pool, contract_id, auth.owner_id).await { - Ok(Some(contract)) => contract.local_only, - _ => false, + Ok(Some(contract)) => (contract.local_only, contract.auto_merge_local), + _ => (false, false), } } else { - false + (false, false) }; // Get list of daemons that have previously failed this task @@ -707,6 +707,7 @@ pub async fn start_task( patch_data: None, patch_base_sha: None, local_only, + auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor }; @@ -761,6 +762,7 @@ pub async fn start_task( patch_data: None, patch_base_sha: None, local_only, + auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor }; @@ -1144,14 +1146,14 @@ pub async fn send_message( }; if let Ok(Some(updated_task)) = repository::update_task_for_owner(pool, id, auth.owner_id, update_req).await { - // Get local_only from contract if task has one - let local_only = if let Some(contract_id) = updated_task.contract_id { + // Get local_only and auto_merge_local from contract if task has one + let (local_only, auto_merge_local) = if let Some(contract_id) = updated_task.contract_id { match repository::get_contract_for_owner(pool, contract_id, auth.owner_id).await { - Ok(Some(contract)) => contract.local_only, - _ => false, + Ok(Some(contract)) => (contract.local_only, contract.auto_merge_local), + _ => (false, false), } } else { - false + (false, false) }; // Send spawn command to new daemon @@ -1177,6 +1179,7 @@ pub async fn send_message( patch_data: None, patch_base_sha: None, local_only, + auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor }; @@ -2689,14 +2692,14 @@ pub async fn reassign_task( } }; - // Get local_only from contract if task has one - let local_only = if let Some(contract_id) = task.contract_id { + // Get local_only and auto_merge_local from contract if task has one + let (local_only, auto_merge_local) = if let Some(contract_id) = task.contract_id { match repository::get_contract_for_owner(pool, contract_id, auth.owner_id).await { - Ok(Some(contract)) => contract.local_only, - _ => false, + Ok(Some(contract)) => (contract.local_only, contract.auto_merge_local), + _ => (false, false), } } else { - false + (false, false) }; // Send SpawnTask command to daemon for the new task @@ -2722,6 +2725,7 @@ pub async fn reassign_task( patch_data, patch_base_sha, local_only, + auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor }; @@ -3028,14 +3032,14 @@ pub async fn continue_task( }; let is_orchestrator = task.depth == 0 && subtask_count > 0; - // Get local_only from contract if task has one - let local_only = if let Some(contract_id) = task.contract_id { + // Get local_only and auto_merge_local from contract if task has one + let (local_only, auto_merge_local) = if let Some(contract_id) = task.contract_id { match repository::get_contract_for_owner(pool, contract_id, auth.owner_id).await { - Ok(Some(contract)) => contract.local_only, - _ => false, + Ok(Some(contract)) => (contract.local_only, contract.auto_merge_local), + _ => (false, false), } } else { - false + (false, false) }; // Send SpawnTask command to daemon @@ -3061,6 +3065,7 @@ pub async fn continue_task( patch_data: None, patch_base_sha: None, local_only, + auto_merge_local, supervisor_worktree_task_id: None, // Not spawned by supervisor }; @@ -3989,6 +3994,7 @@ pub async fn branch_task( patch_data, patch_base_sha, 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 }; |
