From 3662b334dfd68cfdf00ed44ae88927c2e1b2aabe Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 8 Feb 2026 21:07:30 +0000 Subject: Remove directive mechanism --- makima/frontend/src/components/NavStrip.tsx | 1 - .../directives/DirectiveContractsTab.tsx | 148 ------- .../src/components/directives/DirectiveDetail.tsx | 425 --------------------- .../src/components/directives/DirectiveList.tsx | 143 ------- .../src/components/directives/StepDiagram.tsx | 313 --------------- 5 files changed, 1030 deletions(-) delete mode 100644 makima/frontend/src/components/directives/DirectiveContractsTab.tsx delete mode 100644 makima/frontend/src/components/directives/DirectiveDetail.tsx delete mode 100644 makima/frontend/src/components/directives/DirectiveList.tsx delete mode 100644 makima/frontend/src/components/directives/StepDiagram.tsx (limited to 'makima/frontend/src/components') diff --git a/makima/frontend/src/components/NavStrip.tsx b/makima/frontend/src/components/NavStrip.tsx index f7e67db..fb95c7f 100644 --- a/makima/frontend/src/components/NavStrip.tsx +++ b/makima/frontend/src/components/NavStrip.tsx @@ -11,7 +11,6 @@ interface NavLink { const NAV_LINKS: NavLink[] = [ { label: "Listen", href: "/listen" }, { label: "Contracts", href: "/contracts", requiresAuth: true }, - { label: "Directives", href: "/directives", requiresAuth: true }, { label: "Board", href: "/workflow", requiresAuth: true }, { label: "Mesh", href: "/mesh", requiresAuth: true }, { label: "History", href: "/history", requiresAuth: true }, diff --git a/makima/frontend/src/components/directives/DirectiveContractsTab.tsx b/makima/frontend/src/components/directives/DirectiveContractsTab.tsx deleted file mode 100644 index 28da117..0000000 --- a/makima/frontend/src/components/directives/DirectiveContractsTab.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import { useNavigate } from "react-router"; -import type { - DirectiveWithChains, - StepContractSummary, - ContractPhase, -} from "../../lib/api"; -import { PhaseProgressBarCompact } from "../contracts/PhaseProgressBar"; - -interface DirectiveContractsTabProps { - directive: DirectiveWithChains; -} - -const statusColors: Record = { - active: "text-green-400", - completed: "text-blue-400", - archived: "text-[#555]", -}; - -function ContractCard({ - summary, - label, -}: { - summary: StepContractSummary; - label: string; -}) { - const navigate = useNavigate(); - - const progressPct = - summary.taskCount > 0 - ? Math.round((summary.tasksDone / summary.taskCount) * 100) - : 0; - - return ( -
navigate(`/contracts/${summary.id}`)} - > -
-
- - {summary.name} - - - {summary.contractType} - -
-
- - {summary.status} - - -
-
- -
- - {label} - - -
- - {/* Task progress bar */} -
-
-
-
- - {summary.tasksDone}/{summary.taskCount} tasks - -
-
- ); -} - -export function DirectiveContractsTab({ - directive, -}: DirectiveContractsTabProps) { - // Collect all contract summaries - const contracts: { summary: StepContractSummary; label: string }[] = []; - - if (directive.orchestratorContractSummary) { - contracts.push({ - summary: directive.orchestratorContractSummary, - label: "Planning", - }); - } - - for (const chain of directive.chains) { - for (const step of chain.steps) { - if (step.contractSummary) { - contracts.push({ - summary: step.contractSummary, - label: step.name, - }); - } - // Show monitoring/evaluation contracts - if (step.monitoringContractId) { - contracts.push({ - summary: { - id: step.monitoringContractId, - name: `${step.name} - Evaluation`, - contractType: "monitoring", - status: step.status === "evaluating" ? "active" : "completed", - phase: "plan", - taskCount: 1, - tasksDone: step.status === "evaluating" ? 0 : 1, - tasksRunning: step.status === "evaluating" ? 1 : 0, - tasksFailed: 0, - }, - label: `${step.name} eval`, - }); - } - } - } - - if (contracts.length === 0) { - return ( -
-

- {directive.status === "draft" - ? "No contracts yet. Start the directive to begin planning." - : directive.status === "planning" - ? "Planning in progress... contracts will appear when steps are created." - : "No contracts associated with this directive."} -

-
- ); - } - - return ( -
- {contracts.map((c) => ( - - ))} -
- ); -} diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx deleted file mode 100644 index 6bdf5aa..0000000 --- a/makima/frontend/src/components/directives/DirectiveDetail.tsx +++ /dev/null @@ -1,425 +0,0 @@ -import { useState, useEffect, useRef } from "react"; -import { useNavigate } from "react-router"; -import type { - DirectiveWithChains, - DirectiveStatus, - ContractPhase, -} from "../../lib/api"; -import { getDirective } from "../../lib/api"; -import { PhaseProgressBarCompact } from "../contracts/PhaseProgressBar"; -import { StepDiagram } from "./StepDiagram"; -import { DirectiveContractsTab } from "./DirectiveContractsTab"; - -interface DirectiveDetailProps { - directive: DirectiveWithChains; - onBack: () => void; - onDelete?: (id: string) => void; - onStart?: (id: string) => void; - onRefresh?: (updated: DirectiveWithChains) => void; -} - -type Tab = "overview" | "chain" | "contracts"; - -const statusColors: Record = { - draft: "text-[#888]", - planning: "text-yellow-400", - active: "text-green-400", - paused: "text-orange-400", - completed: "text-blue-400", - archived: "text-[#555]", - failed: "text-red-400", -}; - -function JsonSection({ - label, - data, -}: { - label: string; - data: unknown[] | unknown; -}) { - const items = Array.isArray(data) ? data : []; - if (items.length === 0) return null; - - return ( -
-

- {label} -

-
- {items.map((item, i) => ( -
- {typeof item === "string" ? item : JSON.stringify(item)} -
- ))} -
-
- ); -} - -export function DirectiveDetail({ - directive, - onBack, - onDelete, - onStart, - onRefresh, -}: DirectiveDetailProps) { - const navigate = useNavigate(); - const [activeTab, setActiveTab] = useState("overview"); - - // Auto-poll when directive is in an active state - const isLive = - directive.status === "planning" || directive.status === "active"; - const intervalRef = useRef | null>(null); - - useEffect(() => { - if (!isLive) { - if (intervalRef.current) { - clearInterval(intervalRef.current); - intervalRef.current = null; - } - return; - } - - intervalRef.current = setInterval(async () => { - try { - const updated = await getDirective(directive.id); - if (updated && onRefresh) { - onRefresh(updated); - } - } catch { - // Ignore poll errors - } - }, 5000); - - return () => { - if (intervalRef.current) { - clearInterval(intervalRef.current); - intervalRef.current = null; - } - }; - }, [isLive, directive.id, onRefresh]); - - // Count total steps and completed steps across all chains - const totalSteps = directive.chains.reduce( - (sum, c) => sum + c.totalSteps, - 0 - ); - const completedSteps = directive.chains.reduce( - (sum, c) => sum + c.completedSteps, - 0 - ); - - // Count contracts - const contractCount = - (directive.orchestratorContractSummary ? 1 : 0) + - directive.chains.reduce( - (sum, c) => - sum + c.steps.filter((s) => s.contractSummary != null).length, - 0 - ); - - const tabs: { key: Tab; label: string; count?: number }[] = [ - { key: "overview", label: "Overview" }, - { key: "chain", label: "Chain", count: totalSteps }, - { key: "contracts", label: "Contracts", count: contractCount }, - ]; - - return ( -
- {/* Header */} -
-
- -
- {onStart && directive.status === "draft" && ( - - )} - {onDelete && ( - - )} -
-
-
-

- {directive.title} -

- - {directive.status} - - {isLive && ( - - polling - - )} - - v{directive.version} - -
-
- - {/* Tabs */} -
- {tabs.map((tab) => ( - - ))} -
- - {/* Tab content */} -
- {activeTab === "overview" && ( -
- {/* Orchestrator contract link */} - {directive.orchestratorContractId && ( -
- - Planning Contract - - {directive.orchestratorContractSummary && ( - - )} - - {directive.status === "planning" && ( - - planning in progress - - )} -
- )} - - {/* Goal */} -
-

- Goal -

-

- {directive.goal} -

-
- - {/* Config grid */} -
-
- - Autonomy - -
- {directive.autonomyLevel} -
-
-
- - Chains - -
- {directive.chainGenerationCount} generated -
-
-
- - Cost - -
- ${directive.totalCostUsd.toFixed(2)} -
-
- {directive.repositoryUrl && ( -
- - Repository - -
- {directive.repositoryUrl} -
-
- )} -
- - {/* Stat cards */} -
-
-
- {totalSteps} -
-
- Total Steps -
-
-
-
- {completedSteps} -
-
- Completed -
-
-
-
- ${directive.totalCostUsd.toFixed(2)} -
-
- Cost -
-
-
- - {/* Structured sections */} - - - - - - {/* Metadata */} -
-

- Metadata -

-
- Created - - {new Date(directive.createdAt).toLocaleString()} - - Updated - - {new Date(directive.updatedAt).toLocaleString()} - - {directive.startedAt && ( - <> - Started - - {new Date(directive.startedAt).toLocaleString()} - - - )} - {directive.completedAt && ( - <> - Completed - - {new Date(directive.completedAt).toLocaleString()} - - - )} - Version - {directive.version} -
-
-
- )} - - {activeTab === "chain" && ( -
- {directive.chains.length === 0 ? ( -
-
- {directive.status === "planning" ? "\u2699" : "\u25CB"} -
-

- {directive.status === "planning" - ? "Planning in progress... the chain will appear when the planner submits a plan." - : directive.status === "draft" - ? "No chains yet. Start the directive to begin planning." - : "No chains created for this directive."} -

-
- ) : ( - <> - {/* Chain metadata header */} - {directive.chains.map((chain) => ( -
-
- - {chain.name} - - - gen {chain.generation} - - - {chain.status} - - - {chain.completedSteps}/{chain.totalSteps} steps - {chain.failedSteps > 0 && ( - - ({chain.failedSteps} failed) - - )} - -
- -
- ))} - - )} -
- )} - - {activeTab === "contracts" && ( - - )} -
-
- ); -} diff --git a/makima/frontend/src/components/directives/DirectiveList.tsx b/makima/frontend/src/components/directives/DirectiveList.tsx deleted file mode 100644 index 5afa36e..0000000 --- a/makima/frontend/src/components/directives/DirectiveList.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import { useState } from "react"; -import type { DirectiveSummary, DirectiveStatus } from "../../lib/api"; - -interface DirectiveListProps { - directives: DirectiveSummary[]; - loading: boolean; - onSelect: (id: string) => void; - onCreate: () => void; - onDelete?: (directive: DirectiveSummary) => void; - selectedId?: string; -} - -const statusColors: Record = { - draft: "text-[#888]", - planning: "text-yellow-400", - active: "text-green-400", - paused: "text-orange-400", - completed: "text-blue-400", - archived: "text-[#555]", - failed: "text-red-400", -}; - -export function DirectiveList({ - directives, - loading, - onSelect, - onCreate, - selectedId, -}: DirectiveListProps) { - const [filter, setFilter] = useState("all"); - - const filteredDirectives = - filter === "all" - ? directives - : directives.filter((d) => d.status === filter); - - if (loading) { - return ( -
-
Loading...
-
- ); - } - - return ( -
- {/* Header */} -
-
-

- Directives -

- -
- - {/* Filter tabs */} -
- {(["all", "draft", "planning", "active", "paused", "completed", "failed"] as const).map( - (status) => ( - - ) - )} -
-
- - {/* List */} -
- {filteredDirectives.length === 0 ? ( -
-

- {filter === "all" - ? "No directives yet" - : `No ${filter} directives`} -

-
- ) : ( -
- {filteredDirectives.map((directive) => ( - - ))} -
- )} -
-
- ); -} diff --git a/makima/frontend/src/components/directives/StepDiagram.tsx b/makima/frontend/src/components/directives/StepDiagram.tsx deleted file mode 100644 index 33892e0..0000000 --- a/makima/frontend/src/components/directives/StepDiagram.tsx +++ /dev/null @@ -1,313 +0,0 @@ -import { useNavigate } from "react-router"; -import type { ChainStep, ContractPhase } from "../../lib/api"; -import { PhaseProgressBarCompact } from "../contracts/PhaseProgressBar"; - -interface StepDiagramProps { - steps: ChainStep[]; -} - -const statusColors: Record = { - pending: { - border: "border-[#444]", - dot: "bg-[#555]", - bg: "bg-[rgba(40,40,50,0.6)]", - glow: "", - }, - running: { - border: "border-yellow-400/60", - dot: "bg-yellow-400", - bg: "bg-[rgba(80,70,20,0.3)]", - glow: "shadow-[0_0_8px_rgba(250,204,21,0.15)]", - }, - evaluating: { - border: "border-blue-400/60", - dot: "bg-blue-400", - bg: "bg-[rgba(20,50,80,0.3)]", - glow: "shadow-[0_0_8px_rgba(96,165,250,0.15)]", - }, - passed: { - border: "border-green-400/60", - dot: "bg-green-400", - bg: "bg-[rgba(20,60,30,0.3)]", - glow: "", - }, - failed: { - border: "border-red-400/60", - dot: "bg-red-400", - bg: "bg-[rgba(60,20,20,0.3)]", - glow: "", - }, -}; - -const statusLabels: Record = { - pending: "Pending", - ready: "Ready", - running: "Running", - evaluating: "Evaluating", - passed: "Passed", - failed: "Failed", - rework: "Rework", - skipped: "Skipped", - blocked: "Blocked", -}; - -const confidenceColors: Record = { - green: "text-green-400", - yellow: "text-yellow-400", - red: "text-red-400", -}; - -/** - * Assign depth to each step via topological sort based on dependsOn UUIDs. - */ -function assignDepths(steps: ChainStep[]): Map { - const depths = new Map(); - const stepMap = new Map(steps.map((s) => [s.id, s])); - - function getDepth(id: string): number { - if (depths.has(id)) return depths.get(id)!; - const step = stepMap.get(id); - if (!step || !step.dependsOn || step.dependsOn.length === 0) { - depths.set(id, 0); - return 0; - } - const maxParent = Math.max( - ...step.dependsOn.map((depId) => getDepth(depId)) - ); - const d = maxParent + 1; - depths.set(id, d); - return d; - } - - for (const step of steps) { - getDepth(step.id); - } - - return depths; -} - -function StepCard({ step }: { step: ChainStep }) { - const navigate = useNavigate(); - const colors = statusColors[step.status] || statusColors.pending; - const summary = step.contractSummary; - const hasContract = !!step.contractId; - - return ( -
{ - if (hasContract) navigate(`/contracts/${step.contractId}`); - }} - title={hasContract ? "View contract" : undefined} - > - {/* Status header */} -
-
-
- - {step.name} - -
- - {statusLabels[step.status] || step.status} - -
- - {/* Description */} - {step.description && ( -

- {step.description} -

- )} - - {/* Evaluation info */} - {(step.confidenceScore != null || step.evaluationCount > 0 || step.reworkCount > 0) && ( -
-
- {step.confidenceScore != null && ( - - {Math.round(step.confidenceScore * 100)}% confidence - - )} - {step.evaluationCount > 0 && ( - - eval #{step.evaluationCount} - - )} - {step.reworkCount > 0 && ( - - rework x{step.reworkCount} - - )} -
-
- )} - - {/* Monitoring link (when evaluating) */} - {step.status === "evaluating" && step.monitoringContractId && ( -
- { - e.stopPropagation(); - navigate(`/contracts/${step.monitoringContractId}`); - }} - > - evaluation contract → - -
- )} - - {/* Contract progress */} - {summary && ( -
-
- -
-
- - {summary.tasksDone}/{summary.taskCount} tasks - - {summary.tasksRunning > 0 && ( - - {summary.tasksRunning} running - - )} - {summary.tasksFailed > 0 && ( - - {summary.tasksFailed} failed - - )} -
-
- )} - - {/* Contract link arrow */} - {hasContract && !summary && step.status !== "evaluating" && ( -
- - view contract → - -
- )} -
- ); -} - -/** Vertical connector between levels */ -function LevelConnector({ count }: { count: number }) { - return ( -
-
- {Array.from({ length: count }).map((_, i) => ( -
-
-
-
-
- ))} -
-
- ); -} - -export function StepDiagram({ steps }: StepDiagramProps) { - if (steps.length === 0) { - return ( -

No steps to display.

- ); - } - - const depths = assignDepths(steps); - const maxDepth = Math.max(...Array.from(depths.values())); - - // Group steps by depth level - const levels: ChainStep[][] = []; - for (let d = 0; d <= maxDepth; d++) { - levels.push( - steps - .filter((s) => depths.get(s.id) === d) - .sort((a, b) => a.orderIndex - b.orderIndex) - ); - } - - // Compute overall progress - const passedCount = steps.filter(s => s.status === "passed").length; - const failedCount = steps.filter(s => s.status === "failed").length; - const runningCount = steps.filter(s => s.status === "running").length; - const evaluatingCount = steps.filter(s => s.status === "evaluating").length; - - return ( -
- {/* Progress summary */} -
- - {levels.length} level{levels.length !== 1 ? "s" : ""} · {steps.length} step{steps.length !== 1 ? "s" : ""} - - {passedCount > 0 && ( - {passedCount} passed - )} - {runningCount > 0 && ( - {runningCount} running - )} - {evaluatingCount > 0 && ( - {evaluatingCount} evaluating - )} - {failedCount > 0 && ( - {failedCount} failed - )} -
-
-
- - {Math.round((passedCount / steps.length) * 100)}% - -
- - {/* Chain flow */} -
- {levels.map((level, li) => ( -
- {/* Level label */} - {levels.length > 1 && ( -
- - {li === 0 ? "Start" : li === maxDepth ? "Final" : `Level ${li}`} - -
- )} - - {/* Steps at this level */} -
- {level.map((step) => ( - - ))} -
- - {/* Connector to next level */} - {li < maxDepth && ( - - )} -
- ))} -
-
- ); -} -- cgit v1.2.3