feat(KB-057): complete Step 2 — useTerminal hook with history, SSE streaming, and command execution

This commit is contained in:
gsxdsm
2026-03-29 20:57:18 -07:00
parent c5b09e1cb1
commit 287ce1d6d2
6 changed files with 827 additions and 3 deletions

View File

@@ -63,6 +63,12 @@ export function TaskCard({
const titleInputRef = useRef<HTMLInputElement>(null);
const descTextareaRef = useRef<HTMLTextAreaElement>(null);
const touchOpenHandledRef = useRef(false);
const isInteractiveTarget = useCallback((target: EventTarget | null): boolean => {
if (!(target instanceof HTMLElement)) return false;
return !!target.closest("button, a, input, textarea, select, label, [role='button']");
}, []);
// Reset edit state when task changes
useEffect(() => {
@@ -134,6 +140,21 @@ export function TaskCard({
}
}, [task.id, onOpenDetail, addToast, isEditing]);
const handleCardClick = useCallback((e: React.MouseEvent) => {
if (touchOpenHandledRef.current) {
touchOpenHandledRef.current = false;
return;
}
if (isInteractiveTarget(e.target)) return;
handleClick();
}, [handleClick, isInteractiveTarget]);
const handleTouchEnd = useCallback((e: React.TouchEvent) => {
if (isInteractiveTarget(e.target)) return;
touchOpenHandledRef.current = true;
handleClick();
}, [handleClick, isInteractiveTarget]);
const handleDepClick = useCallback(async (e: React.MouseEvent, depId: string) => {
e.stopPropagation(); // Prevent card click
try {
@@ -308,7 +329,8 @@ export function TaskCard({
onDragOver={handleFileDragOver}
onDragLeave={handleFileDragLeave}
onDrop={handleFileDrop}
onClick={handleClick}
onClick={handleCardClick}
onTouchEnd={handleTouchEnd}
onDoubleClick={handleDoubleClick}
>
<div className="card-header">