summaryrefslogtreecommitdiff
path: root/makima/frontend/src/components/directives
diff options
context:
space:
mode:
Diffstat (limited to 'makima/frontend/src/components/directives')
-rw-r--r--makima/frontend/src/components/directives/DirectiveDetail.tsx230
1 files changed, 1 insertions, 229 deletions
diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx
index 369cdaa..f9e7eed 100644
--- a/makima/frontend/src/components/directives/DirectiveDetail.tsx
+++ b/makima/frontend/src/components/directives/DirectiveDetail.tsx
@@ -1,8 +1,7 @@
import { useState, useMemo, useEffect, useRef } from "react";
-import type { DirectiveWithSteps, DirectiveStatus, MemoryCategory } from "../../lib/api";
+import type { DirectiveWithSteps, DirectiveStatus } from "../../lib/api";
import { DirectiveDAG } from "./DirectiveDAG";
import { DirectiveLogStream } from "./DirectiveLogStream";
-import { useDirectiveMemories } from "../../hooks/useDirectiveMemories";
import { useMultiTaskSubscription } from "../../hooks/useMultiTaskSubscription";
const STATUS_BADGE: Record<DirectiveStatus, { color: string; label: string }> = {
@@ -13,18 +12,6 @@ const STATUS_BADGE: Record<DirectiveStatus, { color: string; label: string }> =
archived: { color: "text-[#556677] border-[#2a3a5a]", label: "ARCHIVED" },
};
-const CATEGORY_COLORS: Record<MemoryCategory, { text: string; border: string; bg: string; label: string }> = {
- decision: { text: "text-amber-400", border: "border-amber-800", bg: "bg-amber-900/20", label: "Decision" },
- context: { text: "text-cyan-400", border: "border-cyan-800", bg: "bg-cyan-900/20", label: "Context" },
- preference: { text: "text-violet-400", border: "border-violet-800", bg: "bg-violet-900/20", label: "Preference" },
- learning: { text: "text-emerald-400", border: "border-emerald-800", bg: "bg-emerald-900/20", label: "Learning" },
- issue: { text: "text-red-400", border: "border-red-800", bg: "bg-red-900/20", label: "Issue" },
- progress: { text: "text-blue-400", border: "border-blue-800", bg: "bg-blue-900/20", label: "Progress" },
- other: { text: "text-[#7788aa]", border: "border-[#2a3a5a]", bg: "bg-[#1a2540]", label: "Other" },
-};
-
-const ALL_CATEGORIES: MemoryCategory[] = ["decision", "context", "preference", "learning", "issue", "progress", "other"];
-
interface DirectiveDetailProps {
directive: DirectiveWithSteps;
onStart: () => void;
@@ -66,25 +53,6 @@ export function DirectiveDetail({
const terminalStatuses = new Set(["completed", "failed", "skipped"]);
const hasTerminalTasks = directive.steps.some((s) => s.taskId && terminalStatuses.has(s.status));
- // Memory panel state
- const [memoryOpen, setMemoryOpen] = useState(false);
- const [addingMemory, setAddingMemory] = useState(false);
- const [newCategory, setNewCategory] = useState<MemoryCategory>("context");
- const [newContent, setNewContent] = useState("");
- const [confirmClear, setConfirmClear] = useState(false);
-
- const {
- grouped,
- loading: memoryLoading,
- error: memoryError,
- add: addMemory,
- remove: removeMemory,
- clearAll: clearMemories,
- refresh: refreshMemories,
- } = useDirectiveMemories(directive.id);
-
- const totalMemories = Object.values(grouped).reduce((sum, arr) => sum + arr.length, 0);
-
// Build task map from directive steps and orchestrator
const taskMap = useMemo(() => {
const map = new Map<string, string>();
@@ -123,21 +91,6 @@ export function DirectiveDetail({
setEditingGoal(false);
};
- const handleAddMemory = async () => {
- if (!newContent.trim()) return;
- await addMemory({
- category: newCategory,
- content: newContent.trim(),
- });
- setNewContent("");
- setAddingMemory(false);
- };
-
- const handleClearAll = async () => {
- await clearMemories();
- setConfirmClear(false);
- };
-
return (
<div className="flex flex-col h-full overflow-y-auto">
{/* Header */}
@@ -346,187 +299,6 @@ export function DirectiveDetail({
)}
</div>
- {/* Memory Panel */}
- <div className="px-4 py-3 border-b border-[rgba(117,170,252,0.1)]">
- {/* Memory header — always visible */}
- <div className="flex items-center justify-between">
- <button
- type="button"
- onClick={() => setMemoryOpen((v) => !v)}
- className="flex items-center gap-1.5 group"
- >
- <span className="text-[10px] font-mono text-[#556677] group-hover:text-[#9bc3ff] transition-colors">
- {memoryOpen ? "\u25BC" : "\u25B6"}
- </span>
- <span className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide">
- Memory
- </span>
- {totalMemories > 0 && (
- <span className="text-[9px] font-mono text-[#556677] ml-1">
- ({totalMemories})
- </span>
- )}
- </button>
- <div className="flex items-center gap-2" />
- </div>
-
- {/* Collapsible content */}
- {memoryOpen && (
- <div className="mt-2">
- {memoryError && (
- <div className="text-[10px] font-mono text-red-400 mb-2 px-2 py-1 bg-red-900/10 border border-red-800/30 rounded">
- {memoryError}
- </div>
- )}
-
- {memoryLoading ? (
- <div className="text-[10px] font-mono text-[#556677] py-2">Loading...</div>
- ) : totalMemories === 0 ? (
- <div className="text-[10px] font-mono text-[#556677] py-2">
- No memory entries yet.
- </div>
- ) : (
- /* Grouped entries */
- <div className="flex flex-col gap-2">
- {ALL_CATEGORIES.map((cat) => {
- const entries = grouped[cat];
- if (entries.length === 0) return null;
- const style = CATEGORY_COLORS[cat];
- return (
- <div key={cat}>
- <div className="flex items-center gap-1.5 mb-1">
- <span className={`text-[9px] font-mono ${style.text} uppercase tracking-wider`}>
- {style.label}
- </span>
- <span className="text-[9px] font-mono text-[#556677]">
- ({entries.length})
- </span>
- </div>
- <div className="flex flex-col gap-1">
- {entries.map((entry) => (
- <div
- key={entry.id}
- className={`flex items-start gap-2 px-2 py-1.5 rounded border ${style.border} ${style.bg}`}
- >
- <div className="flex-1 min-w-0">
- <p className="text-[10px] font-mono text-[#c0d0e0] whitespace-pre-wrap break-words">
- {entry.content}
- </p>
- </div>
- <button
- type="button"
- onClick={() => removeMemory(entry.id)}
- className="text-[9px] font-mono text-[#556677] hover:text-red-400 shrink-0 mt-0.5"
- title="Delete entry"
- >
- x
- </button>
- </div>
- ))}
- </div>
- </div>
- );
- })}
- </div>
- )}
-
- {/* Action bar: Add + Clear */}
- <div className="flex items-center gap-2 mt-2 pt-2 border-t border-[rgba(117,170,252,0.1)]">
- <button
- type="button"
- onClick={() => setAddingMemory((v) => !v)}
- className="text-[10px] font-mono text-[#75aafc] hover:text-white border border-[rgba(117,170,252,0.2)] rounded px-2 py-0.5"
- >
- {addingMemory ? "Cancel" : "+ Add"}
- </button>
- {totalMemories > 0 && (
- <>
- {confirmClear ? (
- <div className="flex items-center gap-1.5 ml-auto">
- <span className="text-[9px] font-mono text-red-400">Clear all?</span>
- <button
- type="button"
- onClick={handleClearAll}
- className="text-[9px] font-mono text-red-400 hover:text-red-300 border border-red-800 rounded px-1.5 py-0.5"
- >
- Yes
- </button>
- <button
- type="button"
- onClick={() => setConfirmClear(false)}
- className="text-[9px] font-mono text-[#7788aa] hover:text-white border border-[#2a3a5a] rounded px-1.5 py-0.5"
- >
- No
- </button>
- </div>
- ) : (
- <button
- type="button"
- onClick={() => setConfirmClear(true)}
- className="text-[10px] font-mono text-[#556677] hover:text-red-400 ml-auto"
- >
- Clear all
- </button>
- )}
- </>
- )}
- <button
- type="button"
- onClick={refreshMemories}
- className="text-[9px] font-mono text-[#556677] hover:text-[#75aafc]"
- title="Refresh memories"
- >
- [refresh]
- </button>
- </div>
-
- {/* Add form */}
- {addingMemory && (
- <div className="mt-2 p-2 bg-[#0a1628] border border-[rgba(117,170,252,0.15)] rounded flex flex-col gap-2">
- <div className="flex items-center gap-2">
- <label className="text-[9px] font-mono text-[#7788aa] shrink-0">Category</label>
- <select
- value={newCategory}
- onChange={(e) => setNewCategory(e.target.value as MemoryCategory)}
- className="bg-[#1a2540] border border-[rgba(117,170,252,0.2)] rounded px-1.5 py-0.5 text-[10px] font-mono text-white flex-1"
- >
- {ALL_CATEGORIES.map((c) => (
- <option key={c} value={c}>
- {CATEGORY_COLORS[c].label}
- </option>
- ))}
- </select>
- </div>
- <textarea
- value={newContent}
- onChange={(e) => setNewContent(e.target.value)}
- placeholder="Memory content..."
- className="w-full bg-[#1a2540] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[10px] font-mono text-white resize-y min-h-[40px] placeholder:text-[#556677]"
- rows={2}
- />
- <div className="flex gap-1.5">
- <button
- type="button"
- onClick={handleAddMemory}
- disabled={!newContent.trim()}
- className="text-[10px] font-mono text-emerald-400 hover:text-emerald-300 border border-emerald-800 rounded px-2 py-0.5 disabled:opacity-40 disabled:cursor-not-allowed"
- >
- Save
- </button>
- <button
- type="button"
- onClick={() => { setAddingMemory(false); setNewContent(""); }}
- className="text-[10px] font-mono text-[#7788aa] hover:text-white border border-[#2a3a5a] rounded px-2 py-0.5"
- >
- Cancel
- </button>
- </div>
- </div>
- )}
- </div>
- )}
- </div>
-
{/* DAG */}
<div className="px-4 py-3 flex-1">
<span className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-2">