import { useTaskChatExpansion } from "./expansion-state";
import { cn } from "@/lib/utils";
import {
Check,
ChevronRight,
Loader2,
ShieldCheck,
ShieldX,
X,
} from "lucide-react";
import type { TaskChatToolItem } from "./task-chat-model";
import { toolTaxonomy } from "./tool-taxonomy";
import { useTaskChatShimmer } from "./TaskChatShimmer";
import { TaskChatDiffCounts, TaskChatDiffView } from "./TaskChatDiffView";
import { useTaskReferenceLabel, withTaskReference } from "./task-reference";
const STATUS_ICON = {
pending: { Icon: Loader2, spin: false, tone: "text-muted-foreground" },
in_progress: {
Icon: Loader2,
spin: true,
tone: "text-(--status-agent-running)",
},
completed: { Icon: Check, spin: false, tone: "text-muted-foreground" },
failed: { Icon: X, spin: false, tone: "text-destructive" },
interrupted: { Icon: X, spin: false, tone: "text-muted-foreground" },
} as const;
function ToolTarget({ text }: { text: string }) {
return (
{text}
);
}
/** Names the task a call is about by identifier; its UUID is never shown. */
function TaskReferenceToolTarget({ taskRefId, target }: { taskRefId: string; target?: string }) {
const taskLabel = useTaskReferenceLabel(taskRefId);
return ;
}
/**
* Tool invocation as a flat activity row (v7): [glyph] [name] [mono target] …
* [hover chevron] [status]. No card chrome — activity is metadata, not
* content. Clicking toggles a compact result/change summary (left-rail
* inset). An edit row carries its `+N −M` counts and opens to a compact,
* height-capped diff of that one edit.
*/
export function TaskChatToolCard({ item }: { item: TaskChatToolItem }) {
const { Icon, spin, tone } = STATUS_ICON[item.status];
const shimmer = useTaskChatShimmer(item.id);
const RowIcon = toolTaxonomy(item.rawName ?? item.name).icon;
const [showDetail, setShowDetail] = useTaskChatExpansion(item.id, false);
const expandable = Boolean(item.target || item.detail || item.diff);
return (
{item.target && showDetail && !item.diff?.lines?.length ? (
{item.target}
) : null}
{item.detail && showDetail ? (
{item.detail}
) : null}
{item.diff && showDetail ? (
item.diff.lines && item.diff.lines.length > 0 ? (
) : (
Changed
{item.diff.path ? (
{item.diff.path}
) : null}
)
) : null}
);
}