mirror of
https://github.com/paperclipai/paperclip
synced 2026-03-25 11:21:48 +00:00
Add live ActiveAgentsPanel with real-time transcript feed, SidebarContext for responsive sidebar state, agent config form with reasoning effort, improved inbox with failed run alerts, enriched issue detail with project picker, and various component refinements across pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
75 lines
2.7 KiB
TypeScript
75 lines
2.7 KiB
TypeScript
import { UserPlus, Lightbulb, ShieldCheck } from "lucide-react";
|
|
|
|
export const typeLabel: Record<string, string> = {
|
|
hire_agent: "Hire Agent",
|
|
approve_ceo_strategy: "CEO Strategy",
|
|
};
|
|
|
|
export const typeIcon: Record<string, typeof UserPlus> = {
|
|
hire_agent: UserPlus,
|
|
approve_ceo_strategy: Lightbulb,
|
|
};
|
|
|
|
export const defaultTypeIcon = ShieldCheck;
|
|
|
|
function PayloadField({ label, value }: { label: string; value: unknown }) {
|
|
if (!value) return null;
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-muted-foreground w-20 sm:w-24 shrink-0 text-xs">{label}</span>
|
|
<span>{String(value)}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function HireAgentPayload({ payload }: { payload: Record<string, unknown> }) {
|
|
return (
|
|
<div className="mt-3 space-y-1.5 text-sm">
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-muted-foreground w-20 sm:w-24 shrink-0 text-xs">Name</span>
|
|
<span className="font-medium">{String(payload.name ?? "—")}</span>
|
|
</div>
|
|
<PayloadField label="Role" value={payload.role} />
|
|
<PayloadField label="Title" value={payload.title} />
|
|
{!!payload.capabilities && (
|
|
<div className="flex items-start gap-2">
|
|
<span className="text-muted-foreground w-20 sm:w-24 shrink-0 text-xs pt-0.5">Capabilities</span>
|
|
<span className="text-muted-foreground">{String(payload.capabilities)}</span>
|
|
</div>
|
|
)}
|
|
{!!payload.adapterType && (
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-muted-foreground w-20 sm:w-24 shrink-0 text-xs">Adapter</span>
|
|
<span className="font-mono text-xs bg-muted px-1.5 py-0.5 rounded">
|
|
{String(payload.adapterType)}
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function CeoStrategyPayload({ payload }: { payload: Record<string, unknown> }) {
|
|
const plan = payload.plan ?? payload.description ?? payload.strategy ?? payload.text;
|
|
return (
|
|
<div className="mt-3 space-y-1.5 text-sm">
|
|
<PayloadField label="Title" value={payload.title} />
|
|
{!!plan && (
|
|
<div className="mt-2 rounded-md bg-muted/40 px-3 py-2 text-sm text-muted-foreground whitespace-pre-wrap font-mono text-xs max-h-48 overflow-y-auto">
|
|
{String(plan)}
|
|
</div>
|
|
)}
|
|
{!plan && (
|
|
<pre className="mt-2 rounded-md bg-muted/40 px-3 py-2 text-xs text-muted-foreground overflow-x-auto max-h-48">
|
|
{JSON.stringify(payload, null, 2)}
|
|
</pre>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ApprovalPayloadRenderer({ type, payload }: { type: string; payload: Record<string, unknown> }) {
|
|
if (type === "hire_agent") return <HireAgentPayload payload={payload} />;
|
|
return <CeoStrategyPayload payload={payload} />;
|
|
}
|