summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-18 19:55:37 +0000
committerGitHub <noreply@github.com>2026-01-18 19:55:37 +0000
commitb3eb58d50eea5b235a1c33d5c8787dc81064c46b (patch)
tree50e174970ecd42c60d2efc571cad12eb27e43ffc
parent9dbc2c3199047609a9f8496fec07ecdb10aee73d (diff)
downloadsoryu-b3eb58d50eea5b235a1c33d5c8787dc81064c46b.tar.gz
soryu-b3eb58d50eea5b235a1c33d5c8787dc81064c46b.zip
Clean up mesh page (#6)
* Filter mesh page task list to show only supervisor tasks - Add `isSupervisor` filter to rootTasks filter in TaskList component - Only supervisor tasks will appear in the mesh page task list - Regular tasks are now hidden from the main view - Update empty state messages to reflect supervisor-only filtering - When clicking a supervisor task, its detail still shows orchestrated tasks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add supervisor task button to workflow board contract cards - 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 <noreply@anthropic.com> * Add full task page navigation button to TaskTree rows Add a hover-visible arrow icon (↗) to each task row in the TaskTree component that links to the full task page (/tasks/{taskId}). The button: - Appears on hover using opacity transition - Stops event propagation to avoid triggering parent onSelect - Matches existing hover styling patterns with the #75aafc color scheme Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
-rw-r--r--makima/frontend/src/components/mesh/TaskList.tsx8
-rw-r--r--makima/frontend/src/components/mesh/TaskTree.tsx10
-rw-r--r--makima/frontend/src/components/workflow/WorkflowContractCard.tsx26
-rw-r--r--makima/frontend/src/lib/api.ts2
-rw-r--r--makima/src/db/models.rs2
-rw-r--r--makima/src/db/repository.rs4
-rw-r--r--makima/src/server/handlers/contracts.rs4
-rw-r--r--makima/src/server/handlers/mesh.rs1
8 files changed, 48 insertions, 9 deletions
diff --git a/makima/frontend/src/components/mesh/TaskList.tsx b/makima/frontend/src/components/mesh/TaskList.tsx
index f829b29..80077b6 100644
--- a/makima/frontend/src/components/mesh/TaskList.tsx
+++ b/makima/frontend/src/components/mesh/TaskList.tsx
@@ -95,8 +95,8 @@ export function TaskList({
// Group tasks by contract and filter by status
const groupedTasks = useMemo(() => {
- // Separate root tasks (no parent) from subtasks
- const rootTasks = tasks.filter((t) => !t.parentTaskId);
+ // Separate root tasks (no parent) from subtasks, and only show supervisor tasks
+ const rootTasks = tasks.filter((t) => !t.parentTaskId && t.isSupervisor);
// Filter tasks based on contract status
const filteredTasks = statusFilter === 'all'
@@ -205,8 +205,8 @@ export function TaskList({
{totalTasks === 0 ? (
<div className="text-center text-[#9bc3ff] text-sm font-mono opacity-60 py-8">
{statusFilter === 'all'
- ? 'No tasks yet. Create one to start orchestrating Claude Code instances.'
- : `No ${statusFilter} tasks found.`}
+ ? 'No supervisor tasks yet. Create a contract to start orchestrating tasks.'
+ : `No ${statusFilter} supervisor tasks found.`}
</div>
) : (
<div>
diff --git a/makima/frontend/src/components/mesh/TaskTree.tsx b/makima/frontend/src/components/mesh/TaskTree.tsx
index 46ae78d..296d3c6 100644
--- a/makima/frontend/src/components/mesh/TaskTree.tsx
+++ b/makima/frontend/src/components/mesh/TaskTree.tsx
@@ -165,6 +165,16 @@ function TreeNode({ task, isSupervisorTask, onSelect, depth, fetchSubtasks }: Tr
P{task.priority}
</span>
)}
+
+ {/* Open in full page button */}
+ <a
+ href={`/tasks/${task.id}`}
+ onClick={(e) => e.stopPropagation()}
+ className="font-mono text-[10px] text-[#555] opacity-0 group-hover:opacity-100 hover:text-[#75aafc] transition-all"
+ title="Open task page"
+ >
+ ↗
+ </a>
</div>
{/* Children */}
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 (
<div
draggable
@@ -26,9 +35,20 @@ export function WorkflowContractCard({
onClick={onClick}
className="p-3 bg-[rgba(9,13,20,0.8)] border border-[rgba(117,170,252,0.2)] hover:border-[rgba(117,170,252,0.4)] cursor-pointer transition-colors select-none"
>
- {/* Name */}
- <div className="font-mono text-sm text-[#dbe7ff] truncate mb-1">
- {contract.name}
+ {/* Header row with name and supervisor button */}
+ <div className="flex items-center justify-between gap-2 mb-1">
+ <div className="font-mono text-sm text-[#dbe7ff] truncate flex-1">
+ {contract.name}
+ </div>
+ {contract.supervisorTaskId && (
+ <button
+ onClick={handleSupervisorClick}
+ title="Open Supervisor Task"
+ className="flex-shrink-0 px-1.5 py-0.5 font-mono text-[10px] text-[#75aafc] hover:text-[#9bc3ff] border border-[rgba(117,170,252,0.25)] hover:border-[#3f6fb3] hover:bg-[rgba(117,170,252,0.1)] transition-colors"
+ >
+ ▶
+ </button>
+ )}
</div>
{/* Status and counts row */}
diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts
index abf72b8..daa2b5c 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/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<Uuid>,
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 f710be1..e9a421c 100644
--- a/makima/src/server/handlers/mesh.rs
+++ b/makima/src/server/handlers/mesh.rs
@@ -3447,6 +3447,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,