summaryrefslogtreecommitdiff
path: root/makima/frontend/src/components/directives/DirectiveDetail.tsx
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-08 16:18:13 +0000
committersoryu <soryu@soryu.co>2026-02-08 16:18:13 +0000
commitc0f220582cd61f0d88e42dfbc29d55b3be1e3b19 (patch)
tree5105fe5ffb6e80d3e82f806411628b0587c0685c /makima/frontend/src/components/directives/DirectiveDetail.tsx
parent62d411f61893486680ded5921a8b86b483ee1144 (diff)
downloadsoryu-c0f220582cd61f0d88e42dfbc29d55b3be1e3b19.tar.gz
soryu-c0f220582cd61f0d88e42dfbc29d55b3be1e3b19.zip
Fix directive deletion and stop local only on contracts
Diffstat (limited to 'makima/frontend/src/components/directives/DirectiveDetail.tsx')
-rw-r--r--makima/frontend/src/components/directives/DirectiveDetail.tsx188
1 files changed, 42 insertions, 146 deletions
diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx
index 06d8ba2..6bdf5aa 100644
--- a/makima/frontend/src/components/directives/DirectiveDetail.tsx
+++ b/makima/frontend/src/components/directives/DirectiveDetail.tsx
@@ -3,8 +3,6 @@ import { useNavigate } from "react-router";
import type {
DirectiveWithChains,
DirectiveStatus,
- ChainWithSteps,
- ChainStep,
ContractPhase,
} from "../../lib/api";
import { getDirective } from "../../lib/api";
@@ -32,122 +30,6 @@ const statusColors: Record<DirectiveStatus, string> = {
failed: "text-red-400",
};
-const stepStatusColors: Record<string, string> = {
- pending: "text-[#888]",
- running: "text-yellow-400",
- passed: "text-green-400",
- failed: "text-red-400",
-};
-
-const stepStatusIcons: Record<string, string> = {
- pending: "\u25CB", // ○
- running: "\u25D4", // ◔
- passed: "\u25CF", // ●
- failed: "\u2715", // ✕
-};
-
-function StepRow({ step }: { step: ChainStep }) {
- const navigate = useNavigate();
- const color = stepStatusColors[step.status] || "text-[#888]";
- const icon = stepStatusIcons[step.status] || "\u25CB";
- const summary = step.contractSummary;
-
- return (
- <div className="flex items-start gap-2 py-1.5 px-2 hover:bg-[rgba(117,170,252,0.05)]">
- <span className={`font-mono text-[11px] ${color} mt-px`}>{icon}</span>
- <div className="flex-1 min-w-0">
- <div className="flex items-center gap-2">
- <span className="font-mono text-[11px] text-[#dbe7ff] truncate">
- {step.name}
- </span>
- <span className={`font-mono text-[9px] uppercase ${color}`}>
- {step.status}
- </span>
- </div>
- {summary && (
- <div className="flex items-center gap-2 mt-0.5">
- <PhaseProgressBarCompact
- currentPhase={summary.phase as ContractPhase}
- />
- <span className="font-mono text-[9px] text-[#7788aa]">
- {summary.tasksDone}/{summary.taskCount} tasks
- </span>
- {step.contractId && (
- <button
- onClick={(e) => {
- e.stopPropagation();
- navigate(`/contracts/${step.contractId}`);
- }}
- className="font-mono text-[9px] text-[#75aafc] hover:text-white transition-colors"
- >
- contract &rarr;
- </button>
- )}
- </div>
- )}
- {!summary && step.contractId && (
- <button
- onClick={() => navigate(`/contracts/${step.contractId}`)}
- className="font-mono text-[9px] text-[#75aafc] hover:text-white transition-colors mt-0.5"
- >
- contract &rarr;
- </button>
- )}
- {step.description && (
- <p className="font-mono text-[10px] text-[#7788aa] truncate mt-0.5">
- {step.description}
- </p>
- )}
- </div>
- </div>
- );
-}
-
-function ChainCard({ chainWithSteps }: { chainWithSteps: ChainWithSteps }) {
- const chain = chainWithSteps;
- const steps = chainWithSteps.steps || [];
-
- return (
- <div className="border border-dashed border-[rgba(117,170,252,0.25)] bg-[rgba(117,170,252,0.03)]">
- <div className="p-3">
- <div className="flex items-center justify-between mb-1">
- <span className="font-mono text-xs text-[#dbe7ff]">
- {chain.name}
- </span>
- <span className="font-mono text-[10px] text-[#7788aa] uppercase">
- gen {chain.generation} &middot; {chain.status}
- </span>
- </div>
- {chain.description && (
- <p className="font-mono text-[11px] text-[#7788aa] mb-1">
- {chain.description}
- </p>
- )}
- <div className="flex gap-3 font-mono text-[10px] text-[#7788aa]">
- <span>
- {chain.completedSteps}/{chain.totalSteps} steps
- </span>
- {chain.failedSteps > 0 && (
- <span className="text-red-400">{chain.failedSteps} failed</span>
- )}
- {chain.currentConfidence != null && (
- <span>
- confidence: {(chain.currentConfidence * 100).toFixed(0)}%
- </span>
- )}
- </div>
- </div>
- {steps.length > 0 && (
- <div className="border-t border-dashed border-[rgba(117,170,252,0.15)]">
- {steps.map((step) => (
- <StepRow key={step.id} step={step} />
- ))}
- </div>
- )}
- </div>
- );
-}
-
function JsonSection({
label,
data,
@@ -484,39 +366,53 @@ export function DirectiveDetail({
{activeTab === "chain" && (
<div className="space-y-4">
- {/* Step diagram */}
- {directive.chains.length > 0 && (
- <div>
- <h4 className="font-mono text-[10px] text-[#75aafc] uppercase tracking-wider mb-2">
- Step Dependencies
- </h4>
- <StepDiagram
- steps={directive.chains.flatMap((c) => c.steps)}
- />
- </div>
- )}
-
- {/* Chain cards */}
- <div>
- <h4 className="font-mono text-[10px] text-[#75aafc] uppercase tracking-wider mb-2">
- Chains ({directive.chains.length})
- </h4>
- {directive.chains.length === 0 ? (
- <p className="font-mono text-xs text-[#7788aa]">
+ {directive.chains.length === 0 ? (
+ <div className="flex flex-col items-center justify-center py-12">
+ <div className="font-mono text-[40px] text-[#333] mb-3">
+ {directive.status === "planning" ? "\u2699" : "\u25CB"}
+ </div>
+ <p className="font-mono text-xs text-[#7788aa] text-center max-w-[300px]">
{directive.status === "planning"
- ? "Planning in progress... chains will appear when the planner completes."
+ ? "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."}
</p>
- ) : (
- <div className="space-y-2">
- {directive.chains.map((cws) => (
- <ChainCard key={cws.id} chainWithSteps={cws} />
- ))}
- </div>
- )}
- </div>
+ </div>
+ ) : (
+ <>
+ {/* Chain metadata header */}
+ {directive.chains.map((chain) => (
+ <div key={chain.id} className="space-y-3">
+ <div className="flex items-center gap-3 pb-2 border-b border-dashed border-[rgba(117,170,252,0.15)]">
+ <span className="font-mono text-xs text-[#dbe7ff]">
+ {chain.name}
+ </span>
+ <span className="font-mono text-[10px] text-[#7788aa] uppercase">
+ gen {chain.generation}
+ </span>
+ <span className={`font-mono text-[10px] uppercase ${
+ chain.status === "completed" ? "text-green-400" :
+ chain.status === "failed" ? "text-red-400" :
+ chain.status === "running" ? "text-yellow-400" :
+ "text-[#7788aa]"
+ }`}>
+ {chain.status}
+ </span>
+ <span className="font-mono text-[10px] text-[#7788aa] ml-auto">
+ {chain.completedSteps}/{chain.totalSteps} steps
+ {chain.failedSteps > 0 && (
+ <span className="text-red-400 ml-1">
+ ({chain.failedSteps} failed)
+ </span>
+ )}
+ </span>
+ </div>
+ <StepDiagram steps={chain.steps} />
+ </div>
+ ))}
+ </>
+ )}
</div>
)}