From ec9738a069e61529be040eff065318972b8a11e2 Mon Sep 17 00:00:00 2001
From: soryu <soryu@soryu.co>
Date: Wed, 4 Mar 2026 16:47:12 +0000
Subject: feat: task slide-out panel, 3-way reconcile toggle, daemon reauth fix
 (#85)

* WIP: heartbeat checkpoint

* WIP: heartbeat checkpoint

* feat: soryu-co/soryu - makima: Fix daemon reauth flow for new claude setup-token output format

* feat: soryu-co/soryu - makima: Update frontend reconcile toggle to three-way switch

* feat: soryu-co/soryu - makima: Add task slide-out panel to directive page
---
 .../src/components/directives/DirectiveDAG.tsx        | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

(limited to 'makima/frontend/src/components/directives/DirectiveDAG.tsx')

diff --git a/makima/frontend/src/components/directives/DirectiveDAG.tsx b/makima/frontend/src/components/directives/DirectiveDAG.tsx
index f225356..7fa2ccf 100644
--- a/makima/frontend/src/components/directives/DirectiveDAG.tsx
+++ b/makima/frontend/src/components/directives/DirectiveDAG.tsx
@@ -28,6 +28,7 @@ interface DirectiveDAGProps {
   onComplete?: (stepId: string) => void;
   onFail?: (stepId: string) => void;
   onSkip?: (stepId: string) => void;
+  onViewTask?: (taskId: string) => void;
 }
 
 interface Layer {
@@ -52,7 +53,7 @@ function topoSort(steps: DirectiveStep[]): Layer[] {
   }));
 }
 
-export function DirectiveDAG({ steps, specializedSteps, onComplete, onFail, onSkip }: DirectiveDAGProps) {
+export function DirectiveDAG({ steps, specializedSteps, onComplete, onFail, onSkip, onViewTask }: DirectiveDAGProps) {
   const layers = useMemo(() => topoSort(steps), [steps]);
 
   const orchestratorSteps = specializedSteps?.filter(s => s.type === "orchestrator") ?? [];
@@ -70,7 +71,7 @@ export function DirectiveDAG({ steps, specializedSteps, onComplete, onFail, onSk
     <div className="flex flex-col gap-4 items-center py-4">
       {/* Orchestrator steps (Planning/Cleanup/Orders) - rendered above regular steps */}
       {orchestratorSteps.map(step => (
-        <SpecializedStepNode key={step.id} step={step} />
+        <SpecializedStepNode key={step.id} step={step} onViewTask={onViewTask} />
       ))}
 
       {/* Connector line if both orchestrator step and regular steps exist */}
@@ -96,6 +97,7 @@ export function DirectiveDAG({ steps, specializedSteps, onComplete, onFail, onSk
                 onComplete={onComplete ? () => onComplete(step.id) : undefined}
                 onFail={onFail ? () => onFail(step.id) : undefined}
                 onSkip={onSkip ? () => onSkip(step.id) : undefined}
+                onViewTask={onViewTask}
               />
             ))}
           </div>
@@ -111,13 +113,13 @@ export function DirectiveDAG({ steps, specializedSteps, onComplete, onFail, onSk
 
       {/* Completion steps (PR creation) - rendered below regular steps */}
       {completionSteps.map(step => (
-        <SpecializedStepNode key={step.id} step={step} />
+        <SpecializedStepNode key={step.id} step={step} onViewTask={onViewTask} />
       ))}
     </div>
   );
 }
 
-function SpecializedStepNode({ step }: { step: SpecializedStep }) {
+function SpecializedStepNode({ step, onViewTask }: { step: SpecializedStep; onViewTask?: (taskId: string) => void }) {
   const themeColors = step.type === "orchestrator"
     ? {
         bg: "bg-[#1a1a30]",
@@ -145,12 +147,13 @@ function SpecializedStepNode({ step }: { step: SpecializedStep }) {
       <span className={`text-[11px] font-mono ${themeColors.text} flex-1 truncate`}>
         {step.name}
       </span>
-      <a
-        href={`/exec/${step.taskId}`}
-        className="text-[9px] font-mono text-[#556677] hover:text-white underline"
+      <button
+        type="button"
+        onClick={() => onViewTask?.(step.taskId)}
+        className="text-[9px] font-mono text-[#556677] hover:text-white underline bg-transparent border-none p-0 cursor-pointer"
       >
         View task
-      </a>
+      </button>
     </div>
   );
 }
-- 
cgit v1.2.3

