diff --git a/packages/dashboard/app/components/TaskCard.tsx b/packages/dashboard/app/components/TaskCard.tsx index 4781ffa4a0..ce3d0b1cfa 100644 --- a/packages/dashboard/app/components/TaskCard.tsx +++ b/packages/dashboard/app/components/TaskCard.tsx @@ -11,6 +11,7 @@ import { VALID_TRANSITIONS, getErrorMessage, } from "@fusion/core"; +import { resolveEffectiveAutoMerge } from "../../../core/src/task-merge"; import { fetchTaskDetail, uploadAttachment, fetchMission, fetchAgent, type WorkflowFieldDefinition } from "../api"; import { GitHubBadge } from "./GitHubBadge"; import { PrCreateModal } from "./PrCreateModal"; @@ -402,7 +403,7 @@ interface TaskCardProps { fanout?: BlockerFanoutEntry; /** Whether GitHub CLI auth is available for creating PRs from task cards. */ prAuthAvailable?: boolean; - /** Whether project-level auto-merge is enabled (hides manual Create PR quick action when true). */ + /** Project default auto-merge setting; per-task overrides are applied via resolveEffectiveAutoMerge. */ autoMergeEnabled?: boolean; /** Card-placed custom field definitions for this task's workflow (U13/KTD-14). * Empty/undefined → no field badges render (card byte-identical to today). */ @@ -1264,9 +1265,10 @@ function TaskCardComponent({ }, [liveBadgeData, batchData, task.issueInfo, task.updatedAt]); const showInReviewMoveControl = task.column === "in-review" && Boolean(onMoveTask); + const effectiveAutoMerge = resolveEffectiveAutoMerge({ autoMerge: task.autoMerge }, { autoMerge: autoMergeEnabled ?? false }); const showCreatePrQuickAction = task.column === "in-review" - && autoMergeEnabled !== true + && !effectiveAutoMerge && !livePrInfo && prAuthAvailable === true && !isPaused diff --git a/packages/dashboard/app/components/TaskDetailModal.tsx b/packages/dashboard/app/components/TaskDetailModal.tsx index cd713be125..fa762392ae 100644 --- a/packages/dashboard/app/components/TaskDetailModal.tsx +++ b/packages/dashboard/app/components/TaskDetailModal.tsx @@ -21,6 +21,7 @@ import { resolveTaskPlanningModel, resolveTaskValidatorModel, } from "@fusion/core"; +import { resolveEffectiveAutoMerge } from "../../../core/src/task-merge"; import { uploadAttachment, deleteAttachment, updateTask, pauseTask, unpauseTask, fetchTaskDetail, fetchSettings, fetchGlobalSettings, requestSpecRevision, rebuildTaskSpec, approvePlan, rejectPlan, refineTask, fetchWorkflowResults, assignTask, fetchAgents, fetchAgent, recoverBranchBinding, refreshPrStatus, fetchBoardWorkflows, updateTaskCustomFields, api } from "../api"; import type { RecoverBranchBindingOutcome, WorkflowFieldDefinition, CustomFieldRejection } from "../api"; import { ApiRequestError } from "../api"; @@ -2571,6 +2572,7 @@ export function TaskDetailContent({ const prAutomationLabel = task.status ? prAutomationStatusLabels[task.status] : undefined; const mergeStrategy = settings?.mergeStrategy ?? "direct"; const autoMergeEnabled = settings?.autoMerge ?? false; + const effectiveAutoMerge = resolveEffectiveAutoMerge({ autoMerge: task.autoMerge }, { autoMerge: autoMergeEnabled }); const isManualPrFlow = mergeStrategy === "pull-request" && !autoMergeEnabled; const isCheckPrStatusAction = isManualPrFlow && !prAutomationLabel && task.prInfo?.status === "open"; @@ -3247,7 +3249,7 @@ export function TaskDetailContent({ prInfos={task.prInfos} automationStatus={task.status ?? null} taskColumn={task.column} - autoMerge={settings?.autoMerge ?? false} + autoMerge={effectiveAutoMerge} isManualPrFlow={isManualPrFlow} directMergeCommitStrategy={settings?.directMergeCommitStrategy} prAuthAvailable={prAuthAvailable ?? false} diff --git a/packages/dashboard/app/components/TaskReviewTab.tsx b/packages/dashboard/app/components/TaskReviewTab.tsx index 154f975a85..e4e20f5d78 100644 --- a/packages/dashboard/app/components/TaskReviewTab.tsx +++ b/packages/dashboard/app/components/TaskReviewTab.tsx @@ -346,7 +346,7 @@ export function TaskReviewTab({ : t("taskReview.effective", "Effective: {{label}}", { label: effectiveAutoMergeLabel })} - {task.column === "in-review" && !task.prInfo && prAuthAvailable === true && autoMergeEnabled !== true && typeof onRequestCreatePr === "function" ? ( + {task.column === "in-review" && !task.prInfo && prAuthAvailable === true && !effectiveAutoMerge && typeof onRequestCreatePr === "function" ? (