From a7670b20bfb44802b6b03b03065ab2817e3b9a44 Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 18 Jan 2026 19:13:51 +0000 Subject: Add supervisor task button to workflow board contract cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add supervisorTaskId field to ContractSummary type in backend and frontend - Update SQL queries in repository.rs to include supervisor_task_id - Add navigation button (▶) to WorkflowContractCard that links to /mesh/{supervisorTaskId} - Button only shows when contract has a supervisorTaskId - Button has tooltip "Open Supervisor Task" and stops propagation to avoid triggering card click Co-Authored-By: Claude Opus 4.5 --- .../components/workflow/WorkflowContractCard.tsx | 26 +++++++++++++++++++--- makima/frontend/src/lib/api.ts | 2 ++ makima/frontend/tsconfig.tsbuildinfo | 2 +- makima/src/db/models.rs | 2 ++ makima/src/db/repository.rs | 4 ++-- makima/src/server/handlers/contracts.rs | 4 ++++ makima/src/server/handlers/mesh.rs | 1 + 7 files changed, 35 insertions(+), 6 deletions(-) diff --git a/makima/frontend/src/components/workflow/WorkflowContractCard.tsx b/makima/frontend/src/components/workflow/WorkflowContractCard.tsx index e6c8a1c..61e6d17 100644 --- a/makima/frontend/src/components/workflow/WorkflowContractCard.tsx +++ b/makima/frontend/src/components/workflow/WorkflowContractCard.tsx @@ -1,3 +1,4 @@ +import { useNavigate } from "react-router"; import type { ContractSummary, ContractStatus } from "../../lib/api"; interface WorkflowContractCardProps { @@ -17,8 +18,16 @@ export function WorkflowContractCard({ onClick, onDragStart, }: WorkflowContractCardProps) { + const navigate = useNavigate(); const status = statusConfig[contract.status] || statusConfig.active; + const handleSupervisorClick = (e: React.MouseEvent) => { + e.stopPropagation(); + if (contract.supervisorTaskId) { + navigate(`/mesh/${contract.supervisorTaskId}`); + } + }; + return (
- {/* Name */} -
- {contract.name} + {/* Header row with name and supervisor button */} +
+
+ {contract.name} +
+ {contract.supervisorTaskId && ( + + )}
{/* Status and counts row */} diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts index 4652347..8393d34 100644 --- a/makima/frontend/src/lib/api.ts +++ b/makima/frontend/src/lib/api.ts @@ -1462,6 +1462,8 @@ export interface ContractSummary { contractType: ContractType; phase: ContractPhase; status: ContractStatus; + /** Supervisor task ID for contract orchestration */ + supervisorTaskId: string | null; fileCount: number; taskCount: number; repositoryCount: number; diff --git a/makima/frontend/tsconfig.tsbuildinfo b/makima/frontend/tsconfig.tsbuildinfo index a3ef773..b8f6c2b 100644 --- a/makima/frontend/tsconfig.tsbuildinfo +++ b/makima/frontend/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/components/gridoverlay.tsx","./src/components/japanesehovertext.tsx","./src/components/logo.tsx","./src/components/masthead.tsx","./src/components/navstrip.tsx","./src/components/protectedroute.tsx","./src/components/rewritelink.tsx","./src/components/simplemarkdown.tsx","./src/components/supervisorquestionnotification.tsx","./src/components/charts/chartrenderer.tsx","./src/components/contracts/autopilotpanel.tsx","./src/components/contracts/contractcliinput.tsx","./src/components/contracts/contractdetail.tsx","./src/components/contracts/contractlist.tsx","./src/components/contracts/phasebadge.tsx","./src/components/contracts/phasedeliverablespanel.tsx","./src/components/contracts/phasehint.tsx","./src/components/contracts/phaseprogressbar.tsx","./src/components/contracts/quickactionbuttons.tsx","./src/components/contracts/repositorypanel.tsx","./src/components/contracts/taskderivationpreview.tsx","./src/components/files/bodyrenderer.tsx","./src/components/files/cliinput.tsx","./src/components/files/conflictnotification.tsx","./src/components/files/elementcontextmenu.tsx","./src/components/files/filedetail.tsx","./src/components/files/filelist.tsx","./src/components/files/reposyncindicator.tsx","./src/components/files/updatenotification.tsx","./src/components/files/versionhistorydropdown.tsx","./src/components/history/checkpointcard.tsx","./src/components/history/checkpointlist.tsx","./src/components/history/conversationmessage.tsx","./src/components/history/conversationview.tsx","./src/components/history/historyfilters.tsx","./src/components/history/resumecontrols.tsx","./src/components/history/timelineeventcard.tsx","./src/components/history/timelinelist.tsx","./src/components/history/index.ts","./src/components/listen/contractpickermodal.tsx","./src/components/listen/controlpanel.tsx","./src/components/listen/speakerpanel.tsx","./src/components/listen/transcriptanalysispanel.tsx","./src/components/listen/transcriptpanel.tsx","./src/components/mesh/directoryinput.tsx","./src/components/mesh/inlinesubtaskeditor.tsx","./src/components/mesh/mergeconflictresolver.tsx","./src/components/mesh/overlaydiffviewer.tsx","./src/components/mesh/prpreview.tsx","./src/components/mesh/subtasktree.tsx","./src/components/mesh/taskdetail.tsx","./src/components/mesh/tasklist.tsx","./src/components/mesh/taskoutput.tsx","./src/components/mesh/tasktree.tsx","./src/components/mesh/unifiedmeshchatinput.tsx","./src/components/workflow/phasecolumn.tsx","./src/components/workflow/workflowboard.tsx","./src/components/workflow/workflowcontractcard.tsx","./src/contexts/authcontext.tsx","./src/contexts/supervisorquestionscontext.tsx","./src/hooks/usecontracts.ts","./src/hooks/usefilesubscription.ts","./src/hooks/usefiles.ts","./src/hooks/usemeshchathistory.ts","./src/hooks/usemicrophone.ts","./src/hooks/usetasksubscription.ts","./src/hooks/usetasks.ts","./src/hooks/usetextscramble.ts","./src/hooks/useversionhistory.ts","./src/hooks/usewebsocket.ts","./src/lib/api.ts","./src/lib/listenapi.ts","./src/lib/markdown.ts","./src/lib/supabase.ts","./src/routes/_index.tsx","./src/routes/contracts.tsx","./src/routes/files.tsx","./src/routes/history.tsx","./src/routes/listen.tsx","./src/routes/login.tsx","./src/routes/mesh.tsx","./src/routes/settings.tsx","./src/routes/workflow.tsx","./src/types/messages.ts"],"version":"5.9.3"} \ No newline at end of file +{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/components/gridoverlay.tsx","./src/components/japanesehovertext.tsx","./src/components/logo.tsx","./src/components/masthead.tsx","./src/components/navstrip.tsx","./src/components/phaseconfirmationnotification.tsx","./src/components/protectedroute.tsx","./src/components/rewritelink.tsx","./src/components/simplemarkdown.tsx","./src/components/supervisorquestionnotification.tsx","./src/components/charts/chartrenderer.tsx","./src/components/contracts/autopilotpanel.tsx","./src/components/contracts/contractcliinput.tsx","./src/components/contracts/contractdetail.tsx","./src/components/contracts/contractlist.tsx","./src/components/contracts/phasebadge.tsx","./src/components/contracts/phaseconfirmationmodal.tsx","./src/components/contracts/phasedeliverablespanel.tsx","./src/components/contracts/phasehint.tsx","./src/components/contracts/phaseprogressbar.tsx","./src/components/contracts/quickactionbuttons.tsx","./src/components/contracts/repositorypanel.tsx","./src/components/contracts/taskderivationpreview.tsx","./src/components/files/bodyrenderer.tsx","./src/components/files/cliinput.tsx","./src/components/files/conflictnotification.tsx","./src/components/files/elementcontextmenu.tsx","./src/components/files/filedetail.tsx","./src/components/files/filelist.tsx","./src/components/files/reposyncindicator.tsx","./src/components/files/updatenotification.tsx","./src/components/files/versionhistorydropdown.tsx","./src/components/history/checkpointcard.tsx","./src/components/history/checkpointlist.tsx","./src/components/history/conversationmessage.tsx","./src/components/history/conversationview.tsx","./src/components/history/historyfilters.tsx","./src/components/history/resumecontrols.tsx","./src/components/history/timelineeventcard.tsx","./src/components/history/timelinelist.tsx","./src/components/history/index.ts","./src/components/listen/contractpickermodal.tsx","./src/components/listen/controlpanel.tsx","./src/components/listen/speakerpanel.tsx","./src/components/listen/transcriptanalysispanel.tsx","./src/components/listen/transcriptpanel.tsx","./src/components/mesh/directoryinput.tsx","./src/components/mesh/inlinesubtaskeditor.tsx","./src/components/mesh/mergeconflictresolver.tsx","./src/components/mesh/overlaydiffviewer.tsx","./src/components/mesh/prpreview.tsx","./src/components/mesh/subtasktree.tsx","./src/components/mesh/taskdetail.tsx","./src/components/mesh/tasklist.tsx","./src/components/mesh/taskoutput.tsx","./src/components/mesh/tasktree.tsx","./src/components/mesh/unifiedmeshchatinput.tsx","./src/components/workflow/phasecolumn.tsx","./src/components/workflow/workflowboard.tsx","./src/components/workflow/workflowcontractcard.tsx","./src/contexts/authcontext.tsx","./src/contexts/supervisorquestionscontext.tsx","./src/hooks/usecontracts.ts","./src/hooks/usefilesubscription.ts","./src/hooks/usefiles.ts","./src/hooks/usemeshchathistory.ts","./src/hooks/usemicrophone.ts","./src/hooks/usetasksubscription.ts","./src/hooks/usetasks.ts","./src/hooks/usetextscramble.ts","./src/hooks/useversionhistory.ts","./src/hooks/usewebsocket.ts","./src/lib/api.ts","./src/lib/listenapi.ts","./src/lib/markdown.ts","./src/lib/supabase.ts","./src/routes/_index.tsx","./src/routes/contracts.tsx","./src/routes/files.tsx","./src/routes/history.tsx","./src/routes/listen.tsx","./src/routes/login.tsx","./src/routes/mesh.tsx","./src/routes/settings.tsx","./src/routes/workflow.tsx","./src/types/messages.ts"],"version":"5.9.3"} \ No newline at end of file diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index 3e6997f..65f7168 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -1348,6 +1348,8 @@ pub struct ContractSummary { pub contract_type: String, pub phase: String, pub status: String, + /// Supervisor task ID for contract orchestration + pub supervisor_task_id: Option, pub file_count: i64, pub task_count: i64, pub repository_count: i64, diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index 36e6bc1..536bc9b 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -2190,7 +2190,7 @@ pub async fn list_contracts_for_owner( r#" SELECT c.id, c.name, c.description, c.contract_type, c.phase, c.status, - c.version, c.created_at, + c.supervisor_task_id, c.version, c.created_at, (SELECT COUNT(*) FROM files WHERE contract_id = c.id) as file_count, (SELECT COUNT(*) FROM tasks WHERE contract_id = c.id) as task_count, (SELECT COUNT(*) FROM contract_repositories WHERE contract_id = c.id) as repository_count @@ -2214,7 +2214,7 @@ pub async fn get_contract_summary_for_owner( r#" SELECT c.id, c.name, c.description, c.contract_type, c.phase, c.status, - c.version, c.created_at, + c.supervisor_task_id, c.version, c.created_at, (SELECT COUNT(*) FROM files WHERE contract_id = c.id) as file_count, (SELECT COUNT(*) FROM tasks WHERE contract_id = c.id) as task_count, (SELECT COUNT(*) FROM contract_repositories WHERE contract_id = c.id) as repository_count diff --git a/makima/src/server/handlers/contracts.rs b/makima/src/server/handlers/contracts.rs index 4f4a94b..4524860 100644 --- a/makima/src/server/handlers/contracts.rs +++ b/makima/src/server/handlers/contracts.rs @@ -371,6 +371,7 @@ pub async fn create_contract( contract_type: contract.contract_type, phase: contract.phase, status: contract.status, + supervisor_task_id: contract.supervisor_task_id, file_count: 0, task_count: 0, repository_count: 0, @@ -391,6 +392,7 @@ pub async fn create_contract( contract_type: contract.contract_type, phase: contract.phase, status: contract.status, + supervisor_task_id: contract.supervisor_task_id, file_count: 0, task_count: 0, repository_count: 0, @@ -518,6 +520,7 @@ pub async fn update_contract( contract_type: contract.contract_type, phase: contract.phase, status: contract.status, + supervisor_task_id: contract.supervisor_task_id, file_count: 0, task_count: 0, repository_count: 0, @@ -1398,6 +1401,7 @@ pub async fn change_phase( contract_type: updated_contract.contract_type, phase: updated_contract.phase, status: updated_contract.status, + supervisor_task_id: updated_contract.supervisor_task_id, file_count: 0, task_count: 0, repository_count: 0, diff --git a/makima/src/server/handlers/mesh.rs b/makima/src/server/handlers/mesh.rs index f8df69f..752ffbc 100644 --- a/makima/src/server/handlers/mesh.rs +++ b/makima/src/server/handlers/mesh.rs @@ -3308,6 +3308,7 @@ pub async fn create_adhoc_task( contract_type: contract.contract_type, phase: contract.phase, status: contract.status, + supervisor_task_id: contract.supervisor_task_id, file_count: 0, task_count: 1, repository_count: 0, -- cgit v1.2.3